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 96f650e..4c6950d 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
@@ -4484,7 +4893,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4484 { 4893 {
4485 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4894 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4486 float distance_term = distance * distance * distance; // Script Energy 4895 float distance_term = distance * distance * distance; // Script Energy
4487 float pusher_mass = m_host.GetMass(); 4896 // use total object mass and not part
4897 float pusher_mass = m_host.ParentGroup.GetMass();
4488 4898
4489 float PUSH_ATTENUATION_DISTANCE = 17f; 4899 float PUSH_ATTENUATION_DISTANCE = 17f;
4490 float PUSH_ATTENUATION_SCALE = 5f; 4900 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4738,6 +5148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4738 { 5148 {
4739 return item.AssetID.ToString(); 5149 return item.AssetID.ToString();
4740 } 5150 }
5151 m_host.TaskInventory.LockItemsForRead(false);
4741 5152
4742 return UUID.Zero.ToString(); 5153 return UUID.Zero.ToString();
4743 } 5154 }
@@ -4890,14 +5301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4890 { 5301 {
4891 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4892 5303
4893 if (src == null) 5304 return src.Length;
4894 {
4895 return 0;
4896 }
4897 else
4898 {
4899 return src.Length;
4900 }
4901 } 5305 }
4902 5306
4903 public LSL_Integer llList2Integer(LSL_List src, int index) 5307 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4968,7 +5372,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4968 else if (src.Data[index] is LSL_Float) 5372 else if (src.Data[index] is LSL_Float)
4969 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5373 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4970 else if (src.Data[index] is LSL_String) 5374 else if (src.Data[index] is LSL_String)
4971 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5375 {
5376 string str = ((LSL_String) src.Data[index]).m_string;
5377 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5378 if (m != Match.Empty)
5379 {
5380 str = m.Value;
5381 double d = 0.0;
5382 if (!Double.TryParse(str, out d))
5383 return 0.0;
5384
5385 return d;
5386 }
5387 return 0.0;
5388 }
4972 return Convert.ToDouble(src.Data[index]); 5389 return Convert.ToDouble(src.Data[index]);
4973 } 5390 }
4974 catch (FormatException) 5391 catch (FormatException)
@@ -5010,7 +5427,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5010 // for completion and should LSL_Key ever be implemented 5427 // for completion and should LSL_Key ever be implemented
5011 // as it's own struct 5428 // as it's own struct
5012 else if (!(src.Data[index] is LSL_String || 5429 else if (!(src.Data[index] is LSL_String ||
5013 src.Data[index] is LSL_Key)) 5430 src.Data[index] is LSL_Key ||
5431 src.Data[index] is String))
5014 { 5432 {
5015 return ""; 5433 return "";
5016 } 5434 }
@@ -5268,7 +5686,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5268 } 5686 }
5269 } 5687 }
5270 } 5688 }
5271 else { 5689 else
5690 {
5272 object[] array = new object[src.Length]; 5691 object[] array = new object[src.Length];
5273 Array.Copy(src.Data, 0, array, 0, src.Length); 5692 Array.Copy(src.Data, 0, array, 0, src.Length);
5274 result = new LSL_List(array); 5693 result = new LSL_List(array);
@@ -5375,7 +5794,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5375 public LSL_Integer llGetRegionAgentCount() 5794 public LSL_Integer llGetRegionAgentCount()
5376 { 5795 {
5377 m_host.AddScriptLPS(1); 5796 m_host.AddScriptLPS(1);
5378 return new LSL_Integer(World.GetRootAgentCount()); 5797
5798 int count = 0;
5799 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5800 count++;
5801 });
5802
5803 return new LSL_Integer(count);
5379 } 5804 }
5380 5805
5381 public LSL_Vector llGetRegionCorner() 5806 public LSL_Vector llGetRegionCorner()
@@ -5616,6 +6041,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5616 flags |= ScriptBaseClass.AGENT_AWAY; 6041 flags |= ScriptBaseClass.AGENT_AWAY;
5617 } 6042 }
5618 6043
6044 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6045 UUID[] anims = agent.Animator.GetAnimationArray();
6046 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6047 {
6048 flags |= ScriptBaseClass.AGENT_BUSY;
6049 }
6050
5619 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6051 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5620 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6052 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5621 { 6053 {
@@ -5663,6 +6095,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5663 flags |= ScriptBaseClass.AGENT_SITTING; 6095 flags |= ScriptBaseClass.AGENT_SITTING;
5664 } 6096 }
5665 6097
6098 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6099 {
6100 flags |= ScriptBaseClass.AGENT_MALE;
6101 }
6102
5666 return flags; 6103 return flags;
5667 } 6104 }
5668 6105
@@ -5810,9 +6247,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5810 6247
5811 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6248 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5812 6249
5813 foreach (SceneObjectPart part in parts) 6250 try
6251 {
6252 foreach (SceneObjectPart part in parts)
6253 {
6254 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6255 }
6256 }
6257 finally
5814 { 6258 {
5815 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5816 } 6259 }
5817 } 6260 }
5818 6261
@@ -5866,13 +6309,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5866 6309
5867 if (m_host.OwnerID == land.LandData.OwnerID) 6310 if (m_host.OwnerID == land.LandData.OwnerID)
5868 { 6311 {
5869 World.TeleportClientHome(agentID, presence.ControllingClient); 6312 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6313 presence.TeleportWithMomentum(pos, null);
6314 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5870 } 6315 }
5871 } 6316 }
5872 } 6317 }
5873 ScriptSleep(5000); 6318 ScriptSleep(5000);
5874 } 6319 }
5875 6320
6321 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6322 {
6323 return ParseString2List(str, separators, in_spacers, false);
6324 }
6325
5876 public LSL_Integer llOverMyLand(string id) 6326 public LSL_Integer llOverMyLand(string id)
5877 { 6327 {
5878 m_host.AddScriptLPS(1); 6328 m_host.AddScriptLPS(1);
@@ -5926,25 +6376,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5926 } 6376 }
5927 else 6377 else
5928 { 6378 {
5929 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6379// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6380 Vector3 s = avatar.Appearance.AvatarSize;
6381 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5930 } 6382 }
5931 return agentSize; 6383 return agentSize;
5932 } 6384 }
5933 6385
5934 public LSL_Integer llSameGroup(string agent) 6386 public LSL_Integer llSameGroup(string id)
5935 { 6387 {
5936 m_host.AddScriptLPS(1); 6388 m_host.AddScriptLPS(1);
5937 UUID agentId = new UUID(); 6389 UUID uuid = new UUID();
5938 if (!UUID.TryParse(agent, out agentId)) 6390 if (!UUID.TryParse(id, out uuid))
5939 return new LSL_Integer(0); 6391 return new LSL_Integer(0);
5940 ScenePresence presence = World.GetScenePresence(agentId); 6392
5941 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6393 // Check if it's a group key
5942 return new LSL_Integer(0); 6394 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5943 IClientAPI client = presence.ControllingClient;
5944 if (m_host.GroupID == client.ActiveGroupId)
5945 return new LSL_Integer(1); 6395 return new LSL_Integer(1);
5946 else 6396
6397 // We got passed a UUID.Zero
6398 if (uuid == UUID.Zero)
6399 return new LSL_Integer(0);
6400
6401 // Handle the case where id names an avatar
6402 ScenePresence presence = World.GetScenePresence(uuid);
6403 if (presence != null)
6404 {
6405 if (presence.IsChildAgent)
6406 return new LSL_Integer(0);
6407
6408 IClientAPI client = presence.ControllingClient;
6409 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6410 return new LSL_Integer(1);
6411
6412 return new LSL_Integer(0);
6413 }
6414
6415 // Handle object case
6416 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6417 if (part != null)
6418 {
6419 // This will handle both deed and non-deed and also the no
6420 // group case
6421 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6422 return new LSL_Integer(1);
6423
5947 return new LSL_Integer(0); 6424 return new LSL_Integer(0);
6425 }
6426
6427 return new LSL_Integer(0);
5948 } 6428 }
5949 6429
5950 public void llUnSit(string id) 6430 public void llUnSit(string id)
@@ -6069,7 +6549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6069 return m_host.ParentGroup.AttachmentPoint; 6549 return m_host.ParentGroup.AttachmentPoint;
6070 } 6550 }
6071 6551
6072 public LSL_Integer llGetFreeMemory() 6552 public virtual LSL_Integer llGetFreeMemory()
6073 { 6553 {
6074 m_host.AddScriptLPS(1); 6554 m_host.AddScriptLPS(1);
6075 // Make scripts designed for LSO happy 6555 // Make scripts designed for LSO happy
@@ -6501,6 +6981,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6501 6981
6502 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6982 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6503 { 6983 {
6984 // LSL quaternions can normalize to 0, normal Quaternions can't.
6985 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6986 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6987
6504 part.SitTargetPosition = offset; 6988 part.SitTargetPosition = offset;
6505 part.SitTargetOrientation = rot; 6989 part.SitTargetOrientation = rot;
6506 part.ParentGroup.HasGroupChanged = true; 6990 part.ParentGroup.HasGroupChanged = true;
@@ -6686,30 +7170,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6686 UUID av = new UUID(); 7170 UUID av = new UUID();
6687 if (!UUID.TryParse(avatar,out av)) 7171 if (!UUID.TryParse(avatar,out av))
6688 { 7172 {
6689 LSLError("First parameter to llDialog needs to be a key"); 7173 //LSLError("First parameter to llDialog needs to be a key");
6690 return; 7174 return;
6691 } 7175 }
6692 if (buttons.Length < 1) 7176 if (buttons.Length < 1)
6693 { 7177 {
6694 LSLError("No less than 1 button can be shown"); 7178 buttons.Add("OK");
6695 return;
6696 } 7179 }
6697 if (buttons.Length > 12) 7180 if (buttons.Length > 12)
6698 { 7181 {
6699 LSLError("No more than 12 buttons can be shown"); 7182 ShoutError("button list too long, must be 12 or fewer entries");
6700 return;
6701 } 7183 }
6702 string[] buts = new string[buttons.Length]; 7184 int length = buttons.Length;
6703 for (int i = 0; i < buttons.Length; i++) 7185 if (length > 12)
7186 length = 12;
7187
7188 string[] buts = new string[length];
7189 for (int i = 0; i < length; i++)
6704 { 7190 {
6705 if (buttons.Data[i].ToString() == String.Empty) 7191 if (buttons.Data[i].ToString() == String.Empty)
6706 { 7192 {
6707 LSLError("button label cannot be blank"); 7193 ShoutError("button label cannot be blank");
6708 return; 7194 return;
6709 } 7195 }
6710 if (buttons.Data[i].ToString().Length > 24) 7196 if (buttons.Data[i].ToString().Length > 24)
6711 { 7197 {
6712 LSLError("button label cannot be longer than 24 characters"); 7198 ShoutError("button label cannot be longer than 24 characters");
6713 return; 7199 return;
6714 } 7200 }
6715 buts[i] = buttons.Data[i].ToString(); 7201 buts[i] = buttons.Data[i].ToString();
@@ -6776,9 +7262,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6776 return; 7262 return;
6777 } 7263 }
6778 7264
6779 // the rest of the permission checks are done in RezScript, so check the pin there as well 7265 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6780 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7266 if (dest != null)
7267 {
7268 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7269 {
7270 // the rest of the permission checks are done in RezScript, so check the pin there as well
7271 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6781 7272
7273 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7274 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7275 }
7276 }
6782 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7277 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6783 ScriptSleep(3000); 7278 ScriptSleep(3000);
6784 } 7279 }
@@ -6852,19 +7347,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6852 public LSL_String llMD5String(string src, int nonce) 7347 public LSL_String llMD5String(string src, int nonce)
6853 { 7348 {
6854 m_host.AddScriptLPS(1); 7349 m_host.AddScriptLPS(1);
6855 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7350 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6856 } 7351 }
6857 7352
6858 public LSL_String llSHA1String(string src) 7353 public LSL_String llSHA1String(string src)
6859 { 7354 {
6860 m_host.AddScriptLPS(1); 7355 m_host.AddScriptLPS(1);
6861 return Util.SHA1Hash(src).ToLower(); 7356 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6862 } 7357 }
6863 7358
6864 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7359 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6865 { 7360 {
6866 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7361 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6867 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7362 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7363 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7364 return shapeBlock;
6868 7365
6869 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7366 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6870 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7367 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6969,6 +7466,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6969 // Prim type box, cylinder and prism. 7466 // Prim type box, cylinder and prism.
6970 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) 7467 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)
6971 { 7468 {
7469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7470 return;
7471
6972 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7472 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6973 ObjectShapePacket.ObjectDataBlock shapeBlock; 7473 ObjectShapePacket.ObjectDataBlock shapeBlock;
6974 7474
@@ -7022,6 +7522,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7022 // Prim type sphere. 7522 // Prim type sphere.
7023 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7523 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7024 { 7524 {
7525 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7526 return;
7527
7025 ObjectShapePacket.ObjectDataBlock shapeBlock; 7528 ObjectShapePacket.ObjectDataBlock shapeBlock;
7026 7529
7027 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7530 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7063,6 +7566,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7063 // Prim type torus, tube and ring. 7566 // Prim type torus, tube and ring.
7064 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) 7567 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)
7065 { 7568 {
7569 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7570 return;
7571
7066 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7572 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7067 ObjectShapePacket.ObjectDataBlock shapeBlock; 7573 ObjectShapePacket.ObjectDataBlock shapeBlock;
7068 7574
@@ -7198,6 +7704,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7198 // Prim type sculpt. 7704 // Prim type sculpt.
7199 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7705 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7200 { 7706 {
7707 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7708 return;
7709
7201 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7710 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7202 UUID sculptId; 7711 UUID sculptId;
7203 7712
@@ -7220,7 +7729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7220 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7729 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7221 { 7730 {
7222 // default 7731 // default
7223 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7732 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7224 } 7733 }
7225 7734
7226 part.Shape.SetSculptProperties((byte)type, sculptId); 7735 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7237,48 +7746,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7237 ScriptSleep(200); 7746 ScriptSleep(200);
7238 } 7747 }
7239 7748
7240 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7749 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7241 { 7750 {
7242 m_host.AddScriptLPS(1); 7751 m_host.AddScriptLPS(1);
7243 7752
7244 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7753 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7754 }
7245 7755
7246 ScriptSleep(200); 7756 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7757 {
7758 List<object> parts = new List<object>();
7759 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7760 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7761 foreach (SceneObjectPart p in prims)
7762 parts.Add(p);
7763 foreach (ScenePresence p in avatars)
7764 parts.Add(p);
7765
7766 LSL_List remaining = null;
7767 uint rulesParsed = 0;
7768
7769 if (parts.Count > 0)
7770 {
7771 foreach (object part in parts)
7772 {
7773 if (part is SceneObjectPart)
7774 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7775 else
7776 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7777 }
7778
7779 while ((object)remaining != null && remaining.Length > 2)
7780 {
7781 linknumber = remaining.GetLSLIntegerItem(0);
7782 rules = remaining.GetSublist(1, -1);
7783 parts.Clear();
7784 prims = GetLinkParts(linknumber);
7785 avatars = GetLinkAvatars(linknumber);
7786 foreach (SceneObjectPart p in prims)
7787 parts.Add(p);
7788 foreach (ScenePresence p in avatars)
7789 parts.Add(p);
7790
7791 remaining = null;
7792 foreach (object part in parts)
7793 {
7794 if (part is SceneObjectPart)
7795 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7796 else
7797 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7798 }
7799 }
7800 }
7247 } 7801 }
7248 7802
7249 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7803 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7804 float material_density, float material_friction,
7805 float material_restitution, float material_gravity_modifier)
7250 { 7806 {
7251 m_host.AddScriptLPS(1); 7807 ExtraPhysicsData physdata = new ExtraPhysicsData();
7808 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7809 physdata.Density = part.Density;
7810 physdata.Friction = part.Friction;
7811 physdata.Bounce = part.Restitution;
7812 physdata.GravitationModifier = part.GravityModifier;
7252 7813
7253 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7814 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7815 physdata.Density = material_density;
7816 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7817 physdata.Friction = material_friction;
7818 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7819 physdata.Bounce = material_restitution;
7820 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7821 physdata.GravitationModifier = material_gravity_modifier;
7822
7823 part.UpdateExtraPhysics(physdata);
7254 } 7824 }
7255 7825
7256 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7826 public void llSetPhysicsMaterial(int material_bits,
7827 float material_gravity_modifier, float material_restitution,
7828 float material_friction, float material_density)
7257 { 7829 {
7258 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7830 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7831 }
7259 7832
7260 LSL_List remaining = null; 7833 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7261 uint rulesParsed = 0; 7834 {
7835 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7836 llSetLinkPrimitiveParamsFast(linknumber, rules);
7837 ScriptSleep(200);
7838 }
7262 7839
7263 foreach (SceneObjectPart part in parts) 7840 // vector up using libomv (c&p from sop )
7264 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7841 // vector up rotated by r
7842 private Vector3 Zrot(Quaternion r)
7843 {
7844 double x, y, z, m;
7265 7845
7266 while (remaining != null && remaining.Length > 2) 7846 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7847 if (Math.Abs(1.0 - m) > 0.000001)
7267 { 7848 {
7268 linknumber = remaining.GetLSLIntegerItem(0); 7849 m = 1.0 / Math.Sqrt(m);
7269 rules = remaining.GetSublist(1, -1); 7850 r.X *= (float)m;
7270 parts = GetLinkParts(linknumber); 7851 r.Y *= (float)m;
7271 7852 r.Z *= (float)m;
7272 foreach (SceneObjectPart part in parts) 7853 r.W *= (float)m;
7273 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7274 } 7854 }
7855
7856 x = 2 * (r.X * r.Z + r.Y * r.W);
7857 y = 2 * (-r.X * r.W + r.Y * r.Z);
7858 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7859
7860 return new Vector3((float)x, (float)y, (float)z);
7275 } 7861 }
7276 7862
7277 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7863 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7278 { 7864 {
7865 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7866 return null;
7867
7279 int idx = 0; 7868 int idx = 0;
7280 int idxStart = 0; 7869 int idxStart = 0;
7281 7870
7871 SceneObjectGroup parentgrp = part.ParentGroup;
7872
7282 bool positionChanged = false; 7873 bool positionChanged = false;
7283 LSL_Vector currentPosition = GetPartLocalPos(part); 7874 LSL_Vector currentPosition = GetPartLocalPos(part);
7284 7875
@@ -7303,8 +7894,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7303 return null; 7894 return null;
7304 7895
7305 v=rules.GetVector3Item(idx++); 7896 v=rules.GetVector3Item(idx++);
7897 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7898 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7899 else
7900 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7306 positionChanged = true; 7901 positionChanged = true;
7307 currentPosition = GetSetPosTarget(part, v, currentPosition);
7308 7902
7309 break; 7903 break;
7310 case (int)ScriptBaseClass.PRIM_SIZE: 7904 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7321,7 +7915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7321 7915
7322 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7916 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7323 // try to let this work as in SL... 7917 // try to let this work as in SL...
7324 if (part.ParentID == 0) 7918 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7325 { 7919 {
7326 // special case: If we are root, rotate complete SOG to new rotation 7920 // special case: If we are root, rotate complete SOG to new rotation
7327 SetRot(part, q); 7921 SetRot(part, q);
@@ -7581,7 +8175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7581 return null; 8175 return null;
7582 8176
7583 string ph = rules.Data[idx++].ToString(); 8177 string ph = rules.Data[idx++].ToString();
7584 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8178 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7585 8179
7586 break; 8180 break;
7587 8181
@@ -7615,12 +8209,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7615 8209
7616 break; 8210 break;
7617 8211
8212 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8213 if (remain < 5)
8214 return null;
8215
8216 int material_bits = rules.GetLSLIntegerItem(idx++);
8217 float material_density = (float)rules.GetLSLFloatItem(idx++);
8218 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8219 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8220 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8221
8222 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8223
8224 break;
8225
7618 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8226 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7619 if (remain < 1) 8227 if (remain < 1)
7620 return null; 8228 return null;
7621 string temp = rules.Data[idx++].ToString(); 8229 string temp = rules.Data[idx++].ToString();
7622 8230
7623 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8231 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7624 8232
7625 break; 8233 break;
7626 8234
@@ -7694,14 +8302,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7694 if (part.ParentGroup.RootPart == part) 8302 if (part.ParentGroup.RootPart == part)
7695 { 8303 {
7696 SceneObjectGroup parent = part.ParentGroup; 8304 SceneObjectGroup parent = part.ParentGroup;
7697 parent.UpdateGroupPosition(currentPosition); 8305 Util.FireAndForget(delegate(object x) {
8306 parent.UpdateGroupPosition(currentPosition);
8307 });
7698 } 8308 }
7699 else 8309 else
7700 { 8310 {
7701 part.OffsetPosition = currentPosition; 8311 part.OffsetPosition = currentPosition;
7702 SceneObjectGroup parent = part.ParentGroup; 8312// SceneObjectGroup parent = part.ParentGroup;
7703 parent.HasGroupChanged = true; 8313// parent.HasGroupChanged = true;
7704 parent.ScheduleGroupForTerseUpdate(); 8314// parent.ScheduleGroupForTerseUpdate();
8315 part.ScheduleTerseUpdate();
7705 } 8316 }
7706 } 8317 }
7707 } 8318 }
@@ -7739,10 +8350,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 8350
7740 public LSL_String llXorBase64Strings(string str1, string str2) 8351 public LSL_String llXorBase64Strings(string str1, string str2)
7741 { 8352 {
7742 m_host.AddScriptLPS(1); 8353 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7743 Deprecated("llXorBase64Strings"); 8354
7744 ScriptSleep(300); 8355 ScriptSleep(300);
7745 return String.Empty; 8356 m_host.AddScriptLPS(1);
8357
8358 if (str1 == String.Empty)
8359 return String.Empty;
8360 if (str2 == String.Empty)
8361 return str1;
8362
8363 int len = str2.Length;
8364 if ((len % 4) != 0) // LL is EVIL!!!!
8365 {
8366 while (str2.EndsWith("="))
8367 str2 = str2.Substring(0, str2.Length - 1);
8368
8369 len = str2.Length;
8370 int mod = len % 4;
8371
8372 if (mod == 1)
8373 str2 = str2.Substring(0, str2.Length - 1);
8374 else if (mod == 2)
8375 str2 += "==";
8376 else if (mod == 3)
8377 str2 += "=";
8378 }
8379
8380 byte[] data1;
8381 byte[] data2;
8382 try
8383 {
8384 data1 = Convert.FromBase64String(str1);
8385 data2 = Convert.FromBase64String(str2);
8386 }
8387 catch (Exception)
8388 {
8389 return new LSL_String(String.Empty);
8390 }
8391
8392 // For cases where the decoded length of s2 is greater
8393 // than the decoded length of s1, simply perform a normal
8394 // decode and XOR
8395 //
8396 if (data2.Length >= data1.Length)
8397 {
8398 for (int pos = 0 ; pos < data1.Length ; pos++ )
8399 data1[pos] ^= data2[pos];
8400
8401 return Convert.ToBase64String(data1);
8402 }
8403
8404 // Remove padding
8405 while (str1.EndsWith("="))
8406 str1 = str1.Substring(0, str1.Length - 1);
8407 while (str2.EndsWith("="))
8408 str2 = str2.Substring(0, str2.Length - 1);
8409
8410 byte[] d1 = new byte[str1.Length];
8411 byte[] d2 = new byte[str2.Length];
8412
8413 for (int i = 0 ; i < str1.Length ; i++)
8414 {
8415 int idx = b64.IndexOf(str1.Substring(i, 1));
8416 if (idx == -1)
8417 idx = 0;
8418 d1[i] = (byte)idx;
8419 }
8420
8421 for (int i = 0 ; i < str2.Length ; i++)
8422 {
8423 int idx = b64.IndexOf(str2.Substring(i, 1));
8424 if (idx == -1)
8425 idx = 0;
8426 d2[i] = (byte)idx;
8427 }
8428
8429 string output = String.Empty;
8430
8431 for (int pos = 0 ; pos < d1.Length ; pos++)
8432 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8433
8434 while (output.Length % 3 > 0)
8435 output += "=";
8436
8437 return output;
7746 } 8438 }
7747 8439
7748 public void llRemoteDataSetRegion() 8440 public void llRemoteDataSetRegion()
@@ -7866,8 +8558,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7866 public LSL_Integer llGetNumberOfPrims() 8558 public LSL_Integer llGetNumberOfPrims()
7867 { 8559 {
7868 m_host.AddScriptLPS(1); 8560 m_host.AddScriptLPS(1);
7869 8561 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7870 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8562
8563 return m_host.ParentGroup.PrimCount + avatarCount;
7871 } 8564 }
7872 8565
7873 /// <summary> 8566 /// <summary>
@@ -7882,55 +8575,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7882 m_host.AddScriptLPS(1); 8575 m_host.AddScriptLPS(1);
7883 UUID objID = UUID.Zero; 8576 UUID objID = UUID.Zero;
7884 LSL_List result = new LSL_List(); 8577 LSL_List result = new LSL_List();
8578
8579 // If the ID is not valid, return null result
7885 if (!UUID.TryParse(obj, out objID)) 8580 if (!UUID.TryParse(obj, out objID))
7886 { 8581 {
7887 result.Add(new LSL_Vector()); 8582 result.Add(new LSL_Vector());
7888 result.Add(new LSL_Vector()); 8583 result.Add(new LSL_Vector());
7889 return result; 8584 return result;
7890 } 8585 }
8586
8587 // Check if this is an attached prim. If so, replace
8588 // the UUID with the avatar UUID and report it's bounding box
8589 SceneObjectPart part = World.GetSceneObjectPart(objID);
8590 if (part != null && part.ParentGroup.IsAttachment)
8591 objID = part.ParentGroup.AttachedAvatar;
8592
8593 // Find out if this is an avatar ID. If so, return it's box
7891 ScenePresence presence = World.GetScenePresence(objID); 8594 ScenePresence presence = World.GetScenePresence(objID);
7892 if (presence != null) 8595 if (presence != null)
7893 { 8596 {
7894 if (presence.ParentID == 0) // not sat on an object 8597 // As per LSL Wiki, there is no difference between sitting
8598 // and standing avatar since server 1.36
8599 LSL_Vector lower;
8600 LSL_Vector upper;
8601
8602 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8603
8604 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8605 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8606/*
7895 { 8607 {
7896 LSL_Vector lower; 8608 // This is for ground sitting avatars
7897 LSL_Vector upper; 8609 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7898 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8610 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7899 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8611 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7900 {
7901 // This is for ground sitting avatars
7902 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7903 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7904 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7905 }
7906 else
7907 {
7908 // This is for standing/flying avatars
7909 float height = presence.Appearance.AvatarHeight / 2.0f;
7910 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7911 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7912 }
7913 result.Add(lower);
7914 result.Add(upper);
7915 return result;
7916 } 8612 }
7917 else 8613 else
7918 { 8614 {
7919 // sitting on an object so we need the bounding box of that 8615 // This is for standing/flying avatars
7920 // which should include the avatar so set the UUID to the 8616 float height = presence.Appearance.AvatarHeight / 2.0f;
7921 // UUID of the object the avatar is sat on and allow it to fall through 8617 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7922 // to processing an object 8618 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7923 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7924 objID = p.UUID;
7925 } 8619 }
8620
8621 // Adjust to the documented error offsets (see LSL Wiki)
8622 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8623 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8624*/
8625 {
8626 // This is for ground sitting avatars TODO!
8627 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8628 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8629 }
8630 else
8631 {
8632 // This is for standing/flying avatars
8633 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8634 upper = new LSL_Vector(box.X, box.Y, box.Z);
8635 }
8636
8637 if (lower.x > upper.x)
8638 lower.x = upper.x;
8639 if (lower.y > upper.y)
8640 lower.y = upper.y;
8641 if (lower.z > upper.z)
8642 lower.z = upper.z;
8643
8644 result.Add(lower);
8645 result.Add(upper);
8646 return result;
7926 } 8647 }
7927 SceneObjectPart part = World.GetSceneObjectPart(objID); 8648
8649 part = World.GetSceneObjectPart(objID);
7928 // Currently only works for single prims without a sitting avatar 8650 // Currently only works for single prims without a sitting avatar
7929 if (part != null) 8651 if (part != null)
7930 { 8652 {
7931 Vector3 halfSize = part.Scale / 2.0f; 8653 float minX;
7932 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8654 float maxX;
7933 LSL_Vector upper = new LSL_Vector(halfSize); 8655 float minY;
8656 float maxY;
8657 float minZ;
8658 float maxZ;
8659
8660 // This BBox is in sim coordinates, with the offset being
8661 // a contained point.
8662 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8663 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8664
8665 minX -= offsets[0].X;
8666 maxX -= offsets[0].X;
8667 minY -= offsets[0].Y;
8668 maxY -= offsets[0].Y;
8669 minZ -= offsets[0].Z;
8670 maxZ -= offsets[0].Z;
8671
8672 LSL_Vector lower;
8673 LSL_Vector upper;
8674
8675 // Adjust to the documented error offsets (see LSL Wiki)
8676 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8677 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8678
8679 if (lower.x > upper.x)
8680 lower.x = upper.x;
8681 if (lower.y > upper.y)
8682 lower.y = upper.y;
8683 if (lower.z > upper.z)
8684 lower.z = upper.z;
8685
7934 result.Add(lower); 8686 result.Add(lower);
7935 result.Add(upper); 8687 result.Add(upper);
7936 return result; 8688 return result;
@@ -7944,7 +8696,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7944 8696
7945 public LSL_Vector llGetGeometricCenter() 8697 public LSL_Vector llGetGeometricCenter()
7946 { 8698 {
7947 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8699 Vector3 tmp = m_host.GetGeometricCenter();
8700 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7948 } 8701 }
7949 8702
7950 public LSL_List llGetPrimitiveParams(LSL_List rules) 8703 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7955,7 +8708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 8708
7956 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8709 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7957 8710
7958 while (remaining != null && remaining.Length > 2) 8711 while ((object)remaining != null && remaining.Length > 2)
7959 { 8712 {
7960 int linknumber = remaining.GetLSLIntegerItem(0); 8713 int linknumber = remaining.GetLSLIntegerItem(0);
7961 rules = remaining.GetSublist(1, -1); 8714 rules = remaining.GetSublist(1, -1);
@@ -7972,24 +8725,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7972 { 8725 {
7973 m_host.AddScriptLPS(1); 8726 m_host.AddScriptLPS(1);
7974 8727
7975 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8728 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8729 // keep other options as before
7976 8730
8731 List<SceneObjectPart> parts;
8732 List<ScenePresence> avatars;
8733
7977 LSL_List res = new LSL_List(); 8734 LSL_List res = new LSL_List();
7978 LSL_List remaining = null; 8735 LSL_List remaining = null;
7979 8736
7980 foreach (SceneObjectPart part in parts) 8737 while (rules.Length > 0)
7981 {
7982 remaining = GetPrimParams(part, rules, ref res);
7983 }
7984
7985 while (remaining != null && remaining.Length > 2)
7986 { 8738 {
7987 linknumber = remaining.GetLSLIntegerItem(0);
7988 rules = remaining.GetSublist(1, -1);
7989 parts = GetLinkParts(linknumber); 8739 parts = GetLinkParts(linknumber);
8740 avatars = GetLinkAvatars(linknumber);
7990 8741
8742 remaining = null;
7991 foreach (SceneObjectPart part in parts) 8743 foreach (SceneObjectPart part in parts)
8744 {
7992 remaining = GetPrimParams(part, rules, ref res); 8745 remaining = GetPrimParams(part, rules, ref res);
8746 }
8747 foreach (ScenePresence avatar in avatars)
8748 {
8749 remaining = GetPrimParams(avatar, rules, ref res);
8750 }
8751
8752 if ((object)remaining != null && remaining.Length > 0)
8753 {
8754 linknumber = remaining.GetLSLIntegerItem(0);
8755 rules = remaining.GetSublist(1, -1);
8756 }
8757 else
8758 break;
7993 } 8759 }
7994 8760
7995 return res; 8761 return res;
@@ -8034,13 +8800,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8034 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8800 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8035 part.AbsolutePosition.Y, 8801 part.AbsolutePosition.Y,
8036 part.AbsolutePosition.Z); 8802 part.AbsolutePosition.Z);
8037 // For some reason, the part.AbsolutePosition.* values do not change if the
8038 // linkset is rotated; they always reflect the child prim's world position
8039 // as though the linkset is unrotated. This is incompatible behavior with SL's
8040 // implementation, so will break scripts imported from there (not to mention it
8041 // makes it more difficult to determine a child prim's actual inworld position).
8042 if (part.ParentID != 0)
8043 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8044 res.Add(v); 8803 res.Add(v);
8045 break; 8804 break;
8046 8805
@@ -8212,30 +8971,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8212 if (remain < 1) 8971 if (remain < 1)
8213 return null; 8972 return null;
8214 8973
8215 face=(int)rules.GetLSLIntegerItem(idx++); 8974 face = (int)rules.GetLSLIntegerItem(idx++);
8216 8975
8217 tex = part.Shape.Textures; 8976 tex = part.Shape.Textures;
8977 int shiny;
8218 if (face == ScriptBaseClass.ALL_SIDES) 8978 if (face == ScriptBaseClass.ALL_SIDES)
8219 { 8979 {
8220 for (face = 0; face < GetNumberOfSides(part); face++) 8980 for (face = 0; face < GetNumberOfSides(part); face++)
8221 { 8981 {
8222 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8982 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8223 // Convert Shininess to PRIM_SHINY_* 8983 if (shinyness == Shininess.High)
8224 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8984 {
8225 // PRIM_BUMP_* 8985 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8226 res.Add(new LSL_Integer((int)texface.Bump)); 8986 }
8987 else if (shinyness == Shininess.Medium)
8988 {
8989 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8990 }
8991 else if (shinyness == Shininess.Low)
8992 {
8993 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8994 }
8995 else
8996 {
8997 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8998 }
8999 res.Add(new LSL_Integer(shiny));
9000 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8227 } 9001 }
8228 } 9002 }
8229 else 9003 else
8230 { 9004 {
8231 if (face >= 0 && face < GetNumberOfSides(part)) 9005 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9006 if (shinyness == Shininess.High)
8232 { 9007 {
8233 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9008 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8234 // Convert Shininess to PRIM_SHINY_* 9009 }
8235 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9010 else if (shinyness == Shininess.Medium)
8236 // PRIM_BUMP_* 9011 {
8237 res.Add(new LSL_Integer((int)texface.Bump)); 9012 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9013 }
9014 else if (shinyness == Shininess.Low)
9015 {
9016 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9017 }
9018 else
9019 {
9020 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8238 } 9021 }
9022 res.Add(new LSL_Integer(shiny));
9023 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8239 } 9024 }
8240 break; 9025 break;
8241 9026
@@ -8243,24 +9028,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8243 if (remain < 1) 9028 if (remain < 1)
8244 return null; 9029 return null;
8245 9030
8246 face=(int)rules.GetLSLIntegerItem(idx++); 9031 face = (int)rules.GetLSLIntegerItem(idx++);
8247 9032
8248 tex = part.Shape.Textures; 9033 tex = part.Shape.Textures;
9034 int fullbright;
8249 if (face == ScriptBaseClass.ALL_SIDES) 9035 if (face == ScriptBaseClass.ALL_SIDES)
8250 { 9036 {
8251 for (face = 0; face < GetNumberOfSides(part); face++) 9037 for (face = 0; face < GetNumberOfSides(part); face++)
8252 { 9038 {
8253 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9039 if (tex.GetFace((uint)face).Fullbright == true)
8254 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9040 {
9041 fullbright = ScriptBaseClass.TRUE;
9042 }
9043 else
9044 {
9045 fullbright = ScriptBaseClass.FALSE;
9046 }
9047 res.Add(new LSL_Integer(fullbright));
8255 } 9048 }
8256 } 9049 }
8257 else 9050 else
8258 { 9051 {
8259 if (face >= 0 && face < GetNumberOfSides(part)) 9052 if (tex.GetFace((uint)face).Fullbright == true)
8260 { 9053 {
8261 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9054 fullbright = ScriptBaseClass.TRUE;
8262 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9055 }
9056 else
9057 {
9058 fullbright = ScriptBaseClass.FALSE;
8263 } 9059 }
9060 res.Add(new LSL_Integer(fullbright));
8264 } 9061 }
8265 break; 9062 break;
8266 9063
@@ -8282,27 +9079,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8282 break; 9079 break;
8283 9080
8284 case (int)ScriptBaseClass.PRIM_TEXGEN: 9081 case (int)ScriptBaseClass.PRIM_TEXGEN:
9082 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8285 if (remain < 1) 9083 if (remain < 1)
8286 return null; 9084 return null;
8287 9085
8288 face=(int)rules.GetLSLIntegerItem(idx++); 9086 face = (int)rules.GetLSLIntegerItem(idx++);
8289 9087
8290 tex = part.Shape.Textures; 9088 tex = part.Shape.Textures;
8291 if (face == ScriptBaseClass.ALL_SIDES) 9089 if (face == ScriptBaseClass.ALL_SIDES)
8292 { 9090 {
8293 for (face = 0; face < GetNumberOfSides(part); face++) 9091 for (face = 0; face < GetNumberOfSides(part); face++)
8294 { 9092 {
8295 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9093 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8296 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9094 {
8297 res.Add(new LSL_Integer((uint)texgen >> 1)); 9095 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9096 }
9097 else
9098 {
9099 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9100 }
8298 } 9101 }
8299 } 9102 }
8300 else 9103 else
8301 { 9104 {
8302 if (face >= 0 && face < GetNumberOfSides(part)) 9105 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8303 { 9106 {
8304 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9107 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8305 res.Add(new LSL_Integer((uint)texgen >> 1)); 9108 }
9109 else
9110 {
9111 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8306 } 9112 }
8307 } 9113 }
8308 break; 9114 break;
@@ -8326,24 +9132,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8326 if (remain < 1) 9132 if (remain < 1)
8327 return null; 9133 return null;
8328 9134
8329 face=(int)rules.GetLSLIntegerItem(idx++); 9135 face = (int)rules.GetLSLIntegerItem(idx++);
8330 9136
8331 tex = part.Shape.Textures; 9137 tex = part.Shape.Textures;
9138 float primglow;
8332 if (face == ScriptBaseClass.ALL_SIDES) 9139 if (face == ScriptBaseClass.ALL_SIDES)
8333 { 9140 {
8334 for (face = 0; face < GetNumberOfSides(part); face++) 9141 for (face = 0; face < GetNumberOfSides(part); face++)
8335 { 9142 {
8336 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9143 primglow = tex.GetFace((uint)face).Glow;
8337 res.Add(new LSL_Float(texface.Glow)); 9144 res.Add(new LSL_Float(primglow));
8338 } 9145 }
8339 } 9146 }
8340 else 9147 else
8341 { 9148 {
8342 if (face >= 0 && face < GetNumberOfSides(part)) 9149 primglow = tex.GetFace((uint)face).Glow;
8343 { 9150 res.Add(new LSL_Float(primglow));
8344 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8345 res.Add(new LSL_Float(texface.Glow));
8346 }
8347 } 9151 }
8348 break; 9152 break;
8349 9153
@@ -8355,15 +9159,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8355 textColor.B)); 9159 textColor.B));
8356 res.Add(new LSL_Float(textColor.A)); 9160 res.Add(new LSL_Float(textColor.A));
8357 break; 9161 break;
9162
8358 case (int)ScriptBaseClass.PRIM_NAME: 9163 case (int)ScriptBaseClass.PRIM_NAME:
8359 res.Add(new LSL_String(part.Name)); 9164 res.Add(new LSL_String(part.Name));
8360 break; 9165 break;
9166
8361 case (int)ScriptBaseClass.PRIM_DESC: 9167 case (int)ScriptBaseClass.PRIM_DESC:
8362 res.Add(new LSL_String(part.Description)); 9168 res.Add(new LSL_String(part.Description));
8363 break; 9169 break;
9170
8364 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9171 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8365 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9172 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8366 break; 9173 break;
9174
8367 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9175 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8368 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9176 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8369 break; 9177 break;
@@ -8974,8 +9782,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8974 // The function returns an ordered list 9782 // The function returns an ordered list
8975 // representing the tokens found in the supplied 9783 // representing the tokens found in the supplied
8976 // sources string. If two successive tokenizers 9784 // sources string. If two successive tokenizers
8977 // are encountered, then a NULL entry is added 9785 // are encountered, then a null-string entry is
8978 // to the list. 9786 // added to the list.
8979 // 9787 //
8980 // It is a precondition that the source and 9788 // It is a precondition that the source and
8981 // toekizer lisst are non-null. If they are null, 9789 // toekizer lisst are non-null. If they are null,
@@ -8983,7 +9791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8983 // while their lengths are being determined. 9791 // while their lengths are being determined.
8984 // 9792 //
8985 // A small amount of working memoryis required 9793 // A small amount of working memoryis required
8986 // of approximately 8*#tokenizers. 9794 // of approximately 8*#tokenizers + 8*srcstrlen.
8987 // 9795 //
8988 // There are many ways in which this function 9796 // There are many ways in which this function
8989 // can be implemented, this implementation is 9797 // can be implemented, this implementation is
@@ -8999,155 +9807,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8999 // and eliminates redundant tokenizers as soon 9807 // and eliminates redundant tokenizers as soon
9000 // as is possible. 9808 // as is possible.
9001 // 9809 //
9002 // The implementation tries to avoid any copying 9810 // The implementation tries to minimize temporary
9003 // of arrays or other objects. 9811 // garbage generation.
9004 // </remarks> 9812 // </remarks>
9005 9813
9006 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9814 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9007 { 9815 {
9008 int beginning = 0; 9816 return ParseString2List(src, separators, spacers, true);
9009 int srclen = src.Length; 9817 }
9010 int seplen = separators.Length;
9011 object[] separray = separators.Data;
9012 int spclen = spacers.Length;
9013 object[] spcarray = spacers.Data;
9014 int mlen = seplen+spclen;
9015
9016 int[] offset = new int[mlen+1];
9017 bool[] active = new bool[mlen];
9018
9019 int best;
9020 int j;
9021
9022 // Initial capacity reduces resize cost
9023 9818
9024 LSL_List tokens = new LSL_List(); 9819 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9820 {
9821 int srclen = src.Length;
9822 int seplen = separators.Length;
9823 object[] separray = separators.Data;
9824 int spclen = spacers.Length;
9825 object[] spcarray = spacers.Data;
9826 int dellen = 0;
9827 string[] delarray = new string[seplen+spclen];
9025 9828
9026 // All entries are initially valid 9829 int outlen = 0;
9830 string[] outarray = new string[srclen*2+1];
9027 9831
9028 for (int i = 0; i < mlen; i++) 9832 int i, j;
9029 active[i] = true; 9833 string d;
9030 9834
9031 offset[mlen] = srclen; 9835 m_host.AddScriptLPS(1);
9032 9836
9033 while (beginning < srclen) 9837 /*
9838 * Convert separator and spacer lists to C# strings.
9839 * Also filter out null strings so we don't hang.
9840 */
9841 for (i = 0; i < seplen; i ++)
9034 { 9842 {
9843 d = separray[i].ToString();
9844 if (d.Length > 0)
9845 {
9846 delarray[dellen++] = d;
9847 }
9848 }
9849 seplen = dellen;
9035 9850
9036 best = mlen; // as bad as it gets 9851 for (i = 0; i < spclen; i ++)
9852 {
9853 d = spcarray[i].ToString();
9854 if (d.Length > 0)
9855 {
9856 delarray[dellen++] = d;
9857 }
9858 }
9037 9859
9038 // Scan for separators 9860 /*
9861 * Scan through source string from beginning to end.
9862 */
9863 for (i = 0;;)
9864 {
9039 9865
9040 for (j = 0; j < seplen; j++) 9866 /*
9867 * Find earliest delimeter in src starting at i (if any).
9868 */
9869 int earliestDel = -1;
9870 int earliestSrc = srclen;
9871 string earliestStr = null;
9872 for (j = 0; j < dellen; j ++)
9041 { 9873 {
9042 if (separray[j].ToString() == String.Empty) 9874 d = delarray[j];
9043 active[j] = false; 9875 if (d != null)
9044
9045 if (active[j])
9046 { 9876 {
9047 // scan all of the markers 9877 int index = src.IndexOf(d, i);
9048 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9878 if (index < 0)
9049 { 9879 {
9050 // not present at all 9880 delarray[j] = null; // delim nowhere in src, don't check it anymore
9051 active[j] = false;
9052 } 9881 }
9053 else 9882 else if (index < earliestSrc)
9054 { 9883 {
9055 // present and correct 9884 earliestSrc = index; // where delimeter starts in source string
9056 if (offset[j] < offset[best]) 9885 earliestDel = j; // where delimeter is in delarray[]
9057 { 9886 earliestStr = d; // the delimeter string from delarray[]
9058 // closest so far 9887 if (index == i) break; // can't do any better than found at beg of string
9059 best = j;
9060 if (offset[best] == beginning)
9061 break;
9062 }
9063 } 9888 }
9064 } 9889 }
9065 } 9890 }
9066 9891
9067 // Scan for spacers 9892 /*
9068 9893 * Output source string starting at i through start of earliest delimeter.
9069 if (offset[best] != beginning) 9894 */
9895 if (keepNulls || (earliestSrc > i))
9070 { 9896 {
9071 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9897 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9072 {
9073 if (spcarray[j-seplen].ToString() == String.Empty)
9074 active[j] = false;
9075
9076 if (active[j])
9077 {
9078 // scan all of the markers
9079 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9080 {
9081 // not present at all
9082 active[j] = false;
9083 }
9084 else
9085 {
9086 // present and correct
9087 if (offset[j] < offset[best])
9088 {
9089 // closest so far
9090 best = j;
9091 }
9092 }
9093 }
9094 }
9095 } 9898 }
9096 9899
9097 // This is the normal exit from the scanning loop 9900 /*
9901 * If no delimeter found at or after i, we're done scanning.
9902 */
9903 if (earliestDel < 0) break;
9098 9904
9099 if (best == mlen) 9905 /*
9906 * If delimeter was a spacer, output the spacer.
9907 */
9908 if (earliestDel >= seplen)
9100 { 9909 {
9101 // no markers were found on this pass 9910 outarray[outlen++] = earliestStr;
9102 // so we're pretty much done
9103 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9104 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9105 break;
9106 } 9911 }
9107 9912
9108 // Otherwise we just add the newly delimited token 9913 /*
9109 // and recalculate where the search should continue. 9914 * Look at rest of src string following delimeter.
9110 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9915 */
9111 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9916 i = earliestSrc + earliestStr.Length;
9112
9113 if (best < seplen)
9114 {
9115 beginning = offset[best] + (separray[best].ToString()).Length;
9116 }
9117 else
9118 {
9119 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9120 string str = spcarray[best - seplen].ToString();
9121 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9122 tokens.Add(new LSL_String(str));
9123 }
9124 } 9917 }
9125 9918
9126 // This an awkward an not very intuitive boundary case. If the 9919 /*
9127 // last substring is a tokenizer, then there is an implied trailing 9920 * Make up an exact-sized output array suitable for an LSL_List object.
9128 // null list entry. Hopefully the single comparison will not be too 9921 */
9129 // arduous. Alternatively the 'break' could be replced with a return 9922 object[] outlist = new object[outlen];
9130 // but that's shabby programming. 9923 for (i = 0; i < outlen; i ++)
9131
9132 if ((beginning == srclen) && (keepNulls))
9133 { 9924 {
9134 if (srclen != 0) 9925 outlist[i] = new LSL_String(outarray[i]);
9135 tokens.Add(new LSL_String(""));
9136 } 9926 }
9137 9927 return new LSL_List(outlist);
9138 return tokens;
9139 }
9140
9141 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9142 {
9143 m_host.AddScriptLPS(1);
9144 return this.ParseString(src, separators, spacers, false);
9145 }
9146
9147 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9148 {
9149 m_host.AddScriptLPS(1);
9150 return this.ParseString(src, separators, spacers, true);
9151 } 9928 }
9152 9929
9153 public LSL_Integer llGetObjectPermMask(int mask) 9930 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9242,6 +10019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9242 case 4: 10019 case 4:
9243 return (int)item.NextPermissions; 10020 return (int)item.NextPermissions;
9244 } 10021 }
10022 m_host.TaskInventory.LockItemsForRead(false);
9245 10023
9246 return -1; 10024 return -1;
9247 } 10025 }
@@ -9444,31 +10222,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9444 UUID key = new UUID(); 10222 UUID key = new UUID();
9445 if (UUID.TryParse(id, out key)) 10223 if (UUID.TryParse(id, out key))
9446 { 10224 {
9447 try 10225 // return total object mass
9448 { 10226 SceneObjectPart part = World.GetSceneObjectPart(key);
9449 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10227 if (part != null)
9450 if (obj != null) 10228 return part.ParentGroup.GetMass();
9451 return (double)obj.GetMass(); 10229
9452 // the object is null so the key is for an avatar 10230 // the object is null so the key is for an avatar
9453 ScenePresence avatar = World.GetScenePresence(key); 10231 ScenePresence avatar = World.GetScenePresence(key);
9454 if (avatar != null) 10232 if (avatar != null)
9455 if (avatar.IsChildAgent)
9456 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9457 // child agents have a mass of 1.0
9458 return 1;
9459 else
9460 return (double)avatar.GetMass();
9461 }
9462 catch (KeyNotFoundException)
9463 { 10233 {
9464 return 0; // The Object/Agent not in the region so just return zero 10234 if (avatar.IsChildAgent)
10235 {
10236 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10237 // child agents have a mass of 1.0
10238 return 1;
10239 }
10240 else
10241 {
10242 return (double)avatar.GetMass();
10243 }
9465 } 10244 }
9466 } 10245 }
9467 return 0; 10246 return 0;
9468 } 10247 }
9469 10248
9470 /// <summary> 10249 /// <summary>
9471 /// illListReplaceList removes the sub-list defined by the inclusive indices 10250 /// llListReplaceList removes the sub-list defined by the inclusive indices
9472 /// start and end and inserts the src list in its place. The inclusive 10251 /// start and end and inserts the src list in its place. The inclusive
9473 /// nature of the indices means that at least one element must be deleted 10252 /// nature of the indices means that at least one element must be deleted
9474 /// if the indices are within the bounds of the existing list. I.e. 2,2 10253 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9525,16 +10304,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9525 // based upon end. Note that if end exceeds the upper 10304 // based upon end. Note that if end exceeds the upper
9526 // bound in this case, the entire destination list 10305 // bound in this case, the entire destination list
9527 // is removed. 10306 // is removed.
9528 else 10307 else if (start == 0)
9529 { 10308 {
9530 if (end + 1 < dest.Length) 10309 if (end + 1 < dest.Length)
9531 {
9532 return src + dest.GetSublist(end + 1, -1); 10310 return src + dest.GetSublist(end + 1, -1);
9533 }
9534 else 10311 else
9535 {
9536 return src; 10312 return src;
9537 } 10313 }
10314 else // Start < 0
10315 {
10316 if (end + 1 < dest.Length)
10317 return dest.GetSublist(end + 1, -1);
10318 else
10319 return new LSL_List();
9538 } 10320 }
9539 } 10321 }
9540 // Finally, if start > end, we strip away a prefix and 10322 // Finally, if start > end, we strip away a prefix and
@@ -9585,17 +10367,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9585 int width = 0; 10367 int width = 0;
9586 int height = 0; 10368 int height = 0;
9587 10369
9588 ParcelMediaCommandEnum? commandToSend = null; 10370 uint commandToSend = 0;
9589 float time = 0.0f; // default is from start 10371 float time = 0.0f; // default is from start
9590 10372
9591 ScenePresence presence = null; 10373 ScenePresence presence = null;
9592 10374
9593 for (int i = 0; i < commandList.Data.Length; i++) 10375 for (int i = 0; i < commandList.Data.Length; i++)
9594 { 10376 {
9595 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10377 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9596 switch (command) 10378 switch (command)
9597 { 10379 {
9598 case ParcelMediaCommandEnum.Agent: 10380 case (uint)ParcelMediaCommandEnum.Agent:
9599 // we send only to one agent 10381 // we send only to one agent
9600 if ((i + 1) < commandList.Length) 10382 if ((i + 1) < commandList.Length)
9601 { 10383 {
@@ -9612,25 +10394,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9612 } 10394 }
9613 break; 10395 break;
9614 10396
9615 case ParcelMediaCommandEnum.Loop: 10397 case (uint)ParcelMediaCommandEnum.Loop:
9616 loop = 1; 10398 loop = 1;
9617 commandToSend = command; 10399 commandToSend = command;
9618 update = true; //need to send the media update packet to set looping 10400 update = true; //need to send the media update packet to set looping
9619 break; 10401 break;
9620 10402
9621 case ParcelMediaCommandEnum.Play: 10403 case (uint)ParcelMediaCommandEnum.Play:
9622 loop = 0; 10404 loop = 0;
9623 commandToSend = command; 10405 commandToSend = command;
9624 update = true; //need to send the media update packet to make sure it doesn't loop 10406 update = true; //need to send the media update packet to make sure it doesn't loop
9625 break; 10407 break;
9626 10408
9627 case ParcelMediaCommandEnum.Pause: 10409 case (uint)ParcelMediaCommandEnum.Pause:
9628 case ParcelMediaCommandEnum.Stop: 10410 case (uint)ParcelMediaCommandEnum.Stop:
9629 case ParcelMediaCommandEnum.Unload: 10411 case (uint)ParcelMediaCommandEnum.Unload:
9630 commandToSend = command; 10412 commandToSend = command;
9631 break; 10413 break;
9632 10414
9633 case ParcelMediaCommandEnum.Url: 10415 case (uint)ParcelMediaCommandEnum.Url:
9634 if ((i + 1) < commandList.Length) 10416 if ((i + 1) < commandList.Length)
9635 { 10417 {
9636 if (commandList.Data[i + 1] is LSL_String) 10418 if (commandList.Data[i + 1] is LSL_String)
@@ -9643,7 +10425,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9643 } 10425 }
9644 break; 10426 break;
9645 10427
9646 case ParcelMediaCommandEnum.Texture: 10428 case (uint)ParcelMediaCommandEnum.Texture:
9647 if ((i + 1) < commandList.Length) 10429 if ((i + 1) < commandList.Length)
9648 { 10430 {
9649 if (commandList.Data[i + 1] is LSL_String) 10431 if (commandList.Data[i + 1] is LSL_String)
@@ -9656,7 +10438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 } 10438 }
9657 break; 10439 break;
9658 10440
9659 case ParcelMediaCommandEnum.Time: 10441 case (uint)ParcelMediaCommandEnum.Time:
9660 if ((i + 1) < commandList.Length) 10442 if ((i + 1) < commandList.Length)
9661 { 10443 {
9662 if (commandList.Data[i + 1] is LSL_Float) 10444 if (commandList.Data[i + 1] is LSL_Float)
@@ -9668,7 +10450,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9668 } 10450 }
9669 break; 10451 break;
9670 10452
9671 case ParcelMediaCommandEnum.AutoAlign: 10453 case (uint)ParcelMediaCommandEnum.AutoAlign:
9672 if ((i + 1) < commandList.Length) 10454 if ((i + 1) < commandList.Length)
9673 { 10455 {
9674 if (commandList.Data[i + 1] is LSL_Integer) 10456 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9682,7 +10464,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 } 10464 }
9683 break; 10465 break;
9684 10466
9685 case ParcelMediaCommandEnum.Type: 10467 case (uint)ParcelMediaCommandEnum.Type:
9686 if ((i + 1) < commandList.Length) 10468 if ((i + 1) < commandList.Length)
9687 { 10469 {
9688 if (commandList.Data[i + 1] is LSL_String) 10470 if (commandList.Data[i + 1] is LSL_String)
@@ -9695,7 +10477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 } 10477 }
9696 break; 10478 break;
9697 10479
9698 case ParcelMediaCommandEnum.Desc: 10480 case (uint)ParcelMediaCommandEnum.Desc:
9699 if ((i + 1) < commandList.Length) 10481 if ((i + 1) < commandList.Length)
9700 { 10482 {
9701 if (commandList.Data[i + 1] is LSL_String) 10483 if (commandList.Data[i + 1] is LSL_String)
@@ -9708,7 +10490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9708 } 10490 }
9709 break; 10491 break;
9710 10492
9711 case ParcelMediaCommandEnum.Size: 10493 case (uint)ParcelMediaCommandEnum.Size:
9712 if ((i + 2) < commandList.Length) 10494 if ((i + 2) < commandList.Length)
9713 { 10495 {
9714 if (commandList.Data[i + 1] is LSL_Integer) 10496 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9778,7 +10560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9778 } 10560 }
9779 } 10561 }
9780 10562
9781 if (commandToSend != null) 10563 if (commandToSend != 0)
9782 { 10564 {
9783 // the commandList contained a start/stop/... command, too 10565 // the commandList contained a start/stop/... command, too
9784 if (presence == null) 10566 if (presence == null)
@@ -9815,7 +10597,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9815 10597
9816 if (aList.Data[i] != null) 10598 if (aList.Data[i] != null)
9817 { 10599 {
9818 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10600 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9819 { 10601 {
9820 case ParcelMediaCommandEnum.Url: 10602 case ParcelMediaCommandEnum.Url:
9821 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10603 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9872,15 +10654,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9872 10654
9873 if (quick_pay_buttons.Data.Length < 4) 10655 if (quick_pay_buttons.Data.Length < 4)
9874 { 10656 {
9875 LSLError("List must have at least 4 elements"); 10657 int x;
9876 return; 10658 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10659 {
10660 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10661 }
9877 } 10662 }
9878 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10663 int[] nPrice = new int[5];
9879 10664 nPrice[0] = price;
9880 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10665 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9881 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10666 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9882 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10667 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9883 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10668 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10669 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9884 m_host.ParentGroup.HasGroupChanged = true; 10670 m_host.ParentGroup.HasGroupChanged = true;
9885 } 10671 }
9886 10672
@@ -9897,7 +10683,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9897 return new LSL_Vector(); 10683 return new LSL_Vector();
9898 } 10684 }
9899 10685
9900 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10686// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10687 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9901 if (presence != null) 10688 if (presence != null)
9902 { 10689 {
9903 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10690 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9919,7 +10706,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9919 return new LSL_Rotation(); 10706 return new LSL_Rotation();
9920 } 10707 }
9921 10708
9922 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10709// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10710 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9923 if (presence != null) 10711 if (presence != null)
9924 { 10712 {
9925 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10713 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9979,14 +10767,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9979 { 10767 {
9980 m_host.AddScriptLPS(1); 10768 m_host.AddScriptLPS(1);
9981 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10769 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9982 if (detectedParams == null) return; // only works on the first detected avatar 10770 if (detectedParams == null)
9983 10771 {
10772 if (m_host.ParentGroup.IsAttachment == true)
10773 {
10774 detectedParams = new DetectParams();
10775 detectedParams.Key = m_host.OwnerID;
10776 }
10777 else
10778 {
10779 return;
10780 }
10781 }
10782
9984 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10783 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9985 if (avatar != null) 10784 if (avatar != null)
9986 { 10785 {
9987 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10786 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9988 simname, pos, lookAt); 10787 simname, pos, lookAt);
9989 } 10788 }
10789
9990 ScriptSleep(1000); 10790 ScriptSleep(1000);
9991 } 10791 }
9992 10792
@@ -10110,12 +10910,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10110 10910
10111 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10911 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10112 object[] data = rules.Data; 10912 object[] data = rules.Data;
10113 for (int i = 0; i < data.Length; ++i) { 10913 for (int i = 0; i < data.Length; ++i)
10914 {
10114 int type = Convert.ToInt32(data[i++].ToString()); 10915 int type = Convert.ToInt32(data[i++].ToString());
10115 if (i >= data.Length) break; // odd number of entries => ignore the last 10916 if (i >= data.Length) break; // odd number of entries => ignore the last
10116 10917
10117 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10918 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10118 switch (type) { 10919 switch (type)
10920 {
10119 case ScriptBaseClass.CAMERA_FOCUS: 10921 case ScriptBaseClass.CAMERA_FOCUS:
10120 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10922 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10121 case ScriptBaseClass.CAMERA_POSITION: 10923 case ScriptBaseClass.CAMERA_POSITION:
@@ -10220,19 +11022,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10220 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11022 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10221 { 11023 {
10222 m_host.AddScriptLPS(1); 11024 m_host.AddScriptLPS(1);
10223 string ret = String.Empty; 11025
10224 string src1 = llBase64ToString(str1); 11026 if (str1 == String.Empty)
10225 string src2 = llBase64ToString(str2); 11027 return String.Empty;
10226 int c = 0; 11028 if (str2 == String.Empty)
10227 for (int i = 0; i < src1.Length; i++) 11029 return str1;
11030
11031 int len = str2.Length;
11032 if ((len % 4) != 0) // LL is EVIL!!!!
11033 {
11034 while (str2.EndsWith("="))
11035 str2 = str2.Substring(0, str2.Length - 1);
11036
11037 len = str2.Length;
11038 int mod = len % 4;
11039
11040 if (mod == 1)
11041 str2 = str2.Substring(0, str2.Length - 1);
11042 else if (mod == 2)
11043 str2 += "==";
11044 else if (mod == 3)
11045 str2 += "=";
11046 }
11047
11048 byte[] data1;
11049 byte[] data2;
11050 try
10228 { 11051 {
10229 ret += (char) (src1[i] ^ src2[c]); 11052 data1 = Convert.FromBase64String(str1);
11053 data2 = Convert.FromBase64String(str2);
11054 }
11055 catch (Exception)
11056 {
11057 return new LSL_String(String.Empty);
11058 }
10230 11059
10231 c++; 11060 byte[] d2 = new Byte[data1.Length];
10232 if (c >= src2.Length) 11061 int pos = 0;
10233 c = 0; 11062
11063 if (data1.Length <= data2.Length)
11064 {
11065 Array.Copy(data2, 0, d2, 0, data1.Length);
10234 } 11066 }
10235 return llStringToBase64(ret); 11067 else
11068 {
11069 while (pos < data1.Length)
11070 {
11071 len = data1.Length - pos;
11072 if (len > data2.Length)
11073 len = data2.Length;
11074
11075 Array.Copy(data2, 0, d2, pos, len);
11076 pos += len;
11077 }
11078 }
11079
11080 for (pos = 0 ; pos < data1.Length ; pos++ )
11081 data1[pos] ^= d2[pos];
11082
11083 return Convert.ToBase64String(data1);
10236 } 11084 }
10237 11085
10238 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11086 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10285,16 +11133,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10285 if (userAgent != null) 11133 if (userAgent != null)
10286 httpHeaders["User-Agent"] = userAgent; 11134 httpHeaders["User-Agent"] = userAgent;
10287 11135
11136 // See if the URL contains any header hacks
11137 string[] urlParts = url.Split(new char[] {'\n'});
11138 if (urlParts.Length > 1)
11139 {
11140 // Iterate the passed headers and parse them
11141 for (int i = 1 ; i < urlParts.Length ; i++ )
11142 {
11143 // The rest of those would be added to the body in SL.
11144 // Let's not do that.
11145 if (urlParts[i] == String.Empty)
11146 break;
11147
11148 // See if this could be a valid header
11149 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11150 if (headerParts.Length != 2)
11151 continue;
11152
11153 string headerName = headerParts[0].Trim();
11154 string headerValue = headerParts[1].Trim();
11155
11156 // Filter out headers that could be used to abuse
11157 // another system or cloak the request
11158 if (headerName.ToLower() == "x-secondlife-shard" ||
11159 headerName.ToLower() == "x-secondlife-object-name" ||
11160 headerName.ToLower() == "x-secondlife-object-key" ||
11161 headerName.ToLower() == "x-secondlife-region" ||
11162 headerName.ToLower() == "x-secondlife-local-position" ||
11163 headerName.ToLower() == "x-secondlife-local-velocity" ||
11164 headerName.ToLower() == "x-secondlife-local-rotation" ||
11165 headerName.ToLower() == "x-secondlife-owner-name" ||
11166 headerName.ToLower() == "x-secondlife-owner-key" ||
11167 headerName.ToLower() == "connection" ||
11168 headerName.ToLower() == "content-length" ||
11169 headerName.ToLower() == "from" ||
11170 headerName.ToLower() == "host" ||
11171 headerName.ToLower() == "proxy-authorization" ||
11172 headerName.ToLower() == "referer" ||
11173 headerName.ToLower() == "trailer" ||
11174 headerName.ToLower() == "transfer-encoding" ||
11175 headerName.ToLower() == "via" ||
11176 headerName.ToLower() == "authorization")
11177 continue;
11178
11179 httpHeaders[headerName] = headerValue;
11180 }
11181
11182 // Finally, strip any protocol specifier from the URL
11183 url = urlParts[0].Trim();
11184 int idx = url.IndexOf(" HTTP/");
11185 if (idx != -1)
11186 url = url.Substring(0, idx);
11187 }
11188
10288 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11189 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10289 Regex r = new Regex(authregex); 11190 Regex r = new Regex(authregex);
10290 int[] gnums = r.GetGroupNumbers(); 11191 int[] gnums = r.GetGroupNumbers();
10291 Match m = r.Match(url); 11192 Match m = r.Match(url);
10292 if (m.Success) { 11193 if (m.Success)
10293 for (int i = 1; i < gnums.Length; i++) { 11194 {
11195 for (int i = 1; i < gnums.Length; i++)
11196 {
10294 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11197 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10295 //CaptureCollection cc = g.Captures; 11198 //CaptureCollection cc = g.Captures;
10296 } 11199 }
10297 if (m.Groups.Count == 5) { 11200 if (m.Groups.Count == 5)
11201 {
10298 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11202 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10299 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11203 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10300 } 11204 }
@@ -10497,6 +11401,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10497 11401
10498 LSL_List ret = new LSL_List(); 11402 LSL_List ret = new LSL_List();
10499 UUID key = new UUID(); 11403 UUID key = new UUID();
11404
11405
10500 if (UUID.TryParse(id, out key)) 11406 if (UUID.TryParse(id, out key))
10501 { 11407 {
10502 ScenePresence av = World.GetScenePresence(key); 11408 ScenePresence av = World.GetScenePresence(key);
@@ -10514,13 +11420,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10514 ret.Add(new LSL_String("")); 11420 ret.Add(new LSL_String(""));
10515 break; 11421 break;
10516 case ScriptBaseClass.OBJECT_POS: 11422 case ScriptBaseClass.OBJECT_POS:
10517 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11423 Vector3 avpos;
11424
11425 if (av.ParentID != 0 && av.ParentPart != null)
11426 {
11427 avpos = av.OffsetPosition;
11428
11429 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11430 avpos -= sitOffset;
11431
11432 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11433 }
11434 else
11435 avpos = av.AbsolutePosition;
11436
11437 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10518 break; 11438 break;
10519 case ScriptBaseClass.OBJECT_ROT: 11439 case ScriptBaseClass.OBJECT_ROT:
10520 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11440 Quaternion avrot = av.Rotation;
11441 if (av.ParentID != 0 && av.ParentPart != null)
11442 {
11443 avrot = av.ParentPart.GetWorldRotation() * avrot;
11444 }
11445 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10521 break; 11446 break;
10522 case ScriptBaseClass.OBJECT_VELOCITY: 11447 case ScriptBaseClass.OBJECT_VELOCITY:
10523 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11448 Vector3 avvel = av.Velocity;
11449 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10524 break; 11450 break;
10525 case ScriptBaseClass.OBJECT_OWNER: 11451 case ScriptBaseClass.OBJECT_OWNER:
10526 ret.Add(new LSL_String(id)); 11452 ret.Add(new LSL_String(id));
@@ -10605,11 +11531,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10605 case ScriptBaseClass.OBJECT_NAME: 11531 case ScriptBaseClass.OBJECT_NAME:
10606 ret.Add(new LSL_String(obj.Name)); 11532 ret.Add(new LSL_String(obj.Name));
10607 break; 11533 break;
10608 case ScriptBaseClass.OBJECT_DESC: 11534 case ScriptBaseClass.OBJECT_DESC:
10609 ret.Add(new LSL_String(obj.Description)); 11535 ret.Add(new LSL_String(obj.Description));
10610 break; 11536 break;
10611 case ScriptBaseClass.OBJECT_POS: 11537 case ScriptBaseClass.OBJECT_POS:
10612 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11538 Vector3 opos = obj.AbsolutePosition;
11539 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10613 break; 11540 break;
10614 case ScriptBaseClass.OBJECT_ROT: 11541 case ScriptBaseClass.OBJECT_ROT:
10615 { 11542 {
@@ -10659,9 +11586,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10659 // The value returned in SL for normal prims is prim count 11586 // The value returned in SL for normal prims is prim count
10660 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11587 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10661 break; 11588 break;
10662 // The following 3 costs I have intentionaly coded to return zero. They are part of 11589
10663 // "Land Impact" calculations. These calculations are probably not applicable 11590 // costs below may need to be diferent for root parts, need to check
10664 // to OpenSim and are not yet complete in SL
10665 case ScriptBaseClass.OBJECT_SERVER_COST: 11591 case ScriptBaseClass.OBJECT_SERVER_COST:
10666 // The linden calculation is here 11592 // The linden calculation is here
10667 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11593 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10669,16 +11595,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10669 ret.Add(new LSL_Float(0)); 11595 ret.Add(new LSL_Float(0));
10670 break; 11596 break;
10671 case ScriptBaseClass.OBJECT_STREAMING_COST: 11597 case ScriptBaseClass.OBJECT_STREAMING_COST:
10672 // The linden calculation is here 11598 // The value returned in SL for normal prims is prim count * 0.06
10673 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11599 ret.Add(new LSL_Float(obj.StreamingCost));
10674 // The value returned in SL for normal prims looks like the prim count * 0.06
10675 ret.Add(new LSL_Float(0));
10676 break; 11600 break;
10677 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11601 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10678 // The linden calculation is here 11602 // The value returned in SL for normal prims is prim count
10679 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11603 ret.Add(new LSL_Float(obj.PhysicsCost));
10680 // The value returned in SL for normal prims looks like the prim count
10681 ret.Add(new LSL_Float(0));
10682 break; 11604 break;
10683 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11605 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10684 ret.Add(new LSL_Float(0)); 11606 ret.Add(new LSL_Float(0));
@@ -10935,15 +11857,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10935 return result; 11857 return result;
10936 } 11858 }
10937 11859
10938 public void print(string str) 11860 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10939 { 11861 {
10940 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11862 List<SceneObjectPart> parts = GetLinkParts(link);
10941 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11863 if (parts.Count < 1)
10942 if (ossl != null) 11864 return 0;
10943 { 11865
10944 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11866 return GetNumberOfSides(parts[0]);
10945 m_log.Info("LSL print():" + str);
10946 }
10947 } 11867 }
10948 11868
10949 private string Name2Username(string name) 11869 private string Name2Username(string name)
@@ -10988,7 +11908,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10988 11908
10989 return rq.ToString(); 11909 return rq.ToString();
10990 } 11910 }
10991 11911/*
11912 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11913 {
11914 m_SayShoutCount = 0;
11915 }
11916*/
10992 private struct Tri 11917 private struct Tri
10993 { 11918 {
10994 public Vector3 p1; 11919 public Vector3 p1;
@@ -11137,9 +12062,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11137 12062
11138 ContactResult result = new ContactResult (); 12063 ContactResult result = new ContactResult ();
11139 result.ConsumerID = group.LocalId; 12064 result.ConsumerID = group.LocalId;
11140 result.Depth = intersection.distance; 12065// result.Depth = intersection.distance;
11141 result.Normal = intersection.normal; 12066 result.Normal = intersection.normal;
11142 result.Pos = intersection.ipoint; 12067 result.Pos = intersection.ipoint;
12068 result.Depth = Vector3.Mag(rayStart - result.Pos);
11143 12069
11144 contacts.Add(result); 12070 contacts.Add(result);
11145 }); 12071 });
@@ -11272,6 +12198,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11272 12198
11273 return contacts[0]; 12199 return contacts[0];
11274 } 12200 }
12201/*
12202 // not done:
12203 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12204 {
12205 ContactResult[] contacts = null;
12206 World.ForEachSOG(delegate(SceneObjectGroup group)
12207 {
12208 if (m_host.ParentGroup == group)
12209 return;
12210
12211 if (group.IsAttachment)
12212 return;
12213
12214 if(group.RootPart.PhysActor != null)
12215 return;
12216
12217 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12218 });
12219 return contacts;
12220 }
12221*/
11275 12222
11276 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12223 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11277 { 12224 {
@@ -11395,18 +12342,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11395 } 12342 }
11396 } 12343 }
11397 12344
12345 // Double check this
11398 if (checkTerrain) 12346 if (checkTerrain)
11399 { 12347 {
11400 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12348 bool skipGroundCheck = false;
11401 if (groundContact != null) 12349
11402 results.Add((ContactResult)groundContact); 12350 foreach (ContactResult c in results)
12351 {
12352 if (c.ConsumerID == 0) // Physics gave us a ground collision
12353 skipGroundCheck = true;
12354 }
12355
12356 if (!skipGroundCheck)
12357 {
12358 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12359 if (groundContact != null)
12360 results.Add((ContactResult)groundContact);
12361 }
11403 } 12362 }
11404 12363
11405 results.Sort(delegate(ContactResult a, ContactResult b) 12364 results.Sort(delegate(ContactResult a, ContactResult b)
11406 { 12365 {
11407 return a.Depth.CompareTo(b.Depth); 12366 return a.Depth.CompareTo(b.Depth);
11408 }); 12367 });
11409 12368
11410 int values = 0; 12369 int values = 0;
11411 SceneObjectGroup thisgrp = m_host.ParentGroup; 12370 SceneObjectGroup thisgrp = m_host.ParentGroup;
11412 12371
@@ -11499,7 +12458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11499 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12458 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11500 if (!isAccount) return 0; 12459 if (!isAccount) return 0;
11501 if (estate.HasAccess(id)) return 1; 12460 if (estate.HasAccess(id)) return 1;
11502 if (estate.IsBanned(id)) 12461 if (estate.IsBanned(id, World.GetUserFlags(id)))
11503 estate.RemoveBan(id); 12462 estate.RemoveBan(id);
11504 estate.AddEstateUser(id); 12463 estate.AddEstateUser(id);
11505 break; 12464 break;
@@ -11518,14 +12477,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11518 break; 12477 break;
11519 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12478 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11520 if (!isAccount) return 0; 12479 if (!isAccount) return 0;
11521 if (estate.IsBanned(id)) return 1; 12480 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11522 EstateBan ban = new EstateBan(); 12481 EstateBan ban = new EstateBan();
11523 ban.EstateID = estate.EstateID; 12482 ban.EstateID = estate.EstateID;
11524 ban.BannedUserID = id; 12483 ban.BannedUserID = id;
11525 estate.AddBan(ban); 12484 estate.AddBan(ban);
11526 break; 12485 break;
11527 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12486 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11528 if (!isAccount || !estate.IsBanned(id)) return 0; 12487 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11529 estate.RemoveBan(id); 12488 estate.RemoveBan(id);
11530 break; 12489 break;
11531 default: return 0; 12490 default: return 0;
@@ -11554,7 +12513,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11554 return 16384; 12513 return 16384;
11555 } 12514 }
11556 12515
11557 public LSL_Integer llGetUsedMemory() 12516 public virtual LSL_Integer llGetUsedMemory()
11558 { 12517 {
11559 m_host.AddScriptLPS(1); 12518 m_host.AddScriptLPS(1);
11560 // The value returned for LSO scripts in SL 12519 // The value returned for LSO scripts in SL
@@ -11582,19 +12541,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11582 public void llSetSoundQueueing(int queue) 12541 public void llSetSoundQueueing(int queue)
11583 { 12542 {
11584 m_host.AddScriptLPS(1); 12543 m_host.AddScriptLPS(1);
11585 NotImplemented("llSetSoundQueueing");
11586 } 12544 }
11587 12545
11588 public void llCollisionSprite(string impact_sprite) 12546 public void llCollisionSprite(string impact_sprite)
11589 { 12547 {
11590 m_host.AddScriptLPS(1); 12548 m_host.AddScriptLPS(1);
11591 NotImplemented("llCollisionSprite"); 12549 // Viewer 2.0 broke this and it's likely LL has no intention
12550 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11592 } 12551 }
11593 12552
11594 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12553 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11595 { 12554 {
11596 m_host.AddScriptLPS(1); 12555 m_host.AddScriptLPS(1);
11597 NotImplemented("llGodLikeRezObject"); 12556
12557 if (!World.Permissions.IsGod(m_host.OwnerID))
12558 NotImplemented("llGodLikeRezObject");
12559
12560 AssetBase rezAsset = World.AssetService.Get(inventory);
12561 if (rezAsset == null)
12562 {
12563 llSay(0, "Asset not found");
12564 return;
12565 }
12566
12567 SceneObjectGroup group = null;
12568
12569 try
12570 {
12571 string xmlData = Utils.BytesToString(rezAsset.Data);
12572 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12573 }
12574 catch
12575 {
12576 llSay(0, "Asset not found");
12577 return;
12578 }
12579
12580 if (group == null)
12581 {
12582 llSay(0, "Asset not found");
12583 return;
12584 }
12585
12586 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12587 group.RootPart.AttachOffset = group.AbsolutePosition;
12588
12589 group.ResetIDs();
12590
12591 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12592 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12593 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12594 group.ScheduleGroupForFullUpdate();
12595
12596 // objects rezzed with this method are die_at_edge by default.
12597 group.RootPart.SetDieAtEdge(true);
12598
12599 group.ResumeScripts();
12600
12601 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12602 "object_rez", new Object[] {
12603 new LSL_String(
12604 group.RootPart.UUID.ToString()) },
12605 new DetectParams[0]));
11598 } 12606 }
11599 12607
11600 public LSL_String llTransferLindenDollars(string destination, int amount) 12608 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11646,7 +12654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11646 } 12654 }
11647 12655
11648 bool result = money.ObjectGiveMoney( 12656 bool result = money.ObjectGiveMoney(
11649 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12657 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11650 12658
11651 if (result) 12659 if (result)
11652 { 12660 {
@@ -11671,6 +12679,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11671 } 12679 }
11672 12680
11673 #endregion 12681 #endregion
12682
12683 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12684 {
12685 SceneObjectGroup group = m_host.ParentGroup;
12686
12687 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12688 return;
12689 if (group.IsAttachment)
12690 return;
12691
12692 if (frames.Data.Length > 0) // We are getting a new motion
12693 {
12694 if (group.RootPart.KeyframeMotion != null)
12695 group.RootPart.KeyframeMotion.Delete();
12696 group.RootPart.KeyframeMotion = null;
12697
12698 int idx = 0;
12699
12700 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12701 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12702
12703 while (idx < options.Data.Length)
12704 {
12705 int option = (int)options.GetLSLIntegerItem(idx++);
12706 int remain = options.Data.Length - idx;
12707
12708 switch (option)
12709 {
12710 case ScriptBaseClass.KFM_MODE:
12711 if (remain < 1)
12712 break;
12713 int modeval = (int)options.GetLSLIntegerItem(idx++);
12714 switch(modeval)
12715 {
12716 case ScriptBaseClass.KFM_FORWARD:
12717 mode = KeyframeMotion.PlayMode.Forward;
12718 break;
12719 case ScriptBaseClass.KFM_REVERSE:
12720 mode = KeyframeMotion.PlayMode.Reverse;
12721 break;
12722 case ScriptBaseClass.KFM_LOOP:
12723 mode = KeyframeMotion.PlayMode.Loop;
12724 break;
12725 case ScriptBaseClass.KFM_PING_PONG:
12726 mode = KeyframeMotion.PlayMode.PingPong;
12727 break;
12728 }
12729 break;
12730 case ScriptBaseClass.KFM_DATA:
12731 if (remain < 1)
12732 break;
12733 int dataval = (int)options.GetLSLIntegerItem(idx++);
12734 data = (KeyframeMotion.DataFormat)dataval;
12735 break;
12736 }
12737 }
12738
12739 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12740
12741 idx = 0;
12742
12743 int elemLength = 2;
12744 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12745 elemLength = 3;
12746
12747 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12748 while (idx < frames.Data.Length)
12749 {
12750 int remain = frames.Data.Length - idx;
12751
12752 if (remain < elemLength)
12753 break;
12754
12755 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12756 frame.Position = null;
12757 frame.Rotation = null;
12758
12759 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12760 {
12761 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12762 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12763 }
12764 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12765 {
12766 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12767 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12768 q.Normalize();
12769 frame.Rotation = q;
12770 }
12771
12772 float tempf = (float)frames.GetLSLFloatItem(idx++);
12773 frame.TimeMS = (int)(tempf * 1000.0f);
12774
12775 keyframes.Add(frame);
12776 }
12777
12778 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12779 group.RootPart.KeyframeMotion.Start();
12780 }
12781 else
12782 {
12783 if (group.RootPart.KeyframeMotion == null)
12784 return;
12785
12786 if (options.Data.Length == 0)
12787 {
12788 group.RootPart.KeyframeMotion.Stop();
12789 return;
12790 }
12791
12792 int code = (int)options.GetLSLIntegerItem(0);
12793
12794 int idx = 0;
12795
12796 while (idx < options.Data.Length)
12797 {
12798 int option = (int)options.GetLSLIntegerItem(idx++);
12799 int remain = options.Data.Length - idx;
12800
12801 switch (option)
12802 {
12803 case ScriptBaseClass.KFM_COMMAND:
12804 int cmd = (int)options.GetLSLIntegerItem(idx++);
12805 switch (cmd)
12806 {
12807 case ScriptBaseClass.KFM_CMD_PLAY:
12808 group.RootPart.KeyframeMotion.Start();
12809 break;
12810 case ScriptBaseClass.KFM_CMD_STOP:
12811 group.RootPart.KeyframeMotion.Stop();
12812 break;
12813 case ScriptBaseClass.KFM_CMD_PAUSE:
12814 group.RootPart.KeyframeMotion.Pause();
12815 break;
12816 }
12817 break;
12818 }
12819 }
12820 }
12821 }
12822
12823 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12824 {
12825 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12826
12827 int idx = 0;
12828 int idxStart = 0;
12829
12830 bool positionChanged = false;
12831 Vector3 finalPos = Vector3.Zero;
12832
12833 try
12834 {
12835 while (idx < rules.Length)
12836 {
12837 ++rulesParsed;
12838 int code = rules.GetLSLIntegerItem(idx++);
12839
12840 int remain = rules.Length - idx;
12841 idxStart = idx;
12842
12843 switch (code)
12844 {
12845 case (int)ScriptBaseClass.PRIM_POSITION:
12846 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12847 {
12848 if (remain < 1)
12849 return null;
12850
12851 LSL_Vector v;
12852 v = rules.GetVector3Item(idx++);
12853
12854 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12855 if (part == null)
12856 break;
12857
12858 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12859 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12860 if (part.LinkNum > 1)
12861 {
12862 localRot = GetPartLocalRot(part);
12863 localPos = GetPartLocalPos(part);
12864 }
12865
12866 v -= localPos;
12867 v /= localRot;
12868
12869 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12870
12871 v = v + 2 * sitOffset;
12872
12873 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12874 av.SendAvatarDataToAllAgents();
12875
12876 }
12877 break;
12878
12879 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12880 case (int)ScriptBaseClass.PRIM_ROTATION:
12881 {
12882 if (remain < 1)
12883 return null;
12884
12885 LSL_Rotation r;
12886 r = rules.GetQuaternionItem(idx++);
12887
12888 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12889 if (part == null)
12890 break;
12891
12892 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12893 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12894
12895 if (part.LinkNum > 1)
12896 localRot = GetPartLocalRot(part);
12897
12898 r = r * llGetRootRotation() / localRot;
12899 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12900 av.SendAvatarDataToAllAgents();
12901 }
12902 break;
12903
12904 // parse rest doing nothing but number of parameters error check
12905 case (int)ScriptBaseClass.PRIM_SIZE:
12906 case (int)ScriptBaseClass.PRIM_MATERIAL:
12907 case (int)ScriptBaseClass.PRIM_PHANTOM:
12908 case (int)ScriptBaseClass.PRIM_PHYSICS:
12909 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12910 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12911 case (int)ScriptBaseClass.PRIM_NAME:
12912 case (int)ScriptBaseClass.PRIM_DESC:
12913 if (remain < 1)
12914 return null;
12915 idx++;
12916 break;
12917
12918 case (int)ScriptBaseClass.PRIM_GLOW:
12919 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12920 case (int)ScriptBaseClass.PRIM_TEXGEN:
12921 if (remain < 2)
12922 return null;
12923 idx += 2;
12924 break;
12925
12926 case (int)ScriptBaseClass.PRIM_TYPE:
12927 if (remain < 3)
12928 return null;
12929 code = (int)rules.GetLSLIntegerItem(idx++);
12930 remain = rules.Length - idx;
12931 switch (code)
12932 {
12933 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12934 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12935 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12936 if (remain < 6)
12937 return null;
12938 idx += 6;
12939 break;
12940
12941 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12942 if (remain < 5)
12943 return null;
12944 idx += 5;
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12948 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12949 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12950 if (remain < 11)
12951 return null;
12952 idx += 11;
12953 break;
12954
12955 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12956 if (remain < 2)
12957 return null;
12958 idx += 2;
12959 break;
12960 }
12961 break;
12962
12963 case (int)ScriptBaseClass.PRIM_COLOR:
12964 case (int)ScriptBaseClass.PRIM_TEXT:
12965 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12966 case (int)ScriptBaseClass.PRIM_OMEGA:
12967 if (remain < 3)
12968 return null;
12969 idx += 3;
12970 break;
12971
12972 case (int)ScriptBaseClass.PRIM_TEXTURE:
12973 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12974 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12975 if (remain < 5)
12976 return null;
12977 idx += 5;
12978 break;
12979
12980 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12981 if (remain < 7)
12982 return null;
12983
12984 idx += 7;
12985 break;
12986
12987 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12988 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12989 return null;
12990
12991 return rules.GetSublist(idx, -1);
12992 }
12993 }
12994 }
12995 catch (InvalidCastException e)
12996 {
12997 ShoutError(string.Format(
12998 "{0} error running rule #{1}: arg #{2} ",
12999 originFunc, rulesParsed, idx - idxStart) + e.Message);
13000 }
13001 finally
13002 {
13003 if (positionChanged)
13004 {
13005 av.OffsetPosition = finalPos;
13006// av.SendAvatarDataToAllAgents();
13007 av.SendTerseUpdateToAllClients();
13008 positionChanged = false;
13009 }
13010 }
13011 return null;
13012 }
13013
13014 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13015 {
13016 // avatars case
13017 // replies as SL wiki
13018
13019// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13020 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13021
13022 int idx = 0;
13023 while (idx < rules.Length)
13024 {
13025 int code = (int)rules.GetLSLIntegerItem(idx++);
13026 int remain = rules.Length - idx;
13027
13028 switch (code)
13029 {
13030 case (int)ScriptBaseClass.PRIM_MATERIAL:
13031 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13032 break;
13033
13034 case (int)ScriptBaseClass.PRIM_PHYSICS:
13035 res.Add(new LSL_Integer(0));
13036 break;
13037
13038 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13039 res.Add(new LSL_Integer(0));
13040 break;
13041
13042 case (int)ScriptBaseClass.PRIM_PHANTOM:
13043 res.Add(new LSL_Integer(0));
13044 break;
13045
13046 case (int)ScriptBaseClass.PRIM_POSITION:
13047
13048 Vector3 pos = avatar.OffsetPosition;
13049
13050 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13051 pos -= sitOffset;
13052
13053 if( sitPart != null)
13054 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13055
13056 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13057 break;
13058
13059 case (int)ScriptBaseClass.PRIM_SIZE:
13060 // as in llGetAgentSize above
13061// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13062 Vector3 s = avatar.Appearance.AvatarSize;
13063 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13064
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_ROTATION:
13068 Quaternion rot = avatar.Rotation;
13069 if (sitPart != null)
13070 {
13071 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13072 }
13073
13074 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13075 break;
13076
13077 case (int)ScriptBaseClass.PRIM_TYPE:
13078 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13079 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13080 res.Add(new LSL_Vector(0f,1.0f,0f));
13081 res.Add(new LSL_Float(0.0f));
13082 res.Add(new LSL_Vector(0, 0, 0));
13083 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13084 res.Add(new LSL_Vector(0, 0, 0));
13085 break;
13086
13087 case (int)ScriptBaseClass.PRIM_TEXTURE:
13088 if (remain < 1)
13089 return null;
13090
13091 int face = (int)rules.GetLSLIntegerItem(idx++);
13092 if (face == ScriptBaseClass.ALL_SIDES)
13093 {
13094 for (face = 0; face < 21; face++)
13095 {
13096 res.Add(new LSL_String(""));
13097 res.Add(new LSL_Vector(0,0,0));
13098 res.Add(new LSL_Vector(0,0,0));
13099 res.Add(new LSL_Float(0.0));
13100 }
13101 }
13102 else
13103 {
13104 if (face >= 0 && face < 21)
13105 {
13106 res.Add(new LSL_String(""));
13107 res.Add(new LSL_Vector(0,0,0));
13108 res.Add(new LSL_Vector(0,0,0));
13109 res.Add(new LSL_Float(0.0));
13110 }
13111 }
13112 break;
13113
13114 case (int)ScriptBaseClass.PRIM_COLOR:
13115 if (remain < 1)
13116 return null;
13117
13118 face = (int)rules.GetLSLIntegerItem(idx++);
13119
13120 if (face == ScriptBaseClass.ALL_SIDES)
13121 {
13122 for (face = 0; face < 21; face++)
13123 {
13124 res.Add(new LSL_Vector(0,0,0));
13125 res.Add(new LSL_Float(0));
13126 }
13127 }
13128 else
13129 {
13130 res.Add(new LSL_Vector(0,0,0));
13131 res.Add(new LSL_Float(0));
13132 }
13133 break;
13134
13135 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13136 if (remain < 1)
13137 return null;
13138 face = (int)rules.GetLSLIntegerItem(idx++);
13139
13140 if (face == ScriptBaseClass.ALL_SIDES)
13141 {
13142 for (face = 0; face < 21; face++)
13143 {
13144 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13145 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13146 }
13147 }
13148 else
13149 {
13150 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13151 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13152 }
13153 break;
13154
13155 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13156 if (remain < 1)
13157 return null;
13158 face = (int)rules.GetLSLIntegerItem(idx++);
13159
13160 if (face == ScriptBaseClass.ALL_SIDES)
13161 {
13162 for (face = 0; face < 21; face++)
13163 {
13164 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13165 }
13166 }
13167 else
13168 {
13169 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13170 }
13171 break;
13172
13173 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13174 res.Add(new LSL_Integer(0));
13175 res.Add(new LSL_Integer(0));// softness
13176 res.Add(new LSL_Float(0.0f)); // gravity
13177 res.Add(new LSL_Float(0.0f)); // friction
13178 res.Add(new LSL_Float(0.0f)); // wind
13179 res.Add(new LSL_Float(0.0f)); // tension
13180 res.Add(new LSL_Vector(0f,0f,0f));
13181 break;
13182
13183 case (int)ScriptBaseClass.PRIM_TEXGEN:
13184 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13185 if (remain < 1)
13186 return null;
13187 face = (int)rules.GetLSLIntegerItem(idx++);
13188
13189 if (face == ScriptBaseClass.ALL_SIDES)
13190 {
13191 for (face = 0; face < 21; face++)
13192 {
13193 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13194 }
13195 }
13196 else
13197 {
13198 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13199 }
13200 break;
13201
13202 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13203 res.Add(new LSL_Integer(0));
13204 res.Add(new LSL_Vector(0f,0f,0f));
13205 res.Add(new LSL_Float(0f)); // intensity
13206 res.Add(new LSL_Float(0f)); // radius
13207 res.Add(new LSL_Float(0f)); // falloff
13208 break;
13209
13210 case (int)ScriptBaseClass.PRIM_GLOW:
13211 if (remain < 1)
13212 return null;
13213 face = (int)rules.GetLSLIntegerItem(idx++);
13214
13215 if (face == ScriptBaseClass.ALL_SIDES)
13216 {
13217 for (face = 0; face < 21; face++)
13218 {
13219 res.Add(new LSL_Float(0f));
13220 }
13221 }
13222 else
13223 {
13224 res.Add(new LSL_Float(0f));
13225 }
13226 break;
13227
13228 case (int)ScriptBaseClass.PRIM_TEXT:
13229 res.Add(new LSL_String(""));
13230 res.Add(new LSL_Vector(0f,0f,0f));
13231 res.Add(new LSL_Float(1.0f));
13232 break;
13233
13234 case (int)ScriptBaseClass.PRIM_NAME:
13235 res.Add(new LSL_String(avatar.Name));
13236 break;
13237
13238 case (int)ScriptBaseClass.PRIM_DESC:
13239 res.Add(new LSL_String(""));
13240 break;
13241
13242 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13243 Quaternion lrot = avatar.Rotation;
13244
13245 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13246 {
13247 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13248 }
13249 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13250 break;
13251
13252 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13253 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13254 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13255 lpos -= lsitOffset;
13256
13257 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13258 {
13259 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13260 }
13261 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13262 break;
13263
13264 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13265 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13266 return null;
13267
13268 return rules.GetSublist(idx, -1);
13269 }
13270 }
13271
13272 return null;
13273 }
11674 } 13274 }
11675 13275
11676 public class NotecardCache 13276 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 d356f8c..4c018d4 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.
@@ -2350,7 +2385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2350 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2385 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2351 m_host.AddScriptLPS(1); 2386 m_host.AddScriptLPS(1);
2352 2387
2353 return NpcCreate(firstname, lastname, position, notecard, false, false); 2388 return NpcCreate(firstname, lastname, position, notecard, true, false);
2354 } 2389 }
2355 2390
2356 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2391 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2361,24 +2396,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2361 return NpcCreate( 2396 return NpcCreate(
2362 firstname, lastname, position, notecard, 2397 firstname, lastname, position, notecard,
2363 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2398 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2364 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2399 false);
2400// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2365 } 2401 }
2366 2402
2367 private LSL_Key NpcCreate( 2403 private LSL_Key NpcCreate(
2368 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2404 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2369 { 2405 {
2406 if (!owned)
2407 OSSLError("Unowned NPCs are unsupported");
2408
2409 string groupTitle = String.Empty;
2410
2411 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2412 return new LSL_Key(UUID.Zero.ToString());
2413
2414 if (firstname != String.Empty || lastname != String.Empty)
2415 {
2416 if (firstname != "Shown outfit:")
2417 groupTitle = "- NPC -";
2418 }
2419
2370 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2420 INPCModule module = World.RequestModuleInterface<INPCModule>();
2371 if (module != null) 2421 if (module != null)
2372 { 2422 {
2373 AvatarAppearance appearance = null; 2423 AvatarAppearance appearance = null;
2374 2424
2375 UUID id; 2425// UUID id;
2376 if (UUID.TryParse(notecard, out id)) 2426// if (UUID.TryParse(notecard, out id))
2377 { 2427// {
2378 ScenePresence clonePresence = World.GetScenePresence(id); 2428// ScenePresence clonePresence = World.GetScenePresence(id);
2379 if (clonePresence != null) 2429// if (clonePresence != null)
2380 appearance = clonePresence.Appearance; 2430// appearance = clonePresence.Appearance;
2381 } 2431// }
2382 2432
2383 if (appearance == null) 2433 if (appearance == null)
2384 { 2434 {
@@ -2386,9 +2436,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2386 2436
2387 if (appearanceSerialized != null) 2437 if (appearanceSerialized != null)
2388 { 2438 {
2389 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2439 try
2390 appearance = new AvatarAppearance(); 2440 {
2391 appearance.Unpack(appearanceOsd); 2441 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2442 appearance = new AvatarAppearance();
2443 appearance.Unpack(appearanceOsd);
2444 }
2445 catch
2446 {
2447 return UUID.Zero.ToString();
2448 }
2392 } 2449 }
2393 else 2450 else
2394 { 2451 {
@@ -2407,6 +2464,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2407 World, 2464 World,
2408 appearance); 2465 appearance);
2409 2466
2467 ScenePresence sp;
2468 if (World.TryGetScenePresence(x, out sp))
2469 {
2470 sp.Grouptitle = groupTitle;
2471 sp.SendAvatarDataToAllAgents();
2472 }
2410 return new LSL_Key(x.ToString()); 2473 return new LSL_Key(x.ToString());
2411 } 2474 }
2412 2475
@@ -2710,16 +2773,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2710 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2773 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2711 m_host.AddScriptLPS(1); 2774 m_host.AddScriptLPS(1);
2712 2775
2713 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2776 ManualResetEvent ev = new ManualResetEvent(false);
2714 if (module != null)
2715 {
2716 UUID npcId = new UUID(npc.m_string);
2717 2777
2718 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2778 Util.FireAndForget(delegate(object x) {
2719 return; 2779 try
2780 {
2781 INPCModule module = World.RequestModuleInterface<INPCModule>();
2782 if (module != null)
2783 {
2784 UUID npcId = new UUID(npc.m_string);
2720 2785
2721 module.DeleteNPC(npcId, World); 2786 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2722 } 2787 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2788 {
2789 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2790 return;
2791 }
2792
2793 module.DeleteNPC(npcId, World);
2794 }
2795 }
2796 finally
2797 {
2798 ev.Set();
2799 }
2800 });
2801 ev.WaitOne();
2723 } 2802 }
2724 2803
2725 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2804 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 {