aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3146
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/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.cs29
-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, 3250 insertions, 1097 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 81de9ab..38a9cb0 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.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -112,17 +116,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
112 protected int m_notecardLineReadCharsMax = 255; 116 protected int m_notecardLineReadCharsMax = 255;
113 protected int m_scriptConsoleChannel = 0; 117 protected int m_scriptConsoleChannel = 0;
114 protected bool m_scriptConsoleChannelEnabled = false; 118 protected bool m_scriptConsoleChannelEnabled = false;
119 protected bool m_debuggerSafe = false;
115 protected IUrlModule m_UrlModule = null; 120 protected IUrlModule m_UrlModule = null;
116 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 121 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
117 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 122 new Dictionary<UUID, UserInfoCacheEntry>();
123 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
118 protected ISoundModule m_SoundModule = null; 124 protected ISoundModule m_SoundModule = null;
119 125
126// protected Timer m_ShoutSayTimer;
127 protected int m_SayShoutCount = 0;
128 DateTime m_lastSayShoutCheck;
129
130 private Dictionary<string, string> MovementAnimationsForLSL =
131 new Dictionary<string, string> {
132 {"FLY", "Flying"},
133 {"FLYSLOW", "FlyingSlow"},
134 {"HOVER_UP", "Hovering Up"},
135 {"HOVER_DOWN", "Hovering Down"},
136 {"HOVER", "Hovering"},
137 {"LAND", "Landing"},
138 {"FALLDOWN", "Falling Down"},
139 {"PREJUMP", "PreJumping"},
140 {"JUMP", "Jumping"},
141 {"STANDUP", "Standing Up"},
142 {"SOFT_LAND", "Soft Landing"},
143 {"STAND", "Standing"},
144 {"CROUCHWALK", "CrouchWalking"},
145 {"RUN", "Running"},
146 {"WALK", "Walking"},
147 {"CROUCH", "Crouching"},
148 {"TURNLEFT", "Turning Left"},
149 {"TURNRIGHT", "Turning Right"}
150 };
151
120 public void Initialize( 152 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
122 { 154 {
155 m_lastSayShoutCheck = DateTime.UtcNow;
156
123 m_ScriptEngine = scriptEngine; 157 m_ScriptEngine = scriptEngine;
124 m_host = host; 158 m_host = host;
125 m_item = item; 159 m_item = item;
160 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
126 m_coopSleepHandle = coopSleepHandle; 161 m_coopSleepHandle = coopSleepHandle;
127 162
128 LoadConfig(); 163 LoadConfig();
@@ -211,6 +246,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 get { return m_ScriptEngine.World; } 246 get { return m_ScriptEngine.World; }
212 } 247 }
213 248
249 [DebuggerNonUserCode]
214 public void state(string newState) 250 public void state(string newState)
215 { 251 {
216 m_ScriptEngine.SetState(m_item.ItemID, newState); 252 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -220,6 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
220 /// Reset the named script. The script must be present 256 /// Reset the named script. The script must be present
221 /// in the same prim. 257 /// in the same prim.
222 /// </summary> 258 /// </summary>
259 [DebuggerNonUserCode]
223 public void llResetScript() 260 public void llResetScript()
224 { 261 {
225 m_host.AddScriptLPS(1); 262 m_host.AddScriptLPS(1);
@@ -282,6 +319,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 } 319 }
283 } 320 }
284 321
322 public List<ScenePresence> GetLinkAvatars(int linkType)
323 {
324 List<ScenePresence> ret = new List<ScenePresence>();
325 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
326 return ret;
327
328 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
329
330 switch (linkType)
331 {
332 case ScriptBaseClass.LINK_SET:
333 return avs;
334
335 case ScriptBaseClass.LINK_ROOT:
336 return ret;
337
338 case ScriptBaseClass.LINK_ALL_OTHERS:
339 return avs;
340
341 case ScriptBaseClass.LINK_ALL_CHILDREN:
342 return avs;
343
344 case ScriptBaseClass.LINK_THIS:
345 return ret;
346
347 default:
348 if (linkType < 0)
349 return ret;
350
351 int partCount = m_host.ParentGroup.GetPartCount();
352
353 if (linkType <= partCount)
354 {
355 return ret;
356 }
357 else
358 {
359 linkType = linkType - partCount;
360 if (linkType > avs.Count)
361 {
362 return ret;
363 }
364 else
365 {
366 ret.Add(avs[linkType-1]);
367 return ret;
368 }
369 }
370 }
371 }
372
285 public List<SceneObjectPart> GetLinkParts(int linkType) 373 public List<SceneObjectPart> GetLinkParts(int linkType)
286 { 374 {
287 return GetLinkParts(m_host, linkType); 375 return GetLinkParts(m_host, linkType);
@@ -290,6 +378,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
290 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 378 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
291 { 379 {
292 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 380 List<SceneObjectPart> ret = new List<SceneObjectPart>();
381 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
382 return ret;
293 ret.Add(part); 383 ret.Add(part);
294 384
295 switch (linkType) 385 switch (linkType)
@@ -516,31 +606,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
516 606
517 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 607 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
518 608
519 /// <summary> 609 // Utility function for llRot2Euler
520 /// Convert an LSL rotation to a Euler vector. 610
521 /// </summary> 611 // normalize an angle between -PI and PI (-180 to +180 degrees)
522 /// <remarks> 612 protected double NormalizeAngle(double angle)
523 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
524 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
525 /// </remarks>
526 /// <param name="r"></param>
527 /// <returns></returns>
528 public LSL_Vector llRot2Euler(LSL_Rotation r)
529 { 613 {
530 m_host.AddScriptLPS(1); 614 if (angle > -Math.PI && angle < Math.PI)
615 return angle;
531 616
532 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 617 int numPis = (int)(Math.PI / angle);
533 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 618 double remainder = angle - Math.PI * numPis;
534 if (m == 0.0) return new LSL_Vector(); 619 if (numPis % 2 == 1)
535 double x = Math.Atan2(-v.y, v.z); 620 return Math.PI - angle;
536 double sin = v.x / m; 621 return remainder;
537 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 622 }
538 double y = Math.Asin(sin);
539 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
540 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)));
541 double z = Math.Atan2(v.y, v.x);
542 623
543 return new LSL_Vector(x, y, z); 624 public LSL_Vector llRot2Euler(LSL_Rotation q1)
625 {
626 m_host.AddScriptLPS(1);
627 LSL_Vector eul = new LSL_Vector();
628
629 double sqw = q1.s*q1.s;
630 double sqx = q1.x*q1.x;
631 double sqy = q1.z*q1.z;
632 double sqz = q1.y*q1.y;
633 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
634 double test = q1.x*q1.z + q1.y*q1.s;
635 if (test > 0.4999*unit) { // singularity at north pole
636 eul.z = 2 * Math.Atan2(q1.x,q1.s);
637 eul.y = Math.PI/2;
638 eul.x = 0;
639 return eul;
640 }
641 if (test < -0.4999*unit) { // singularity at south pole
642 eul.z = -2 * Math.Atan2(q1.x,q1.s);
643 eul.y = -Math.PI/2;
644 eul.x = 0;
645 return eul;
646 }
647 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
648 eul.y = Math.Asin(2*test/unit);
649 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
650 return eul;
544 } 651 }
545 652
546 /* From wiki: 653 /* From wiki:
@@ -593,18 +700,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
593 m_host.AddScriptLPS(1); 700 m_host.AddScriptLPS(1);
594 701
595 double x,y,z,s; 702 double x,y,z,s;
596 703 v.x *= 0.5;
597 double c1 = Math.Cos(v.x * 0.5); 704 v.y *= 0.5;
598 double c2 = Math.Cos(v.y * 0.5); 705 v.z *= 0.5;
599 double c3 = Math.Cos(v.z * 0.5); 706 double c1 = Math.Cos(v.x);
600 double s1 = Math.Sin(v.x * 0.5); 707 double c2 = Math.Cos(v.y);
601 double s2 = Math.Sin(v.y * 0.5); 708 double c1c2 = c1 * c2;
602 double s3 = Math.Sin(v.z * 0.5); 709 double s1 = Math.Sin(v.x);
603 710 double s2 = Math.Sin(v.y);
604 x = s1 * c2 * c3 + c1 * s2 * s3; 711 double s1s2 = s1 * s2;
605 y = c1 * s2 * c3 - s1 * c2 * s3; 712 double c1s2 = c1 * s2;
606 z = s1 * s2 * c3 + c1 * c2 * s3; 713 double s1c2 = s1 * c2;
607 s = c1 * c2 * c3 - s1 * s2 * s3; 714 double c3 = Math.Cos(v.z);
715 double s3 = Math.Sin(v.z);
716
717 x = s1c2 * c3 + c1s2 * s3;
718 y = c1s2 * c3 - s1c2 * s3;
719 z = s1s2 * c3 + c1c2 * s3;
720 s = c1c2 * c3 - s1s2 * s3;
608 721
609 return new LSL_Rotation(x, y, z, s); 722 return new LSL_Rotation(x, y, z, s);
610 } 723 }
@@ -742,77 +855,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
742 { 855 {
743 //A and B should both be normalized 856 //A and B should both be normalized
744 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
745 LSL_Rotation rotBetween; 858 /* This method is more accurate than the SL one, and thus causes problems
746 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 859 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
747 // continue calculation. 860
748 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 861 double dotProduct = LSL_Vector.Dot(a, b);
862 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
863 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
864 double angle = Math.Acos(dotProduct / magProduct);
865 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
866 double s = Math.Sin(angle / 2);
867
868 double x = axis.x * s;
869 double y = axis.y * s;
870 double z = axis.z * s;
871 double w = Math.Cos(angle / 2);
872
873 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
874 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
875
876 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
877 */
878
879 // This method mimics the 180 errors found in SL
880 // See www.euclideanspace.com... angleBetween
881 LSL_Vector vec_a = a;
882 LSL_Vector vec_b = b;
883
884 // Eliminate zero length
885 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
886 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
887 if (vec_a_mag < 0.00001 ||
888 vec_b_mag < 0.00001)
749 { 889 {
750 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 890 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
751 } 891 }
752 else 892
893 // Normalize
894 vec_a = llVecNorm(vec_a);
895 vec_b = llVecNorm(vec_b);
896
897 // Calculate axis and rotation angle
898 LSL_Vector axis = vec_a % vec_b;
899 LSL_Float cos_theta = vec_a * vec_b;
900
901 // Check if parallel
902 if (cos_theta > 0.99999)
753 { 903 {
754 a = LSL_Vector.Norm(a); 904 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
755 b = LSL_Vector.Norm(b); 905 }
756 double dotProduct = LSL_Vector.Dot(a, b); 906
757 // There are two degenerate cases possible. These are for vectors 180 or 907 // Check if anti-parallel
758 // 0 degrees apart. These have to be detected and handled individually. 908 else if (cos_theta < -0.99999)
759 // 909 {
760 // Check for vectors 180 degrees apart. 910 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
761 // A dot product of -1 would mean the angle between vectors is 180 degrees. 911 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
762 if (dotProduct < -0.9999999f) 912 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
763 { 913 }
764 // First assume X axis is orthogonal to the vectors. 914 else // other rotation
765 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 915 {
766 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 916 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
767 // Check for near zero vector. A very small non-zero number here will create 917 axis = llVecNorm(axis);
768 // a rotation in an undesired direction. 918 double x, y, z, s, t;
769 if (LSL_Vector.Mag(orthoVector) > 0.0001) 919 s = Math.Cos(theta);
770 { 920 t = Math.Sin(theta);
771 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 921 x = axis.x * t;
772 } 922 y = axis.y * t;
773 // If the magnitude of the vector was near zero, then assume the X axis is not 923 z = axis.z * t;
774 // orthogonal and use the Z axis instead. 924 return new LSL_Rotation(x,y,z,s);
775 else
776 {
777 // Set 180 z rotation.
778 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
779 }
780 }
781 // Check for parallel vectors.
782 // A dot product of 1 would mean the angle between vectors is 0 degrees.
783 else if (dotProduct > 0.9999999f)
784 {
785 // Set zero rotation.
786 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
787 }
788 else
789 {
790 // All special checks have been performed so get the axis of rotation.
791 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
792 // Quarternion s value is the length of the unit vector + dot product.
793 double qs = 1.0 + dotProduct;
794 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
795 // Normalize the rotation.
796 double mag = LSL_Rotation.Mag(rotBetween);
797 // We shouldn't have to worry about a divide by zero here. The qs value will be
798 // non-zero because we already know if we're here, then the dotProduct is not -1 so
799 // qs will not be zero. Also, we've already handled the input vectors being zero so the
800 // crossProduct vector should also not be zero.
801 rotBetween.x = rotBetween.x / mag;
802 rotBetween.y = rotBetween.y / mag;
803 rotBetween.z = rotBetween.z / mag;
804 rotBetween.s = rotBetween.s / mag;
805 // Check for undefined values and set zero rotation if any found. This code might not actually be required
806 // any longer since zero vectors are checked for at the top.
807 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
808 {
809 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
810 }
811 }
812 } 925 }
813 return rotBetween;
814 } 926 }
815 927
816 public void llWhisper(int channelID, string text) 928 public void llWhisper(int channelID, string text)
817 { 929 {
818 m_host.AddScriptLPS(1); 930 m_host.AddScriptLPS(1);
@@ -828,10 +940,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 940 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
829 } 941 }
830 942
943 private void CheckSayShoutTime()
944 {
945 DateTime now = DateTime.UtcNow;
946 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
947 {
948 m_lastSayShoutCheck = now;
949 m_SayShoutCount = 0;
950 }
951 else
952 m_SayShoutCount++;
953 }
954
831 public void llSay(int channelID, string text) 955 public void llSay(int channelID, string text)
832 { 956 {
833 m_host.AddScriptLPS(1); 957 m_host.AddScriptLPS(1);
834 958
959 if (channelID == 0)
960// m_SayShoutCount++;
961 CheckSayShoutTime();
962
963 if (m_SayShoutCount >= 11)
964 ScriptSleep(2000);
965
835 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 966 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
836 { 967 {
837 Console.WriteLine(text); 968 Console.WriteLine(text);
@@ -854,6 +985,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
854 { 985 {
855 m_host.AddScriptLPS(1); 986 m_host.AddScriptLPS(1);
856 987
988 if (channelID == 0)
989// m_SayShoutCount++;
990 CheckSayShoutTime();
991
992 if (m_SayShoutCount >= 11)
993 ScriptSleep(2000);
994
857 if (text.Length > 1023) 995 if (text.Length > 1023)
858 text = text.Substring(0, 1023); 996 text = text.Substring(0, 1023);
859 997
@@ -885,22 +1023,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
885 1023
886 public void llRegionSayTo(string target, int channel, string msg) 1024 public void llRegionSayTo(string target, int channel, string msg)
887 { 1025 {
1026 string error = String.Empty;
1027
888 if (msg.Length > 1023) 1028 if (msg.Length > 1023)
889 msg = msg.Substring(0, 1023); 1029 msg = msg.Substring(0, 1023);
890 1030
891 m_host.AddScriptLPS(1); 1031 m_host.AddScriptLPS(1);
892 1032
893 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
894 {
895 return;
896 }
897
898 UUID TargetID; 1033 UUID TargetID;
899 UUID.TryParse(target, out TargetID); 1034 UUID.TryParse(target, out TargetID);
900 1035
901 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1036 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
902 if (wComm != null) 1037 if (wComm != null)
903 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1038 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1039 LSLError(error);
904 } 1040 }
905 1041
906 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1042 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1156,10 +1292,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 return detectedParams.TouchUV; 1292 return detectedParams.TouchUV;
1157 } 1293 }
1158 1294
1295 [DebuggerNonUserCode]
1159 public virtual void llDie() 1296 public virtual void llDie()
1160 { 1297 {
1161 m_host.AddScriptLPS(1); 1298 m_host.AddScriptLPS(1);
1162 throw new SelfDeleteException(); 1299 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1163 } 1300 }
1164 1301
1165 public LSL_Float llGround(LSL_Vector offset) 1302 public LSL_Float llGround(LSL_Vector offset)
@@ -1230,6 +1367,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1230 1367
1231 public void llSetStatus(int status, int value) 1368 public void llSetStatus(int status, int value)
1232 { 1369 {
1370 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1371 return;
1233 m_host.AddScriptLPS(1); 1372 m_host.AddScriptLPS(1);
1234 1373
1235 int statusrotationaxis = 0; 1374 int statusrotationaxis = 0;
@@ -1253,6 +1392,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1253 if (!allow) 1392 if (!allow)
1254 return; 1393 return;
1255 1394
1395 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1396 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1397 return;
1398
1256 m_host.ScriptSetPhysicsStatus(true); 1399 m_host.ScriptSetPhysicsStatus(true);
1257 } 1400 }
1258 else 1401 else
@@ -1453,6 +1596,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1453 { 1596 {
1454 m_host.AddScriptLPS(1); 1597 m_host.AddScriptLPS(1);
1455 1598
1599 SetColor(m_host, color, face);
1600 }
1601
1602 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1607 Primitive.TextureEntry tex = part.Shape.Textures;
1608 Color4 texcolor;
1609 if (face >= 0 && face < GetNumberOfSides(part))
1610 {
1611 texcolor = tex.CreateFace((uint)face).RGBA;
1612 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1613 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1614 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1615 tex.FaceTextures[face].RGBA = texcolor;
1616 part.UpdateTextureEntry(tex.GetBytes());
1617 return;
1618 }
1619 else if (face == ScriptBaseClass.ALL_SIDES)
1620 {
1621 for (uint i = 0; i < GetNumberOfSides(part); i++)
1622 {
1623 if (tex.FaceTextures[i] != null)
1624 {
1625 texcolor = tex.FaceTextures[i].RGBA;
1626 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1627 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1628 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1629 tex.FaceTextures[i].RGBA = texcolor;
1630 }
1631 texcolor = tex.DefaultTexture.RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.DefaultTexture.RGBA = texcolor;
1636 }
1637 part.UpdateTextureEntry(tex.GetBytes());
1638 return;
1639 }
1640
1456 if (face == ScriptBaseClass.ALL_SIDES) 1641 if (face == ScriptBaseClass.ALL_SIDES)
1457 face = SceneObjectPart.ALL_SIDES; 1642 face = SceneObjectPart.ALL_SIDES;
1458 1643
@@ -1461,6 +1646,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1461 1646
1462 public void SetTexGen(SceneObjectPart part, int face,int style) 1647 public void SetTexGen(SceneObjectPart part, int face,int style)
1463 { 1648 {
1649 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1650 return;
1651
1464 Primitive.TextureEntry tex = part.Shape.Textures; 1652 Primitive.TextureEntry tex = part.Shape.Textures;
1465 MappingType textype; 1653 MappingType textype;
1466 textype = MappingType.Default; 1654 textype = MappingType.Default;
@@ -1491,6 +1679,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1491 1679
1492 public void SetGlow(SceneObjectPart part, int face, float glow) 1680 public void SetGlow(SceneObjectPart part, int face, float glow)
1493 { 1681 {
1682 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1683 return;
1684
1494 Primitive.TextureEntry tex = part.Shape.Textures; 1685 Primitive.TextureEntry tex = part.Shape.Textures;
1495 if (face >= 0 && face < GetNumberOfSides(part)) 1686 if (face >= 0 && face < GetNumberOfSides(part))
1496 { 1687 {
@@ -1516,6 +1707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1516 1707
1517 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1708 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1518 { 1709 {
1710 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1711 return;
1519 1712
1520 Shininess sval = new Shininess(); 1713 Shininess sval = new Shininess();
1521 1714
@@ -1566,6 +1759,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1566 1759
1567 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1760 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1568 { 1761 {
1762 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1763 return;
1764
1569 Primitive.TextureEntry tex = part.Shape.Textures; 1765 Primitive.TextureEntry tex = part.Shape.Textures;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1766 if (face >= 0 && face < GetNumberOfSides(part))
1571 { 1767 {
@@ -1626,13 +1822,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1626 m_host.AddScriptLPS(1); 1822 m_host.AddScriptLPS(1);
1627 1823
1628 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1824 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1629 1825 if (parts.Count > 0)
1630 foreach (SceneObjectPart part in parts) 1826 {
1631 SetAlpha(part, alpha, face); 1827 try
1828 {
1829 foreach (SceneObjectPart part in parts)
1830 SetAlpha(part, alpha, face);
1831 }
1832 finally
1833 {
1834 }
1835 }
1632 } 1836 }
1633 1837
1634 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1838 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1635 { 1839 {
1840 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1841 return;
1842
1636 Primitive.TextureEntry tex = part.Shape.Textures; 1843 Primitive.TextureEntry tex = part.Shape.Textures;
1637 Color4 texcolor; 1844 Color4 texcolor;
1638 if (face >= 0 && face < GetNumberOfSides(part)) 1845 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1685,7 +1892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1685 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1892 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1686 float wind, float tension, LSL_Vector Force) 1893 float wind, float tension, LSL_Vector Force)
1687 { 1894 {
1688 if (part == null) 1895 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1689 return; 1896 return;
1690 1897
1691 if (flexi) 1898 if (flexi)
@@ -1726,7 +1933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1726 /// <param name="falloff"></param> 1933 /// <param name="falloff"></param>
1727 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1934 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1728 { 1935 {
1729 if (part == null) 1936 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1730 return; 1937 return;
1731 1938
1732 if (light) 1939 if (light)
@@ -1759,11 +1966,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1759 Primitive.TextureEntry tex = part.Shape.Textures; 1966 Primitive.TextureEntry tex = part.Shape.Textures;
1760 Color4 texcolor; 1967 Color4 texcolor;
1761 LSL_Vector rgb = new LSL_Vector(); 1968 LSL_Vector rgb = new LSL_Vector();
1969 int nsides = GetNumberOfSides(part);
1970
1762 if (face == ScriptBaseClass.ALL_SIDES) 1971 if (face == ScriptBaseClass.ALL_SIDES)
1763 { 1972 {
1764 int i; 1973 int i;
1765 1974 for (i = 0; i < nsides; i++)
1766 for (i = 0 ; i < GetNumberOfSides(part); i++)
1767 { 1975 {
1768 texcolor = tex.GetFace((uint)i).RGBA; 1976 texcolor = tex.GetFace((uint)i).RGBA;
1769 rgb.x += texcolor.R; 1977 rgb.x += texcolor.R;
@@ -1771,14 +1979,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1771 rgb.z += texcolor.B; 1979 rgb.z += texcolor.B;
1772 } 1980 }
1773 1981
1774 rgb.x /= (float)GetNumberOfSides(part); 1982 float invnsides = 1.0f / (float)nsides;
1775 rgb.y /= (float)GetNumberOfSides(part); 1983
1776 rgb.z /= (float)GetNumberOfSides(part); 1984 rgb.x *= invnsides;
1985 rgb.y *= invnsides;
1986 rgb.z *= invnsides;
1777 1987
1778 return rgb; 1988 return rgb;
1779 } 1989 }
1780 1990 if (face >= 0 && face < nsides)
1781 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 1991 {
1783 texcolor = tex.GetFace((uint)face).RGBA; 1992 texcolor = tex.GetFace((uint)face).RGBA;
1784 rgb.x = texcolor.R; 1993 rgb.x = texcolor.R;
@@ -1805,15 +2014,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1805 m_host.AddScriptLPS(1); 2014 m_host.AddScriptLPS(1);
1806 2015
1807 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2016 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1808 2017 if (parts.Count > 0)
1809 foreach (SceneObjectPart part in parts) 2018 {
1810 SetTexture(part, texture, face); 2019 try
1811 2020 {
2021 foreach (SceneObjectPart part in parts)
2022 SetTexture(part, texture, face);
2023 }
2024 finally
2025 {
2026 }
2027 }
1812 ScriptSleep(200); 2028 ScriptSleep(200);
1813 } 2029 }
1814 2030
1815 protected void SetTexture(SceneObjectPart part, string texture, int face) 2031 protected void SetTexture(SceneObjectPart part, string texture, int face)
1816 { 2032 {
2033 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2034 return;
2035
1817 UUID textureID = new UUID(); 2036 UUID textureID = new UUID();
1818 2037
1819 textureID = InventoryKey(texture, (int)AssetType.Texture); 2038 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1858,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1858 2077
1859 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2078 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1860 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1861 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1862 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1863 { 2085 {
@@ -1894,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1894 2116
1895 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2117 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1896 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1897 Primitive.TextureEntry tex = part.Shape.Textures; 2122 Primitive.TextureEntry tex = part.Shape.Textures;
1898 if (face >= 0 && face < GetNumberOfSides(part)) 2123 if (face >= 0 && face < GetNumberOfSides(part))
1899 { 2124 {
@@ -1930,6 +2155,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1930 2155
1931 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2156 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1932 { 2157 {
2158 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2159 return;
2160
1933 Primitive.TextureEntry tex = part.Shape.Textures; 2161 Primitive.TextureEntry tex = part.Shape.Textures;
1934 if (face >= 0 && face < GetNumberOfSides(part)) 2162 if (face >= 0 && face < GetNumberOfSides(part))
1935 { 2163 {
@@ -2071,7 +2299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2071 return end; 2299 return end;
2072 } 2300 }
2073 2301
2074 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2302 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2075 { 2303 {
2076 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2304 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2077 return fromPos; 2305 return fromPos;
@@ -2087,9 +2315,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2087 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2315 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2088 targetPos.z = ground; 2316 targetPos.z = ground;
2089 } 2317 }
2090 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2318 if (adjust)
2319 return SetPosAdjust(fromPos, targetPos);
2091 2320
2092 return real_vec; 2321 return targetPos;
2093 } 2322 }
2094 2323
2095 /// <summary> 2324 /// <summary>
@@ -2100,27 +2329,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2100 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2329 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2101 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2330 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2102 { 2331 {
2103 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2332 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2333 return;
2334
2104 LSL_Vector currentPos = GetPartLocalPos(part); 2335 LSL_Vector currentPos = GetPartLocalPos(part);
2336 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2105 2337
2106 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2107 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2108 2338
2109 if (part.ParentGroup.RootPart == part) 2339 if (part.ParentGroup.RootPart == part)
2110 { 2340 {
2111 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2112 targetPos.z = ground;
2113 SceneObjectGroup parent = part.ParentGroup; 2341 SceneObjectGroup parent = part.ParentGroup;
2114 parent.UpdateGroupPosition(!adjust ? targetPos : 2342 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2115 SetPosAdjust(currentPos, targetPos)); 2343 return;
2344 Util.FireAndForget(delegate(object x) {
2345 parent.UpdateGroupPosition((Vector3)toPos);
2346 });
2116 } 2347 }
2117 else 2348 else
2118 { 2349 {
2119 part.OffsetPosition = !adjust ? targetPos : 2350 part.OffsetPosition = (Vector3)toPos;
2120 SetPosAdjust(currentPos, targetPos); 2351// SceneObjectGroup parent = part.ParentGroup;
2121 SceneObjectGroup parent = part.ParentGroup; 2352// parent.HasGroupChanged = true;
2122 parent.HasGroupChanged = true; 2353// parent.ScheduleGroupForTerseUpdate();
2123 parent.ScheduleGroupForTerseUpdate(); 2354 part.ScheduleTerseUpdate();
2124 } 2355 }
2125 } 2356 }
2126 2357
@@ -2149,13 +2380,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2149 else 2380 else
2150 { 2381 {
2151 if (part.ParentGroup.IsAttachment) 2382 if (part.ParentGroup.IsAttachment)
2152 {
2153 pos = part.AttachedPos; 2383 pos = part.AttachedPos;
2154 }
2155 else 2384 else
2156 {
2157 pos = part.AbsolutePosition; 2385 pos = part.AbsolutePosition;
2158 }
2159 } 2386 }
2160 2387
2161// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2388// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2167,8 +2394,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2167 { 2394 {
2168 m_host.AddScriptLPS(1); 2395 m_host.AddScriptLPS(1);
2169 2396
2397
2398 // 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
2399 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2400 // 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.
2401 // RootPart != null should shortcircuit
2402
2170 // try to let this work as in SL... 2403 // try to let this work as in SL...
2171 if (m_host.ParentID == 0) 2404 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2172 { 2405 {
2173 // special case: If we are root, rotate complete SOG to new rotation 2406 // special case: If we are root, rotate complete SOG to new rotation
2174 SetRot(m_host, rot); 2407 SetRot(m_host, rot);
@@ -2195,25 +2428,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2195 2428
2196 protected void SetRot(SceneObjectPart part, Quaternion rot) 2429 protected void SetRot(SceneObjectPart part, Quaternion rot)
2197 { 2430 {
2198 part.UpdateRotation(rot); 2431 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2199 // Update rotation does not move the object in the physics scene if it's a linkset. 2432 return;
2200 2433
2201//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2434 bool isroot = (part == part.ParentGroup.RootPart);
2202// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2435 bool isphys;
2203 2436
2204 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2205 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2206 // It's perfectly okay when the object is not an active physical body though.
2207 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2208 // but only if the object is not physial and active. This is important for rotating doors.
2209 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2210 // scene
2211 PhysicsActor pa = part.PhysActor; 2437 PhysicsActor pa = part.PhysActor;
2212 2438
2213 if (pa != null && !pa.IsPhysical) 2439 // keep using physactor ideia of isphysical
2440 // it should be SOP ideia of that
2441 // not much of a issue with ubitODE
2442 if (pa != null && pa.IsPhysical)
2443 isphys = true;
2444 else
2445 isphys = false;
2446
2447 // SL doesn't let scripts rotate root of physical linksets
2448 if (isroot && isphys)
2449 return;
2450
2451 part.UpdateRotation(rot);
2452
2453 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2454 // so do a nasty update of parts positions if is a root part rotation
2455 if (isroot && pa != null) // with if above implies non physical root part
2214 { 2456 {
2215 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2457 part.ParentGroup.ResetChildPrimPhysicsPositions();
2216 } 2458 }
2459 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2460 {
2461 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2462 if (sittingavas.Count > 0)
2463 {
2464 foreach (ScenePresence av in sittingavas)
2465 {
2466 if (isroot || part.LocalId == av.ParentID)
2467 av.SendTerseUpdateToAllClients();
2468 }
2469 }
2470 }
2217 } 2471 }
2218 2472
2219 /// <summary> 2473 /// <summary>
@@ -2230,6 +2484,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2230 2484
2231 m_host.AddScriptLPS(1); 2485 m_host.AddScriptLPS(1);
2232 Quaternion q = m_host.GetWorldRotation(); 2486 Quaternion q = m_host.GetWorldRotation();
2487
2488 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2489 {
2490 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2491 if (avatar != null)
2492 {
2493 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2494 q = avatar.CameraRotation * q; // Mouselook
2495 else
2496 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2497 }
2498 }
2499
2233 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2500 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2234 } 2501 }
2235 2502
@@ -2255,14 +2522,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2255 q = part.ParentGroup.GroupRotation; // just the group rotation 2522 q = part.ParentGroup.GroupRotation; // just the group rotation
2256 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2523 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2257 } 2524 }
2525
2258 q = part.GetWorldRotation(); 2526 q = part.GetWorldRotation();
2527 if (part.ParentGroup.AttachmentPoint != 0)
2528 {
2529 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2530 if (avatar != null)
2531 {
2532 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2533 q = avatar.CameraRotation * q; // Mouselook
2534 else
2535 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2536 }
2537 }
2538
2259 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2539 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2260 } 2540 }
2261 2541
2262 public LSL_Rotation llGetLocalRot() 2542 public LSL_Rotation llGetLocalRot()
2263 { 2543 {
2544 return GetPartLocalRot(m_host);
2545 }
2546
2547 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2548 {
2264 m_host.AddScriptLPS(1); 2549 m_host.AddScriptLPS(1);
2265 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2550 Quaternion rot = part.RotationOffset;
2551 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2266 } 2552 }
2267 2553
2268 public void llSetForce(LSL_Vector force, int local) 2554 public void llSetForce(LSL_Vector force, int local)
@@ -2342,16 +2628,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 m_host.ApplyImpulse(v, local != 0); 2628 m_host.ApplyImpulse(v, local != 0);
2343 } 2629 }
2344 2630
2631
2345 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2632 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2346 { 2633 {
2347 m_host.AddScriptLPS(1); 2634 m_host.AddScriptLPS(1);
2348 m_host.ApplyAngularImpulse(force, local != 0); 2635 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2349 } 2636 }
2350 2637
2351 public void llSetTorque(LSL_Vector torque, int local) 2638 public void llSetTorque(LSL_Vector torque, int local)
2352 { 2639 {
2353 m_host.AddScriptLPS(1); 2640 m_host.AddScriptLPS(1);
2354 m_host.SetAngularImpulse(torque, local != 0); 2641 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2355 } 2642 }
2356 2643
2357 public LSL_Vector llGetTorque() 2644 public LSL_Vector llGetTorque()
@@ -2368,20 +2655,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 llSetTorque(torque, local); 2655 llSetTorque(torque, local);
2369 } 2656 }
2370 2657
2658 public void llSetVelocity(LSL_Vector vel, int local)
2659 {
2660 m_host.AddScriptLPS(1);
2661 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2662 }
2663
2371 public LSL_Vector llGetVel() 2664 public LSL_Vector llGetVel()
2372 { 2665 {
2373 m_host.AddScriptLPS(1); 2666 m_host.AddScriptLPS(1);
2374 2667
2375 Vector3 vel; 2668 Vector3 vel = Vector3.Zero;
2376 2669
2377 if (m_host.ParentGroup.IsAttachment) 2670 if (m_host.ParentGroup.IsAttachment)
2378 { 2671 {
2379 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2672 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2380 vel = avatar.Velocity; 2673 if (avatar != null)
2674 vel = avatar.Velocity;
2381 } 2675 }
2382 else 2676 else
2383 { 2677 {
2384 vel = m_host.Velocity; 2678 vel = m_host.ParentGroup.RootPart.Velocity;
2385 } 2679 }
2386 2680
2387 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2681 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2393,10 +2687,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2393 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2687 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2394 } 2688 }
2395 2689
2690 public void llSetAngularVelocity(LSL_Vector avel, int local)
2691 {
2692 m_host.AddScriptLPS(1);
2693 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2694 }
2695
2396 public LSL_Vector llGetOmega() 2696 public LSL_Vector llGetOmega()
2397 { 2697 {
2398 m_host.AddScriptLPS(1); 2698 m_host.AddScriptLPS(1);
2399 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2699 Vector3 avel = m_host.AngularVelocity;
2700 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2400 } 2701 }
2401 2702
2402 public LSL_Float llGetTimeOfDay() 2703 public LSL_Float llGetTimeOfDay()
@@ -2755,7 +3056,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2755 return src.ToLower(); 3056 return src.ToLower();
2756 } 3057 }
2757 3058
2758 public void llGiveMoney(string destination, int amount) 3059 public LSL_Integer llGiveMoney(string destination, int amount)
2759 { 3060 {
2760 Util.FireAndForget(x => 3061 Util.FireAndForget(x =>
2761 { 3062 {
@@ -2787,8 +3088,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2787 } 3088 }
2788 3089
2789 money.ObjectGiveMoney( 3090 money.ObjectGiveMoney(
2790 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3091 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2791 }); 3092 });
3093
3094 return 0;
2792 } 3095 }
2793 3096
2794 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3097 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2867,13 +3170,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2867 new_group.RootPart.UUID.ToString()) }, 3170 new_group.RootPart.UUID.ToString()) },
2868 new DetectParams[0])); 3171 new DetectParams[0]));
2869 3172
2870 float groupmass = new_group.GetMass(); 3173 // do recoil
3174 SceneObjectGroup hostgrp = m_host.ParentGroup;
3175 if (hostgrp == null)
3176 return;
3177
3178 if (hostgrp.IsAttachment) // don't recoil avatars
3179 return;
2871 3180
2872 PhysicsActor pa = new_group.RootPart.PhysActor; 3181 PhysicsActor pa = new_group.RootPart.PhysActor;
2873 3182
2874 //Recoil. 3183 //Recoil.
2875 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3184 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2876 { 3185 {
3186 float groupmass = new_group.GetMass();
2877 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3187 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2878 if (recoil != Vector3.Zero) 3188 if (recoil != Vector3.Zero)
2879 { 3189 {
@@ -2881,6 +3191,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2881 } 3191 }
2882 } 3192 }
2883 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3193 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3194 return;
3195
2884 }); 3196 });
2885 3197
2886 //ScriptSleep((int)((groupmass * velmag) / 10)); 3198 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2895,35 +3207,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2895 public void llLookAt(LSL_Vector target, double strength, double damping) 3207 public void llLookAt(LSL_Vector target, double strength, double damping)
2896 { 3208 {
2897 m_host.AddScriptLPS(1); 3209 m_host.AddScriptLPS(1);
2898 // Determine where we are looking from
2899 LSL_Vector from = llGetPos();
2900 3210
2901 // Work out the normalised vector from the source to the target 3211 // Get the normalized vector to the target
2902 LSL_Vector delta = llVecNorm(target - from); 3212 LSL_Vector d1 = llVecNorm(target - llGetPos());
2903 LSL_Vector angle = new LSL_Vector(0,0,0);
2904 3213
2905 // Calculate the yaw 3214 // Get the bearing (yaw)
2906 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3215 LSL_Vector a1 = new LSL_Vector(0,0,0);
2907 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3216 a1.z = llAtan2(d1.y, d1.x);
2908 3217
2909 // Calculate pitch 3218 // Get the elevation (pitch)
2910 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3219 LSL_Vector a2 = new LSL_Vector(0,0,0);
3220 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2911 3221
2912 // we need to convert from a vector describing 3222 LSL_Rotation r1 = llEuler2Rot(a1);
2913 // the angles of rotation in radians into rotation value 3223 LSL_Rotation r2 = llEuler2Rot(a2);
2914 LSL_Rotation rot = llEuler2Rot(angle); 3224 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2915
2916 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2917 // set the rotation of the object, copy that behavior
2918 PhysicsActor pa = m_host.PhysActor;
2919 3225
2920 if (strength == 0 || pa == null || !pa.IsPhysical) 3226 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2921 { 3227 {
2922 llSetRot(rot); 3228 // Do nothing if either value is 0 (this has been checked in SL)
3229 if (strength <= 0.0 || damping <= 0.0)
3230 return;
3231
3232 llSetRot(r3 * r2 * r1);
2923 } 3233 }
2924 else 3234 else
2925 { 3235 {
2926 m_host.StartLookAt(rot, (float)strength, (float)damping); 3236 if (strength == 0)
3237 {
3238 llSetRot(r3 * r2 * r1);
3239 return;
3240 }
3241
3242 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2927 } 3243 }
2928 } 3244 }
2929 3245
@@ -2970,17 +3286,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2970 } 3286 }
2971 else 3287 else
2972 { 3288 {
2973 if (m_host.IsRoot) 3289 // new SL always returns object mass
2974 { 3290// if (m_host.IsRoot)
3291// {
2975 return m_host.ParentGroup.GetMass(); 3292 return m_host.ParentGroup.GetMass();
2976 } 3293// }
2977 else 3294// else
2978 { 3295// {
2979 return m_host.GetMass(); 3296// return m_host.GetMass();
2980 } 3297// }
2981 } 3298 }
2982 } 3299 }
2983 3300
3301
3302 public LSL_Float llGetMassMKS()
3303 {
3304 return 100f * llGetMass();
3305 }
3306
2984 public void llCollisionFilter(string name, string id, int accept) 3307 public void llCollisionFilter(string name, string id, int accept)
2985 { 3308 {
2986 m_host.AddScriptLPS(1); 3309 m_host.AddScriptLPS(1);
@@ -3028,8 +3351,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3028 { 3351 {
3029 // Unregister controls from Presence 3352 // Unregister controls from Presence
3030 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3353 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3031 // Remove Take Control permission.
3032 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3033 } 3354 }
3034 } 3355 }
3035 } 3356 }
@@ -3057,7 +3378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3378 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3058 3379
3059 if (attachmentsModule != null) 3380 if (attachmentsModule != null)
3060 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3381 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3061 else 3382 else
3062 return false; 3383 return false;
3063 } 3384 }
@@ -3087,9 +3408,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3087 { 3408 {
3088 m_host.AddScriptLPS(1); 3409 m_host.AddScriptLPS(1);
3089 3410
3090// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3091// return;
3092
3093 if (m_item.PermsGranter != m_host.OwnerID) 3411 if (m_item.PermsGranter != m_host.OwnerID)
3094 return; 3412 return;
3095 3413
@@ -3132,6 +3450,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 3450
3133 public void llInstantMessage(string user, string message) 3451 public void llInstantMessage(string user, string message)
3134 { 3452 {
3453 UUID result;
3454 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3455 {
3456 ShoutError("An invalid key was passed to llInstantMessage");
3457 ScriptSleep(2000);
3458 return;
3459 }
3460
3461
3135 m_host.AddScriptLPS(1); 3462 m_host.AddScriptLPS(1);
3136 3463
3137 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3464 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3146,14 +3473,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3146 UUID friendTransactionID = UUID.Random(); 3473 UUID friendTransactionID = UUID.Random();
3147 3474
3148 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3475 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3149 3476
3150 GridInstantMessage msg = new GridInstantMessage(); 3477 GridInstantMessage msg = new GridInstantMessage();
3151 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3478 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3152 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3479 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3153 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3480 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3154// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3481// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3155// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3482// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3156 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3483// DateTime dt = DateTime.UtcNow;
3484//
3485// // Ticks from UtcNow, but make it look like local. Evil, huh?
3486// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3487//
3488// try
3489// {
3490// // Convert that to the PST timezone
3491// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3492// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3493// }
3494// catch
3495// {
3496// // No logging here, as it could be VERY spammy
3497// }
3498//
3499// // And make it look local again to fool the unix time util
3500// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3501
3502 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3503
3157 //if (client != null) 3504 //if (client != null)
3158 //{ 3505 //{
3159 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3506 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3167,12 +3514,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3167 msg.message = message.Substring(0, 1024); 3514 msg.message = message.Substring(0, 1024);
3168 else 3515 else
3169 msg.message = message; 3516 msg.message = message;
3170 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3517 msg.dialog = (byte)19; // MessageFromObject
3171 msg.fromGroup = false;// fromGroup; 3518 msg.fromGroup = false;// fromGroup;
3172 msg.offline = (byte)0; //offline; 3519 msg.offline = (byte)0; //offline;
3173 msg.ParentEstateID = 0; //ParentEstateID; 3520 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3174 msg.Position = new Vector3(m_host.AbsolutePosition); 3521 msg.Position = new Vector3(m_host.AbsolutePosition);
3175 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3522 msg.RegionID = World.RegionInfo.RegionID.Guid;
3176 msg.binaryBucket 3523 msg.binaryBucket
3177 = Util.StringToBytes256( 3524 = Util.StringToBytes256(
3178 "{0}/{1}/{2}/{3}", 3525 "{0}/{1}/{2}/{3}",
@@ -3200,7 +3547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3200 } 3547 }
3201 3548
3202 emailModule.SendEmail(m_host.UUID, address, subject, message); 3549 emailModule.SendEmail(m_host.UUID, address, subject, message);
3203 llSleep(EMAIL_PAUSE_TIME); 3550 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3204 } 3551 }
3205 3552
3206 public void llGetNextEmail(string address, string subject) 3553 public void llGetNextEmail(string address, string subject)
@@ -3446,7 +3793,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3793 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3447 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3794 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3448 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3795 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3796 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3449 ScriptBaseClass.PERMISSION_ATTACH; 3797 ScriptBaseClass.PERMISSION_ATTACH;
3798
3450 } 3799 }
3451 else 3800 else
3452 { 3801 {
@@ -3463,15 +3812,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3463 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3812 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3464 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3813 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3465 } 3814 }
3815 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3816 {
3817 implicitPerms = perm;
3818 }
3466 } 3819 }
3467 3820
3468 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3821 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3469 { 3822 {
3470 lock (m_host.TaskInventory) 3823 m_host.TaskInventory.LockItemsForWrite(true);
3471 { 3824 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3472 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3825 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3473 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3826 m_host.TaskInventory.LockItemsForWrite(false);
3474 }
3475 3827
3476 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3828 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3477 "run_time_permissions", new Object[] { 3829 "run_time_permissions", new Object[] {
@@ -3514,11 +3866,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3514 3866
3515 if (!m_waitingForScriptAnswer) 3867 if (!m_waitingForScriptAnswer)
3516 { 3868 {
3517 lock (m_host.TaskInventory) 3869 m_host.TaskInventory.LockItemsForWrite(true);
3518 { 3870 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3519 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3871 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3520 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3872 m_host.TaskInventory.LockItemsForWrite(false);
3521 }
3522 3873
3523 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3874 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3524 m_waitingForScriptAnswer=true; 3875 m_waitingForScriptAnswer=true;
@@ -3547,14 +3898,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3547 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3898 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3548 llReleaseControls(); 3899 llReleaseControls();
3549 3900
3550 lock (m_host.TaskInventory) 3901 m_host.TaskInventory.LockItemsForWrite(true);
3551 { 3902 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3552 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3903 m_host.TaskInventory.LockItemsForWrite(false);
3553 } 3904
3554 3905 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3555 m_ScriptEngine.PostScriptEvent( 3906 "run_time_permissions", new Object[] {
3556 m_item.ItemID, 3907 new LSL_Integer(answer) },
3557 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3908 new DetectParams[0]));
3558 } 3909 }
3559 3910
3560 public LSL_String llGetPermissionsKey() 3911 public LSL_String llGetPermissionsKey()
@@ -3593,14 +3944,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3593 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3944 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3594 { 3945 {
3595 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3946 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3596 3947 if (parts.Count > 0)
3597 foreach (SceneObjectPart part in parts) 3948 {
3598 part.SetFaceColorAlpha(face, color, null); 3949 try
3950 {
3951 foreach (SceneObjectPart part in parts)
3952 part.SetFaceColorAlpha(face, color, null);
3953 }
3954 finally
3955 {
3956 }
3957 }
3599 } 3958 }
3600 3959
3601 public void llCreateLink(string target, int parent) 3960 public void llCreateLink(string target, int parent)
3602 { 3961 {
3603 m_host.AddScriptLPS(1); 3962 m_host.AddScriptLPS(1);
3963
3604 UUID targetID; 3964 UUID targetID;
3605 3965
3606 if (!UUID.TryParse(target, out targetID)) 3966 if (!UUID.TryParse(target, out targetID))
@@ -3706,10 +4066,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3706 // Restructuring Multiple Prims. 4066 // Restructuring Multiple Prims.
3707 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4067 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3708 parts.Remove(parentPrim.RootPart); 4068 parts.Remove(parentPrim.RootPart);
3709 foreach (SceneObjectPart part in parts) 4069 if (parts.Count > 0)
3710 { 4070 {
3711 parentPrim.DelinkFromGroup(part.LocalId, true); 4071 try
4072 {
4073 foreach (SceneObjectPart part in parts)
4074 {
4075 parentPrim.DelinkFromGroup(part.LocalId, true);
4076 }
4077 }
4078 finally
4079 {
4080 }
3712 } 4081 }
4082
3713 parentPrim.HasGroupChanged = true; 4083 parentPrim.HasGroupChanged = true;
3714 parentPrim.ScheduleGroupForFullUpdate(); 4084 parentPrim.ScheduleGroupForFullUpdate();
3715 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4085 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3718,12 +4088,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 { 4088 {
3719 SceneObjectPart newRoot = parts[0]; 4089 SceneObjectPart newRoot = parts[0];
3720 parts.Remove(newRoot); 4090 parts.Remove(newRoot);
3721 foreach (SceneObjectPart part in parts) 4091
4092 try
3722 { 4093 {
3723 // Required for linking 4094 foreach (SceneObjectPart part in parts)
3724 part.ClearUpdateSchedule(); 4095 {
3725 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4096 part.ClearUpdateSchedule();
4097 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4098 }
3726 } 4099 }
4100 finally
4101 {
4102 }
4103
4104
3727 newRoot.ParentGroup.HasGroupChanged = true; 4105 newRoot.ParentGroup.HasGroupChanged = true;
3728 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4106 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3729 } 4107 }
@@ -3743,6 +4121,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3743 public void llBreakAllLinks() 4121 public void llBreakAllLinks()
3744 { 4122 {
3745 m_host.AddScriptLPS(1); 4123 m_host.AddScriptLPS(1);
4124
4125 TaskInventoryItem item = m_item;
4126
4127 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4128 && !m_automaticLinkPermission)
4129 {
4130 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4131 return;
4132 }
4133
3746 SceneObjectGroup parentPrim = m_host.ParentGroup; 4134 SceneObjectGroup parentPrim = m_host.ParentGroup;
3747 if (parentPrim.AttachmentPoint != 0) 4135 if (parentPrim.AttachmentPoint != 0)
3748 return; // Fail silently if attached 4136 return; // Fail silently if attached
@@ -3762,47 +4150,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3762 public LSL_String llGetLinkKey(int linknum) 4150 public LSL_String llGetLinkKey(int linknum)
3763 { 4151 {
3764 m_host.AddScriptLPS(1); 4152 m_host.AddScriptLPS(1);
3765 4153 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3766 if (linknum < 0) 4154 if (part != null)
3767 {
3768 if (linknum == ScriptBaseClass.LINK_THIS)
3769 return m_host.UUID.ToString();
3770 else
3771 return ScriptBaseClass.NULL_KEY;
3772 }
3773
3774 int actualPrimCount = m_host.ParentGroup.PrimCount;
3775 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3776 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3777
3778 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3779 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3780 if (linknum == 0)
3781 {
3782 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3783 return m_host.UUID.ToString();
3784
3785 return ScriptBaseClass.NULL_KEY;
3786 }
3787 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3788 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3789 else if (linknum == 1 && actualPrimCount == 1)
3790 {
3791 if (sittingAvatarIds.Count > 0)
3792 return m_host.ParentGroup.RootPart.UUID.ToString();
3793 else
3794 return ScriptBaseClass.NULL_KEY;
3795 }
3796 else if (linknum <= adjustedPrimCount)
3797 { 4155 {
3798 if (linknum <= actualPrimCount) 4156 return part.UUID.ToString();
3799 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3800 else
3801 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3802 } 4157 }
3803 else 4158 else
3804 { 4159 {
3805 return ScriptBaseClass.NULL_KEY; 4160 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4161 {
4162 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4163
4164 if (linknum < 0)
4165 return UUID.Zero.ToString();
4166
4167 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4168 if (avatars.Count > linknum)
4169 {
4170 return avatars[linknum].UUID.ToString();
4171 }
4172 }
4173 return UUID.Zero.ToString();
3806 } 4174 }
3807 } 4175 }
3808 4176
@@ -3905,17 +4273,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3905 m_host.AddScriptLPS(1); 4273 m_host.AddScriptLPS(1);
3906 int count = 0; 4274 int count = 0;
3907 4275
3908 lock (m_host.TaskInventory) 4276 m_host.TaskInventory.LockItemsForRead(true);
4277 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3909 { 4278 {
3910 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4279 if (inv.Value.Type == type || type == -1)
3911 { 4280 {
3912 if (inv.Value.Type == type || type == -1) 4281 count = count + 1;
3913 {
3914 count = count + 1;
3915 }
3916 } 4282 }
3917 } 4283 }
3918 4284
4285 m_host.TaskInventory.LockItemsForRead(false);
3919 return count; 4286 return count;
3920 } 4287 }
3921 4288
@@ -3924,16 +4291,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3924 m_host.AddScriptLPS(1); 4291 m_host.AddScriptLPS(1);
3925 ArrayList keys = new ArrayList(); 4292 ArrayList keys = new ArrayList();
3926 4293
3927 lock (m_host.TaskInventory) 4294 m_host.TaskInventory.LockItemsForRead(true);
4295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3928 { 4296 {
3929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4297 if (inv.Value.Type == type || type == -1)
3930 { 4298 {
3931 if (inv.Value.Type == type || type == -1) 4299 keys.Add(inv.Value.Name);
3932 {
3933 keys.Add(inv.Value.Name);
3934 }
3935 } 4300 }
3936 } 4301 }
4302 m_host.TaskInventory.LockItemsForRead(false);
3937 4303
3938 if (keys.Count == 0) 4304 if (keys.Count == 0)
3939 { 4305 {
@@ -3971,7 +4337,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 if (item == null) 4337 if (item == null)
3972 { 4338 {
3973 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4339 llSay(0, String.Format("Could not find object '{0}'", inventory));
3974 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4340 return;
4341// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3975 } 4342 }
3976 4343
3977 UUID objId = item.ItemID; 4344 UUID objId = item.ItemID;
@@ -3999,33 +4366,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3999 return; 4366 return;
4000 } 4367 }
4001 } 4368 }
4369
4002 // destination is an avatar 4370 // destination is an avatar
4003 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4371 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4004 4372
4005 if (agentItem == null) 4373 if (agentItem == null)
4006 return; 4374 return;
4007 4375
4008 if (m_TransferModule != null) 4376 byte[] bucket = new byte[1];
4009 { 4377 bucket[0] = (byte)item.Type;
4010 byte[] bucket = new byte[1]; 4378 //byte[] objBytes = agentItem.ID.GetBytes();
4011 bucket[0] = (byte)item.Type; 4379 //Array.Copy(objBytes, 0, bucket, 1, 16);
4380
4381 GridInstantMessage msg = new GridInstantMessage(World,
4382 m_host.OwnerID, m_host.Name, destId,
4383 (byte)InstantMessageDialog.TaskInventoryOffered,
4384 false, item.Name+". "+m_host.Name+" is located at "+
4385 World.RegionInfo.RegionName+" "+
4386 m_host.AbsolutePosition.ToString(),
4387 agentItem.ID, true, m_host.AbsolutePosition,
4388 bucket, true);
4012 4389
4013 GridInstantMessage msg = new GridInstantMessage(World, 4390 ScenePresence sp;
4014 m_host.OwnerID, m_host.Name, destId,
4015 (byte)InstantMessageDialog.TaskInventoryOffered,
4016 false, item.Name+". "+m_host.Name+" is located at "+
4017 World.RegionInfo.RegionName+" "+
4018 m_host.AbsolutePosition.ToString(),
4019 agentItem.ID, true, m_host.AbsolutePosition,
4020 bucket, true);
4021 4391
4022 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4392 if (World.TryGetScenePresence(destId, out sp))
4393 {
4394 sp.ControllingClient.SendInstantMessage(msg);
4023 } 4395 }
4024 4396 else
4397 {
4398 if (m_TransferModule != null)
4399 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4400 }
4401
4402 //This delay should only occur when giving inventory to avatars.
4025 ScriptSleep(3000); 4403 ScriptSleep(3000);
4026 } 4404 }
4027 } 4405 }
4028 4406
4407 [DebuggerNonUserCode]
4029 public void llRemoveInventory(string name) 4408 public void llRemoveInventory(string name)
4030 { 4409 {
4031 m_host.AddScriptLPS(1); 4410 m_host.AddScriptLPS(1);
@@ -4080,109 +4459,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4080 { 4459 {
4081 m_host.AddScriptLPS(1); 4460 m_host.AddScriptLPS(1);
4082 4461
4083 UUID uuid = (UUID)id; 4462 UUID uuid;
4084 PresenceInfo pinfo = null; 4463 if (UUID.TryParse(id, out uuid))
4085 UserAccount account;
4086
4087 UserInfoCacheEntry ce;
4088 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4089 { 4464 {
4090 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4465 PresenceInfo pinfo = null;
4091 if (account == null) 4466 UserAccount account;
4467
4468 UserInfoCacheEntry ce;
4469 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4092 { 4470 {
4093 m_userInfoCache[uuid] = null; // Cache negative 4471 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4094 return UUID.Zero.ToString(); 4472 if (account == null)
4095 } 4473 {
4474 m_userInfoCache[uuid] = null; // Cache negative
4475 return UUID.Zero.ToString();
4476 }
4096 4477
4097 4478
4098 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4479 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4099 if (pinfos != null && pinfos.Length > 0) 4480 if (pinfos != null && pinfos.Length > 0)
4100 {
4101 foreach (PresenceInfo p in pinfos)
4102 { 4481 {
4103 if (p.RegionID != UUID.Zero) 4482 foreach (PresenceInfo p in pinfos)
4104 { 4483 {
4105 pinfo = p; 4484 if (p.RegionID != UUID.Zero)
4485 {
4486 pinfo = p;
4487 }
4106 } 4488 }
4107 } 4489 }
4108 }
4109 4490
4110 ce = new UserInfoCacheEntry(); 4491 ce = new UserInfoCacheEntry();
4111 ce.time = Util.EnvironmentTickCount(); 4492 ce.time = Util.EnvironmentTickCount();
4112 ce.account = account; 4493 ce.account = account;
4113 ce.pinfo = pinfo; 4494 ce.pinfo = pinfo;
4114 } 4495 m_userInfoCache[uuid] = ce;
4115 else 4496 }
4116 { 4497 else
4117 if (ce == null) 4498 {
4118 return UUID.Zero.ToString(); 4499 if (ce == null)
4500 return UUID.Zero.ToString();
4119 4501
4120 account = ce.account; 4502 account = ce.account;
4121 pinfo = ce.pinfo; 4503 pinfo = ce.pinfo;
4122 } 4504 }
4123 4505
4124 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4506 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4125 {
4126 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4127 if (pinfos != null && pinfos.Length > 0)
4128 { 4507 {
4129 foreach (PresenceInfo p in pinfos) 4508 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4509 if (pinfos != null && pinfos.Length > 0)
4130 { 4510 {
4131 if (p.RegionID != UUID.Zero) 4511 foreach (PresenceInfo p in pinfos)
4132 { 4512 {
4133 pinfo = p; 4513 if (p.RegionID != UUID.Zero)
4514 {
4515 pinfo = p;
4516 }
4134 } 4517 }
4135 } 4518 }
4136 } 4519 else
4137 else 4520 pinfo = null;
4138 pinfo = null;
4139 4521
4140 ce.time = Util.EnvironmentTickCount(); 4522 ce.time = Util.EnvironmentTickCount();
4141 ce.pinfo = pinfo; 4523 ce.pinfo = pinfo;
4142 } 4524 }
4143 4525
4144 string reply = String.Empty; 4526 string reply = String.Empty;
4145 4527
4146 switch (data) 4528 switch (data)
4147 { 4529 {
4148 case 1: // DATA_ONLINE (0|1) 4530 case 1: // DATA_ONLINE (0|1)
4149 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4531 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4150 reply = "1"; 4532 reply = "1";
4151 else 4533 else
4152 reply = "0"; 4534 reply = "0";
4153 break; 4535 break;
4154 case 2: // DATA_NAME (First Last) 4536 case 2: // DATA_NAME (First Last)
4155 reply = account.FirstName + " " + account.LastName; 4537 reply = account.FirstName + " " + account.LastName;
4156 break; 4538 break;
4157 case 3: // DATA_BORN (YYYY-MM-DD) 4539 case 3: // DATA_BORN (YYYY-MM-DD)
4158 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4540 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4159 born = born.AddSeconds(account.Created); 4541 born = born.AddSeconds(account.Created);
4160 reply = born.ToString("yyyy-MM-dd"); 4542 reply = born.ToString("yyyy-MM-dd");
4161 break; 4543 break;
4162 case 4: // DATA_RATING (0,0,0,0,0,0) 4544 case 4: // DATA_RATING (0,0,0,0,0,0)
4163 reply = "0,0,0,0,0,0"; 4545 reply = "0,0,0,0,0,0";
4164 break; 4546 break;
4165 case 7: // DATA_USERLEVEL (integer) 4547 case 8: // DATA_PAYINFO (0|1|2|3)
4166 reply = account.UserLevel.ToString(); 4548 reply = "0";
4167 break; 4549 break;
4168 case 8: // DATA_PAYINFO (0|1|2|3) 4550 default:
4169 reply = "0"; 4551 return UUID.Zero.ToString(); // Raise no event
4170 break; 4552 }
4171 default:
4172 return UUID.Zero.ToString(); // Raise no event
4173 }
4174 4553
4175 UUID rq = UUID.Random(); 4554 UUID rq = UUID.Random();
4176 4555
4177 UUID tid = AsyncCommands. 4556 UUID tid = AsyncCommands.
4178 DataserverPlugin.RegisterRequest(m_host.LocalId, 4557 DataserverPlugin.RegisterRequest(m_host.LocalId,
4179 m_item.ItemID, rq.ToString()); 4558 m_item.ItemID, rq.ToString());
4180 4559
4181 AsyncCommands. 4560 AsyncCommands.
4182 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4561 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4183 4562
4184 ScriptSleep(100); 4563 ScriptSleep(100);
4185 return tid.ToString(); 4564 return tid.ToString();
4565 }
4566 else
4567 {
4568 ShoutError("Invalid UUID passed to llRequestAgentData.");
4569 }
4570 return "";
4186 } 4571 }
4187 4572
4188 public LSL_String llRequestInventoryData(string name) 4573 public LSL_String llRequestInventoryData(string name)
@@ -4239,13 +4624,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4239 if (UUID.TryParse(agent, out agentId)) 4624 if (UUID.TryParse(agent, out agentId))
4240 { 4625 {
4241 ScenePresence presence = World.GetScenePresence(agentId); 4626 ScenePresence presence = World.GetScenePresence(agentId);
4242 if (presence != null) 4627 if (presence != null && presence.PresenceType != PresenceType.Npc)
4243 { 4628 {
4629 // agent must not be a god
4630 if (presence.UserLevel >= 200) return;
4631
4244 // agent must be over the owners land 4632 // agent must be over the owners land
4245 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4633 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4246 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4634 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4247 { 4635 {
4248 World.TeleportClientHome(agentId, presence.ControllingClient); 4636 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4637 {
4638 // They can't be teleported home for some reason
4639 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4640 if (regionInfo != null)
4641 {
4642 World.RequestTeleportLocation(
4643 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4644 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4645 }
4646 }
4249 } 4647 }
4250 } 4648 }
4251 } 4649 }
@@ -4352,7 +4750,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4352 UUID av = new UUID(); 4750 UUID av = new UUID();
4353 if (!UUID.TryParse(agent,out av)) 4751 if (!UUID.TryParse(agent,out av))
4354 { 4752 {
4355 LSLError("First parameter to llDialog needs to be a key"); 4753 //LSLError("First parameter to llDialog needs to be a key");
4356 return; 4754 return;
4357 } 4755 }
4358 4756
@@ -4384,10 +4782,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4384 public void llCollisionSound(string impact_sound, double impact_volume) 4782 public void llCollisionSound(string impact_sound, double impact_volume)
4385 { 4783 {
4386 m_host.AddScriptLPS(1); 4784 m_host.AddScriptLPS(1);
4387 4785
4786 if(impact_sound == "")
4787 {
4788 m_host.CollisionSoundVolume = (float)impact_volume;
4789 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4790 m_host.CollisionSoundType = 0;
4791 return;
4792 }
4388 // TODO: Parameter check logic required. 4793 // TODO: Parameter check logic required.
4389 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4794 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4390 m_host.CollisionSoundVolume = (float)impact_volume; 4795 m_host.CollisionSoundVolume = (float)impact_volume;
4796 m_host.CollisionSoundType = 1;
4391 } 4797 }
4392 4798
4393 public LSL_String llGetAnimation(string id) 4799 public LSL_String llGetAnimation(string id)
@@ -4401,14 +4807,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4401 4807
4402 if (m_host.RegionHandle == presence.RegionHandle) 4808 if (m_host.RegionHandle == presence.RegionHandle)
4403 { 4809 {
4404 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4405
4406 if (presence != null) 4810 if (presence != null)
4407 { 4811 {
4408 AnimationSet currentAnims = presence.Animator.Animations; 4812 if (presence.SitGround)
4409 string currentAnimationState = String.Empty; 4813 return "Sitting on Ground";
4410 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4814 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4411 return currentAnimationState; 4815 return "Sitting";
4816
4817 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4818 string lslMovementAnimation;
4819
4820 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4821 return lslMovementAnimation;
4412 } 4822 }
4413 } 4823 }
4414 4824
@@ -4555,7 +4965,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4555 { 4965 {
4556 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4966 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4557 float distance_term = distance * distance * distance; // Script Energy 4967 float distance_term = distance * distance * distance; // Script Energy
4558 float pusher_mass = m_host.GetMass(); 4968 // use total object mass and not part
4969 float pusher_mass = m_host.ParentGroup.GetMass();
4559 4970
4560 float PUSH_ATTENUATION_DISTANCE = 17f; 4971 float PUSH_ATTENUATION_DISTANCE = 17f;
4561 float PUSH_ATTENUATION_SCALE = 5f; 4972 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4805,6 +5216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4805 { 5216 {
4806 return item.AssetID.ToString(); 5217 return item.AssetID.ToString();
4807 } 5218 }
5219 m_host.TaskInventory.LockItemsForRead(false);
4808 5220
4809 return UUID.Zero.ToString(); 5221 return UUID.Zero.ToString();
4810 } 5222 }
@@ -4957,14 +5369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4957 { 5369 {
4958 m_host.AddScriptLPS(1); 5370 m_host.AddScriptLPS(1);
4959 5371
4960 if (src == null) 5372 return src.Length;
4961 {
4962 return 0;
4963 }
4964 else
4965 {
4966 return src.Length;
4967 }
4968 } 5373 }
4969 5374
4970 public LSL_Integer llList2Integer(LSL_List src, int index) 5375 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5035,7 +5440,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5035 else if (src.Data[index] is LSL_Float) 5440 else if (src.Data[index] is LSL_Float)
5036 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5441 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5037 else if (src.Data[index] is LSL_String) 5442 else if (src.Data[index] is LSL_String)
5038 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5443 {
5444 string str = ((LSL_String) src.Data[index]).m_string;
5445 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5446 if (m != Match.Empty)
5447 {
5448 str = m.Value;
5449 double d = 0.0;
5450 if (!Double.TryParse(str, out d))
5451 return 0.0;
5452
5453 return d;
5454 }
5455 return 0.0;
5456 }
5039 return Convert.ToDouble(src.Data[index]); 5457 return Convert.ToDouble(src.Data[index]);
5040 } 5458 }
5041 catch (FormatException) 5459 catch (FormatException)
@@ -5077,7 +5495,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5077 // for completion and should LSL_Key ever be implemented 5495 // for completion and should LSL_Key ever be implemented
5078 // as it's own struct 5496 // as it's own struct
5079 else if (!(src.Data[index] is LSL_String || 5497 else if (!(src.Data[index] is LSL_String ||
5080 src.Data[index] is LSL_Key)) 5498 src.Data[index] is LSL_Key ||
5499 src.Data[index] is String))
5081 { 5500 {
5082 return ""; 5501 return "";
5083 } 5502 }
@@ -5335,7 +5754,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5335 } 5754 }
5336 } 5755 }
5337 } 5756 }
5338 else { 5757 else
5758 {
5339 object[] array = new object[src.Length]; 5759 object[] array = new object[src.Length];
5340 Array.Copy(src.Data, 0, array, 0, src.Length); 5760 Array.Copy(src.Data, 0, array, 0, src.Length);
5341 result = new LSL_List(array); 5761 result = new LSL_List(array);
@@ -5442,7 +5862,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5442 public LSL_Integer llGetRegionAgentCount() 5862 public LSL_Integer llGetRegionAgentCount()
5443 { 5863 {
5444 m_host.AddScriptLPS(1); 5864 m_host.AddScriptLPS(1);
5445 return new LSL_Integer(World.GetRootAgentCount()); 5865
5866 int count = 0;
5867 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5868 count++;
5869 });
5870
5871 return new LSL_Integer(count);
5446 } 5872 }
5447 5873
5448 public LSL_Vector llGetRegionCorner() 5874 public LSL_Vector llGetRegionCorner()
@@ -5683,6 +6109,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5683 flags |= ScriptBaseClass.AGENT_AWAY; 6109 flags |= ScriptBaseClass.AGENT_AWAY;
5684 } 6110 }
5685 6111
6112 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6113 UUID[] anims = agent.Animator.GetAnimationArray();
6114 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6115 {
6116 flags |= ScriptBaseClass.AGENT_BUSY;
6117 }
6118
5686 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6119 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5687 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6120 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5688 { 6121 {
@@ -5730,6 +6163,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5730 flags |= ScriptBaseClass.AGENT_SITTING; 6163 flags |= ScriptBaseClass.AGENT_SITTING;
5731 } 6164 }
5732 6165
6166 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6167 {
6168 flags |= ScriptBaseClass.AGENT_MALE;
6169 }
6170
5733 return flags; 6171 return flags;
5734 } 6172 }
5735 6173
@@ -5877,9 +6315,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5877 6315
5878 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6316 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5879 6317
5880 foreach (SceneObjectPart part in parts) 6318 try
6319 {
6320 foreach (SceneObjectPart part in parts)
6321 {
6322 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6323 }
6324 }
6325 finally
5881 { 6326 {
5882 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5883 } 6327 }
5884 } 6328 }
5885 6329
@@ -5933,13 +6377,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5933 6377
5934 if (m_host.OwnerID == land.LandData.OwnerID) 6378 if (m_host.OwnerID == land.LandData.OwnerID)
5935 { 6379 {
5936 World.TeleportClientHome(agentID, presence.ControllingClient); 6380 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6381 presence.TeleportWithMomentum(pos, null);
6382 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5937 } 6383 }
5938 } 6384 }
5939 } 6385 }
5940 ScriptSleep(5000); 6386 ScriptSleep(5000);
5941 } 6387 }
5942 6388
6389 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6390 {
6391 return ParseString2List(str, separators, in_spacers, false);
6392 }
6393
5943 public LSL_Integer llOverMyLand(string id) 6394 public LSL_Integer llOverMyLand(string id)
5944 { 6395 {
5945 m_host.AddScriptLPS(1); 6396 m_host.AddScriptLPS(1);
@@ -5993,25 +6444,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5993 } 6444 }
5994 else 6445 else
5995 { 6446 {
5996 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6447// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6448 Vector3 s = avatar.Appearance.AvatarSize;
6449 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5997 } 6450 }
5998 return agentSize; 6451 return agentSize;
5999 } 6452 }
6000 6453
6001 public LSL_Integer llSameGroup(string agent) 6454 public LSL_Integer llSameGroup(string id)
6002 { 6455 {
6003 m_host.AddScriptLPS(1); 6456 m_host.AddScriptLPS(1);
6004 UUID agentId = new UUID(); 6457 UUID uuid = new UUID();
6005 if (!UUID.TryParse(agent, out agentId)) 6458 if (!UUID.TryParse(id, out uuid))
6006 return new LSL_Integer(0);
6007 ScenePresence presence = World.GetScenePresence(agentId);
6008 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6009 return new LSL_Integer(0); 6459 return new LSL_Integer(0);
6010 IClientAPI client = presence.ControllingClient; 6460
6011 if (m_host.GroupID == client.ActiveGroupId) 6461 // Check if it's a group key
6462 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6012 return new LSL_Integer(1); 6463 return new LSL_Integer(1);
6013 else 6464
6465 // We got passed a UUID.Zero
6466 if (uuid == UUID.Zero)
6467 return new LSL_Integer(0);
6468
6469 // Handle the case where id names an avatar
6470 ScenePresence presence = World.GetScenePresence(uuid);
6471 if (presence != null)
6472 {
6473 if (presence.IsChildAgent)
6474 return new LSL_Integer(0);
6475
6476 IClientAPI client = presence.ControllingClient;
6477 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6478 return new LSL_Integer(1);
6479
6480 return new LSL_Integer(0);
6481 }
6482
6483 // Handle object case
6484 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6485 if (part != null)
6486 {
6487 // This will handle both deed and non-deed and also the no
6488 // group case
6489 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6490 return new LSL_Integer(1);
6491
6014 return new LSL_Integer(0); 6492 return new LSL_Integer(0);
6493 }
6494
6495 return new LSL_Integer(0);
6015 } 6496 }
6016 6497
6017 public void llUnSit(string id) 6498 public void llUnSit(string id)
@@ -6136,7 +6617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6136 return m_host.ParentGroup.AttachmentPoint; 6617 return m_host.ParentGroup.AttachmentPoint;
6137 } 6618 }
6138 6619
6139 public LSL_Integer llGetFreeMemory() 6620 public virtual LSL_Integer llGetFreeMemory()
6140 { 6621 {
6141 m_host.AddScriptLPS(1); 6622 m_host.AddScriptLPS(1);
6142 // Make scripts designed for LSO happy 6623 // Make scripts designed for LSO happy
@@ -6568,6 +7049,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6568 7049
6569 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7050 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6570 { 7051 {
7052 // LSL quaternions can normalize to 0, normal Quaternions can't.
7053 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7054 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7055
6571 part.SitTargetPosition = offset; 7056 part.SitTargetPosition = offset;
6572 part.SitTargetOrientation = rot; 7057 part.SitTargetOrientation = rot;
6573 part.ParentGroup.HasGroupChanged = true; 7058 part.ParentGroup.HasGroupChanged = true;
@@ -6753,13 +7238,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6753 UUID av = new UUID(); 7238 UUID av = new UUID();
6754 if (!UUID.TryParse(avatar,out av)) 7239 if (!UUID.TryParse(avatar,out av))
6755 { 7240 {
6756 LSLError("First parameter to llDialog needs to be a key"); 7241 //LSLError("First parameter to llDialog needs to be a key");
6757 return; 7242 return;
6758 } 7243 }
6759 if (buttons.Length < 1) 7244 if (buttons.Length < 1)
6760 { 7245 {
6761 LSLError("No less than 1 button can be shown"); 7246 buttons.Add("OK");
6762 return;
6763 } 7247 }
6764 if (buttons.Length > 12) 7248 if (buttons.Length > 12)
6765 { 7249 {
@@ -6776,7 +7260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6776 } 7260 }
6777 if (buttons.Data[i].ToString().Length > 24) 7261 if (buttons.Data[i].ToString().Length > 24)
6778 { 7262 {
6779 LSLError("button label cannot be longer than 24 characters"); 7263 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6780 return; 7264 return;
6781 } 7265 }
6782 buts[i] = buttons.Data[i].ToString(); 7266 buts[i] = buttons.Data[i].ToString();
@@ -6843,9 +7327,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6843 return; 7327 return;
6844 } 7328 }
6845 7329
6846 // the rest of the permission checks are done in RezScript, so check the pin there as well 7330 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6847 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7331 if (dest != null)
7332 {
7333 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7334 {
7335 // the rest of the permission checks are done in RezScript, so check the pin there as well
7336 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6848 7337
7338 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7339 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7340 }
7341 }
6849 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7342 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6850 ScriptSleep(3000); 7343 ScriptSleep(3000);
6851 } 7344 }
@@ -6919,19 +7412,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6919 public LSL_String llMD5String(string src, int nonce) 7412 public LSL_String llMD5String(string src, int nonce)
6920 { 7413 {
6921 m_host.AddScriptLPS(1); 7414 m_host.AddScriptLPS(1);
6922 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7415 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6923 } 7416 }
6924 7417
6925 public LSL_String llSHA1String(string src) 7418 public LSL_String llSHA1String(string src)
6926 { 7419 {
6927 m_host.AddScriptLPS(1); 7420 m_host.AddScriptLPS(1);
6928 return Util.SHA1Hash(src).ToLower(); 7421 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6929 } 7422 }
6930 7423
6931 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7424 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6932 { 7425 {
6933 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7426 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6934 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7427 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return shapeBlock;
6935 7430
6936 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7431 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6937 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7432 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7036,6 +7531,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7036 // Prim type box, cylinder and prism. 7531 // Prim type box, cylinder and prism.
7037 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) 7532 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)
7038 { 7533 {
7534 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7535 return;
7536
7039 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7537 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7040 ObjectShapePacket.ObjectDataBlock shapeBlock; 7538 ObjectShapePacket.ObjectDataBlock shapeBlock;
7041 7539
@@ -7089,6 +7587,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7089 // Prim type sphere. 7587 // Prim type sphere.
7090 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7588 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7091 { 7589 {
7590 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7591 return;
7592
7092 ObjectShapePacket.ObjectDataBlock shapeBlock; 7593 ObjectShapePacket.ObjectDataBlock shapeBlock;
7093 7594
7094 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7595 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7130,6 +7631,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7130 // Prim type torus, tube and ring. 7631 // Prim type torus, tube and ring.
7131 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) 7632 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)
7132 { 7633 {
7634 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7635 return;
7636
7133 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7637 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7134 ObjectShapePacket.ObjectDataBlock shapeBlock; 7638 ObjectShapePacket.ObjectDataBlock shapeBlock;
7135 7639
@@ -7265,6 +7769,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7265 // Prim type sculpt. 7769 // Prim type sculpt.
7266 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7770 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7267 { 7771 {
7772 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7773 return;
7774
7268 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7775 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7269 UUID sculptId; 7776 UUID sculptId;
7270 7777
@@ -7289,7 +7796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7289 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7796 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7290 { 7797 {
7291 // default 7798 // default
7292 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7799 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7293 } 7800 }
7294 7801
7295 part.Shape.SetSculptProperties((byte)type, sculptId); 7802 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7306,48 +7813,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7306 ScriptSleep(200); 7813 ScriptSleep(200);
7307 } 7814 }
7308 7815
7309 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7816 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7310 { 7817 {
7311 m_host.AddScriptLPS(1); 7818 m_host.AddScriptLPS(1);
7312 7819
7313 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7820 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7821 }
7314 7822
7315 ScriptSleep(200); 7823 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7824 {
7825 List<object> parts = new List<object>();
7826 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7827 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7828 foreach (SceneObjectPart p in prims)
7829 parts.Add(p);
7830 foreach (ScenePresence p in avatars)
7831 parts.Add(p);
7832
7833 LSL_List remaining = null;
7834 uint rulesParsed = 0;
7835
7836 if (parts.Count > 0)
7837 {
7838 foreach (object part in parts)
7839 {
7840 if (part is SceneObjectPart)
7841 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7842 else
7843 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7844 }
7845
7846 while ((object)remaining != null && remaining.Length > 2)
7847 {
7848 linknumber = remaining.GetLSLIntegerItem(0);
7849 rules = remaining.GetSublist(1, -1);
7850 parts.Clear();
7851 prims = GetLinkParts(linknumber);
7852 avatars = GetLinkAvatars(linknumber);
7853 foreach (SceneObjectPart p in prims)
7854 parts.Add(p);
7855 foreach (ScenePresence p in avatars)
7856 parts.Add(p);
7857
7858 remaining = null;
7859 foreach (object part in parts)
7860 {
7861 if (part is SceneObjectPart)
7862 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7863 else
7864 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7865 }
7866 }
7867 }
7316 } 7868 }
7317 7869
7318 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7870 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7871 float material_density, float material_friction,
7872 float material_restitution, float material_gravity_modifier)
7319 { 7873 {
7320 m_host.AddScriptLPS(1); 7874 ExtraPhysicsData physdata = new ExtraPhysicsData();
7875 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7876 physdata.Density = part.Density;
7877 physdata.Friction = part.Friction;
7878 physdata.Bounce = part.Bounciness;
7879 physdata.GravitationModifier = part.GravityModifier;
7321 7880
7322 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7881 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7882 physdata.Density = material_density;
7883 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7884 physdata.Friction = material_friction;
7885 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7886 physdata.Bounce = material_restitution;
7887 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7888 physdata.GravitationModifier = material_gravity_modifier;
7889
7890 part.UpdateExtraPhysics(physdata);
7323 } 7891 }
7324 7892
7325 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7893 public void llSetPhysicsMaterial(int material_bits,
7894 float material_gravity_modifier, float material_restitution,
7895 float material_friction, float material_density)
7326 { 7896 {
7327 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7897 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7898 }
7328 7899
7329 LSL_List remaining = null; 7900 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7330 uint rulesParsed = 0; 7901 {
7902 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7903 llSetLinkPrimitiveParamsFast(linknumber, rules);
7904 ScriptSleep(200);
7905 }
7331 7906
7332 foreach (SceneObjectPart part in parts) 7907 // vector up using libomv (c&p from sop )
7333 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7908 // vector up rotated by r
7909 private Vector3 Zrot(Quaternion r)
7910 {
7911 double x, y, z, m;
7334 7912
7335 while (remaining != null && remaining.Length > 2) 7913 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7914 if (Math.Abs(1.0 - m) > 0.000001)
7336 { 7915 {
7337 linknumber = remaining.GetLSLIntegerItem(0); 7916 m = 1.0 / Math.Sqrt(m);
7338 rules = remaining.GetSublist(1, -1); 7917 r.X *= (float)m;
7339 parts = GetLinkParts(linknumber); 7918 r.Y *= (float)m;
7340 7919 r.Z *= (float)m;
7341 foreach (SceneObjectPart part in parts) 7920 r.W *= (float)m;
7342 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7343 } 7921 }
7922
7923 x = 2 * (r.X * r.Z + r.Y * r.W);
7924 y = 2 * (-r.X * r.W + r.Y * r.Z);
7925 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7926
7927 return new Vector3((float)x, (float)y, (float)z);
7344 } 7928 }
7345 7929
7346 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7930 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7347 { 7931 {
7932 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7933 return null;
7934
7348 int idx = 0; 7935 int idx = 0;
7349 int idxStart = 0; 7936 int idxStart = 0;
7350 7937
7938 SceneObjectGroup parentgrp = part.ParentGroup;
7939
7351 bool positionChanged = false; 7940 bool positionChanged = false;
7352 LSL_Vector currentPosition = GetPartLocalPos(part); 7941 LSL_Vector currentPosition = GetPartLocalPos(part);
7353 7942
@@ -7372,8 +7961,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7372 return null; 7961 return null;
7373 7962
7374 v=rules.GetVector3Item(idx++); 7963 v=rules.GetVector3Item(idx++);
7964 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7965 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7966 else
7967 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7375 positionChanged = true; 7968 positionChanged = true;
7376 currentPosition = GetSetPosTarget(part, v, currentPosition);
7377 7969
7378 break; 7970 break;
7379 case (int)ScriptBaseClass.PRIM_SIZE: 7971 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7390,7 +7982,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7390 7982
7391 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7983 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7392 // try to let this work as in SL... 7984 // try to let this work as in SL...
7393 if (part.ParentID == 0) 7985 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7394 { 7986 {
7395 // special case: If we are root, rotate complete SOG to new rotation 7987 // special case: If we are root, rotate complete SOG to new rotation
7396 SetRot(part, q); 7988 SetRot(part, q);
@@ -7650,7 +8242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7650 return null; 8242 return null;
7651 8243
7652 string ph = rules.Data[idx++].ToString(); 8244 string ph = rules.Data[idx++].ToString();
7653 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8245 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7654 8246
7655 break; 8247 break;
7656 8248
@@ -7668,12 +8260,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7668 part.ScriptSetPhysicsStatus(physics); 8260 part.ScriptSetPhysicsStatus(physics);
7669 break; 8261 break;
7670 8262
8263 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8264 if (remain < 1)
8265 return null;
8266
8267 int shape_type = rules.GetLSLIntegerItem(idx++);
8268
8269 ExtraPhysicsData physdata = new ExtraPhysicsData();
8270 physdata.Density = part.Density;
8271 physdata.Bounce = part.Bounciness;
8272 physdata.GravitationModifier = part.GravityModifier;
8273 physdata.PhysShapeType = (PhysShapeType)shape_type;
8274
8275 part.UpdateExtraPhysics(physdata);
8276
8277 break;
8278
8279 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8280 if (remain < 5)
8281 return null;
8282
8283 int material_bits = rules.GetLSLIntegerItem(idx++);
8284 float material_density = (float)rules.GetLSLFloatItem(idx++);
8285 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8286 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8287 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8288
8289 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8290
8291 break;
8292
7671 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8293 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7672 if (remain < 1) 8294 if (remain < 1)
7673 return null; 8295 return null;
7674 string temp = rules.Data[idx++].ToString(); 8296 string temp = rules.Data[idx++].ToString();
7675 8297
7676 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8298 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7677 8299
7678 break; 8300 break;
7679 8301
@@ -7747,14 +8369,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7747 if (part.ParentGroup.RootPart == part) 8369 if (part.ParentGroup.RootPart == part)
7748 { 8370 {
7749 SceneObjectGroup parent = part.ParentGroup; 8371 SceneObjectGroup parent = part.ParentGroup;
7750 parent.UpdateGroupPosition(currentPosition); 8372 Util.FireAndForget(delegate(object x) {
8373 parent.UpdateGroupPosition(currentPosition);
8374 });
7751 } 8375 }
7752 else 8376 else
7753 { 8377 {
7754 part.OffsetPosition = currentPosition; 8378 part.OffsetPosition = currentPosition;
7755 SceneObjectGroup parent = part.ParentGroup; 8379// SceneObjectGroup parent = part.ParentGroup;
7756 parent.HasGroupChanged = true; 8380// parent.HasGroupChanged = true;
7757 parent.ScheduleGroupForTerseUpdate(); 8381// parent.ScheduleGroupForTerseUpdate();
8382 part.ScheduleTerseUpdate();
7758 } 8383 }
7759 } 8384 }
7760 } 8385 }
@@ -7792,10 +8417,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7792 8417
7793 public LSL_String llXorBase64Strings(string str1, string str2) 8418 public LSL_String llXorBase64Strings(string str1, string str2)
7794 { 8419 {
7795 m_host.AddScriptLPS(1); 8420 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7796 Deprecated("llXorBase64Strings"); 8421
7797 ScriptSleep(300); 8422 ScriptSleep(300);
7798 return String.Empty; 8423 m_host.AddScriptLPS(1);
8424
8425 if (str1 == String.Empty)
8426 return String.Empty;
8427 if (str2 == String.Empty)
8428 return str1;
8429
8430 int len = str2.Length;
8431 if ((len % 4) != 0) // LL is EVIL!!!!
8432 {
8433 while (str2.EndsWith("="))
8434 str2 = str2.Substring(0, str2.Length - 1);
8435
8436 len = str2.Length;
8437 int mod = len % 4;
8438
8439 if (mod == 1)
8440 str2 = str2.Substring(0, str2.Length - 1);
8441 else if (mod == 2)
8442 str2 += "==";
8443 else if (mod == 3)
8444 str2 += "=";
8445 }
8446
8447 byte[] data1;
8448 byte[] data2;
8449 try
8450 {
8451 data1 = Convert.FromBase64String(str1);
8452 data2 = Convert.FromBase64String(str2);
8453 }
8454 catch (Exception)
8455 {
8456 return new LSL_String(String.Empty);
8457 }
8458
8459 // For cases where the decoded length of s2 is greater
8460 // than the decoded length of s1, simply perform a normal
8461 // decode and XOR
8462 //
8463 if (data2.Length >= data1.Length)
8464 {
8465 for (int pos = 0 ; pos < data1.Length ; pos++ )
8466 data1[pos] ^= data2[pos];
8467
8468 return Convert.ToBase64String(data1);
8469 }
8470
8471 // Remove padding
8472 while (str1.EndsWith("="))
8473 str1 = str1.Substring(0, str1.Length - 1);
8474 while (str2.EndsWith("="))
8475 str2 = str2.Substring(0, str2.Length - 1);
8476
8477 byte[] d1 = new byte[str1.Length];
8478 byte[] d2 = new byte[str2.Length];
8479
8480 for (int i = 0 ; i < str1.Length ; i++)
8481 {
8482 int idx = b64.IndexOf(str1.Substring(i, 1));
8483 if (idx == -1)
8484 idx = 0;
8485 d1[i] = (byte)idx;
8486 }
8487
8488 for (int i = 0 ; i < str2.Length ; i++)
8489 {
8490 int idx = b64.IndexOf(str2.Substring(i, 1));
8491 if (idx == -1)
8492 idx = 0;
8493 d2[i] = (byte)idx;
8494 }
8495
8496 string output = String.Empty;
8497
8498 for (int pos = 0 ; pos < d1.Length ; pos++)
8499 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8500
8501 while (output.Length % 3 > 0)
8502 output += "=";
8503
8504 return output;
7799 } 8505 }
7800 8506
7801 public void llRemoteDataSetRegion() 8507 public void llRemoteDataSetRegion()
@@ -7919,8 +8625,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7919 public LSL_Integer llGetNumberOfPrims() 8625 public LSL_Integer llGetNumberOfPrims()
7920 { 8626 {
7921 m_host.AddScriptLPS(1); 8627 m_host.AddScriptLPS(1);
7922 8628 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7923 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8629
8630 return m_host.ParentGroup.PrimCount + avatarCount;
7924 } 8631 }
7925 8632
7926 /// <summary> 8633 /// <summary>
@@ -7935,55 +8642,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7935 m_host.AddScriptLPS(1); 8642 m_host.AddScriptLPS(1);
7936 UUID objID = UUID.Zero; 8643 UUID objID = UUID.Zero;
7937 LSL_List result = new LSL_List(); 8644 LSL_List result = new LSL_List();
8645
8646 // If the ID is not valid, return null result
7938 if (!UUID.TryParse(obj, out objID)) 8647 if (!UUID.TryParse(obj, out objID))
7939 { 8648 {
7940 result.Add(new LSL_Vector()); 8649 result.Add(new LSL_Vector());
7941 result.Add(new LSL_Vector()); 8650 result.Add(new LSL_Vector());
7942 return result; 8651 return result;
7943 } 8652 }
8653
8654 // Check if this is an attached prim. If so, replace
8655 // the UUID with the avatar UUID and report it's bounding box
8656 SceneObjectPart part = World.GetSceneObjectPart(objID);
8657 if (part != null && part.ParentGroup.IsAttachment)
8658 objID = part.ParentGroup.AttachedAvatar;
8659
8660 // Find out if this is an avatar ID. If so, return it's box
7944 ScenePresence presence = World.GetScenePresence(objID); 8661 ScenePresence presence = World.GetScenePresence(objID);
7945 if (presence != null) 8662 if (presence != null)
7946 { 8663 {
7947 if (presence.ParentID == 0) // not sat on an object 8664 // As per LSL Wiki, there is no difference between sitting
8665 // and standing avatar since server 1.36
8666 LSL_Vector lower;
8667 LSL_Vector upper;
8668
8669 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8670
8671 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8672 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8673/*
7948 { 8674 {
7949 LSL_Vector lower; 8675 // This is for ground sitting avatars
7950 LSL_Vector upper; 8676 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7951 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8677 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7952 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8678 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7953 { 8679 }
7954 // This is for ground sitting avatars 8680 else
7955 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8681 {
7956 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8682 // This is for standing/flying avatars
7957 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8683 float height = presence.Appearance.AvatarHeight / 2.0f;
7958 } 8684 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7959 else 8685 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7960 { 8686 }
7961 // This is for standing/flying avatars 8687
7962 float height = presence.Appearance.AvatarHeight / 2.0f; 8688 // Adjust to the documented error offsets (see LSL Wiki)
7963 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8689 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7964 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8690 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7965 } 8691*/
7966 result.Add(lower); 8692 {
7967 result.Add(upper); 8693 // This is for ground sitting avatars TODO!
7968 return result; 8694 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8695 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7969 } 8696 }
7970 else 8697 else
7971 { 8698 {
7972 // sitting on an object so we need the bounding box of that 8699 // This is for standing/flying avatars
7973 // which should include the avatar so set the UUID to the 8700 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7974 // UUID of the object the avatar is sat on and allow it to fall through 8701 upper = new LSL_Vector(box.X, box.Y, box.Z);
7975 // to processing an object
7976 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7977 objID = p.UUID;
7978 } 8702 }
8703
8704 if (lower.x > upper.x)
8705 lower.x = upper.x;
8706 if (lower.y > upper.y)
8707 lower.y = upper.y;
8708 if (lower.z > upper.z)
8709 lower.z = upper.z;
8710
8711 result.Add(lower);
8712 result.Add(upper);
8713 return result;
7979 } 8714 }
7980 SceneObjectPart part = World.GetSceneObjectPart(objID); 8715
8716 part = World.GetSceneObjectPart(objID);
7981 // Currently only works for single prims without a sitting avatar 8717 // Currently only works for single prims without a sitting avatar
7982 if (part != null) 8718 if (part != null)
7983 { 8719 {
7984 Vector3 halfSize = part.Scale / 2.0f; 8720 float minX;
7985 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8721 float maxX;
7986 LSL_Vector upper = new LSL_Vector(halfSize); 8722 float minY;
8723 float maxY;
8724 float minZ;
8725 float maxZ;
8726
8727 // This BBox is in sim coordinates, with the offset being
8728 // a contained point.
8729 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8730 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8731
8732 minX -= offsets[0].X;
8733 maxX -= offsets[0].X;
8734 minY -= offsets[0].Y;
8735 maxY -= offsets[0].Y;
8736 minZ -= offsets[0].Z;
8737 maxZ -= offsets[0].Z;
8738
8739 LSL_Vector lower;
8740 LSL_Vector upper;
8741
8742 // Adjust to the documented error offsets (see LSL Wiki)
8743 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8744 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8745
8746 if (lower.x > upper.x)
8747 lower.x = upper.x;
8748 if (lower.y > upper.y)
8749 lower.y = upper.y;
8750 if (lower.z > upper.z)
8751 lower.z = upper.z;
8752
7987 result.Add(lower); 8753 result.Add(lower);
7988 result.Add(upper); 8754 result.Add(upper);
7989 return result; 8755 return result;
@@ -7997,7 +8763,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7997 8763
7998 public LSL_Vector llGetGeometricCenter() 8764 public LSL_Vector llGetGeometricCenter()
7999 { 8765 {
8000 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8766 Vector3 tmp = m_host.GetGeometricCenter();
8767 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
8001 } 8768 }
8002 8769
8003 public LSL_List llGetPrimitiveParams(LSL_List rules) 8770 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8008,7 +8775,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 8775
8009 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8776 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8010 8777
8011 while (remaining != null && remaining.Length > 2) 8778 while ((object)remaining != null && remaining.Length > 2)
8012 { 8779 {
8013 int linknumber = remaining.GetLSLIntegerItem(0); 8780 int linknumber = remaining.GetLSLIntegerItem(0);
8014 rules = remaining.GetSublist(1, -1); 8781 rules = remaining.GetSublist(1, -1);
@@ -8025,24 +8792,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8025 { 8792 {
8026 m_host.AddScriptLPS(1); 8793 m_host.AddScriptLPS(1);
8027 8794
8028 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8795 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8796 // keep other options as before
8029 8797
8798 List<SceneObjectPart> parts;
8799 List<ScenePresence> avatars;
8800
8030 LSL_List res = new LSL_List(); 8801 LSL_List res = new LSL_List();
8031 LSL_List remaining = null; 8802 LSL_List remaining = null;
8032 8803
8033 foreach (SceneObjectPart part in parts) 8804 while (rules.Length > 0)
8034 {
8035 remaining = GetPrimParams(part, rules, ref res);
8036 }
8037
8038 while (remaining != null && remaining.Length > 2)
8039 { 8805 {
8040 linknumber = remaining.GetLSLIntegerItem(0);
8041 rules = remaining.GetSublist(1, -1);
8042 parts = GetLinkParts(linknumber); 8806 parts = GetLinkParts(linknumber);
8807 avatars = GetLinkAvatars(linknumber);
8043 8808
8809 remaining = null;
8044 foreach (SceneObjectPart part in parts) 8810 foreach (SceneObjectPart part in parts)
8811 {
8045 remaining = GetPrimParams(part, rules, ref res); 8812 remaining = GetPrimParams(part, rules, ref res);
8813 }
8814 foreach (ScenePresence avatar in avatars)
8815 {
8816 remaining = GetPrimParams(avatar, rules, ref res);
8817 }
8818
8819 if ((object)remaining != null && remaining.Length > 0)
8820 {
8821 linknumber = remaining.GetLSLIntegerItem(0);
8822 rules = remaining.GetSublist(1, -1);
8823 }
8824 else
8825 break;
8046 } 8826 }
8047 8827
8048 return res; 8828 return res;
@@ -8087,13 +8867,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8087 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8867 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8088 part.AbsolutePosition.Y, 8868 part.AbsolutePosition.Y,
8089 part.AbsolutePosition.Z); 8869 part.AbsolutePosition.Z);
8090 // For some reason, the part.AbsolutePosition.* values do not change if the
8091 // linkset is rotated; they always reflect the child prim's world position
8092 // as though the linkset is unrotated. This is incompatible behavior with SL's
8093 // implementation, so will break scripts imported from there (not to mention it
8094 // makes it more difficult to determine a child prim's actual inworld position).
8095 if (part.ParentID != 0)
8096 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8097 res.Add(v); 8870 res.Add(v);
8098 break; 8871 break;
8099 8872
@@ -8265,30 +9038,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8265 if (remain < 1) 9038 if (remain < 1)
8266 return null; 9039 return null;
8267 9040
8268 face=(int)rules.GetLSLIntegerItem(idx++); 9041 face = (int)rules.GetLSLIntegerItem(idx++);
8269 9042
8270 tex = part.Shape.Textures; 9043 tex = part.Shape.Textures;
9044 int shiny;
8271 if (face == ScriptBaseClass.ALL_SIDES) 9045 if (face == ScriptBaseClass.ALL_SIDES)
8272 { 9046 {
8273 for (face = 0; face < GetNumberOfSides(part); face++) 9047 for (face = 0; face < GetNumberOfSides(part); face++)
8274 { 9048 {
8275 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9049 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8276 // Convert Shininess to PRIM_SHINY_* 9050 if (shinyness == Shininess.High)
8277 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9051 {
8278 // PRIM_BUMP_* 9052 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8279 res.Add(new LSL_Integer((int)texface.Bump)); 9053 }
9054 else if (shinyness == Shininess.Medium)
9055 {
9056 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9057 }
9058 else if (shinyness == Shininess.Low)
9059 {
9060 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9061 }
9062 else
9063 {
9064 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9065 }
9066 res.Add(new LSL_Integer(shiny));
9067 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8280 } 9068 }
8281 } 9069 }
8282 else 9070 else
8283 { 9071 {
8284 if (face >= 0 && face < GetNumberOfSides(part)) 9072 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9073 if (shinyness == Shininess.High)
8285 { 9074 {
8286 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9075 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8287 // Convert Shininess to PRIM_SHINY_*
8288 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8289 // PRIM_BUMP_*
8290 res.Add(new LSL_Integer((int)texface.Bump));
8291 } 9076 }
9077 else if (shinyness == Shininess.Medium)
9078 {
9079 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9080 }
9081 else if (shinyness == Shininess.Low)
9082 {
9083 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9084 }
9085 else
9086 {
9087 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9088 }
9089 res.Add(new LSL_Integer(shiny));
9090 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8292 } 9091 }
8293 break; 9092 break;
8294 9093
@@ -8296,24 +9095,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8296 if (remain < 1) 9095 if (remain < 1)
8297 return null; 9096 return null;
8298 9097
8299 face=(int)rules.GetLSLIntegerItem(idx++); 9098 face = (int)rules.GetLSLIntegerItem(idx++);
8300 9099
8301 tex = part.Shape.Textures; 9100 tex = part.Shape.Textures;
9101 int fullbright;
8302 if (face == ScriptBaseClass.ALL_SIDES) 9102 if (face == ScriptBaseClass.ALL_SIDES)
8303 { 9103 {
8304 for (face = 0; face < GetNumberOfSides(part); face++) 9104 for (face = 0; face < GetNumberOfSides(part); face++)
8305 { 9105 {
8306 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9106 if (tex.GetFace((uint)face).Fullbright == true)
8307 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9107 {
9108 fullbright = ScriptBaseClass.TRUE;
9109 }
9110 else
9111 {
9112 fullbright = ScriptBaseClass.FALSE;
9113 }
9114 res.Add(new LSL_Integer(fullbright));
8308 } 9115 }
8309 } 9116 }
8310 else 9117 else
8311 { 9118 {
8312 if (face >= 0 && face < GetNumberOfSides(part)) 9119 if (tex.GetFace((uint)face).Fullbright == true)
8313 { 9120 {
8314 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9121 fullbright = ScriptBaseClass.TRUE;
8315 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9122 }
9123 else
9124 {
9125 fullbright = ScriptBaseClass.FALSE;
8316 } 9126 }
9127 res.Add(new LSL_Integer(fullbright));
8317 } 9128 }
8318 break; 9129 break;
8319 9130
@@ -8335,27 +9146,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8335 break; 9146 break;
8336 9147
8337 case (int)ScriptBaseClass.PRIM_TEXGEN: 9148 case (int)ScriptBaseClass.PRIM_TEXGEN:
9149 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8338 if (remain < 1) 9150 if (remain < 1)
8339 return null; 9151 return null;
8340 9152
8341 face=(int)rules.GetLSLIntegerItem(idx++); 9153 face = (int)rules.GetLSLIntegerItem(idx++);
8342 9154
8343 tex = part.Shape.Textures; 9155 tex = part.Shape.Textures;
8344 if (face == ScriptBaseClass.ALL_SIDES) 9156 if (face == ScriptBaseClass.ALL_SIDES)
8345 { 9157 {
8346 for (face = 0; face < GetNumberOfSides(part); face++) 9158 for (face = 0; face < GetNumberOfSides(part); face++)
8347 { 9159 {
8348 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9160 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8349 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9161 {
8350 res.Add(new LSL_Integer((uint)texgen >> 1)); 9162 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9163 }
9164 else
9165 {
9166 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9167 }
8351 } 9168 }
8352 } 9169 }
8353 else 9170 else
8354 { 9171 {
8355 if (face >= 0 && face < GetNumberOfSides(part)) 9172 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9173 {
9174 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9175 }
9176 else
8356 { 9177 {
8357 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9178 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8358 res.Add(new LSL_Integer((uint)texgen >> 1));
8359 } 9179 }
8360 } 9180 }
8361 break; 9181 break;
@@ -8379,24 +9199,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8379 if (remain < 1) 9199 if (remain < 1)
8380 return null; 9200 return null;
8381 9201
8382 face=(int)rules.GetLSLIntegerItem(idx++); 9202 face = (int)rules.GetLSLIntegerItem(idx++);
8383 9203
8384 tex = part.Shape.Textures; 9204 tex = part.Shape.Textures;
9205 float primglow;
8385 if (face == ScriptBaseClass.ALL_SIDES) 9206 if (face == ScriptBaseClass.ALL_SIDES)
8386 { 9207 {
8387 for (face = 0; face < GetNumberOfSides(part); face++) 9208 for (face = 0; face < GetNumberOfSides(part); face++)
8388 { 9209 {
8389 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9210 primglow = tex.GetFace((uint)face).Glow;
8390 res.Add(new LSL_Float(texface.Glow)); 9211 res.Add(new LSL_Float(primglow));
8391 } 9212 }
8392 } 9213 }
8393 else 9214 else
8394 { 9215 {
8395 if (face >= 0 && face < GetNumberOfSides(part)) 9216 primglow = tex.GetFace((uint)face).Glow;
8396 { 9217 res.Add(new LSL_Float(primglow));
8397 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8398 res.Add(new LSL_Float(texface.Glow));
8399 }
8400 } 9218 }
8401 break; 9219 break;
8402 9220
@@ -8408,15 +9226,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8408 textColor.B)); 9226 textColor.B));
8409 res.Add(new LSL_Float(textColor.A)); 9227 res.Add(new LSL_Float(textColor.A));
8410 break; 9228 break;
9229
8411 case (int)ScriptBaseClass.PRIM_NAME: 9230 case (int)ScriptBaseClass.PRIM_NAME:
8412 res.Add(new LSL_String(part.Name)); 9231 res.Add(new LSL_String(part.Name));
8413 break; 9232 break;
9233
8414 case (int)ScriptBaseClass.PRIM_DESC: 9234 case (int)ScriptBaseClass.PRIM_DESC:
8415 res.Add(new LSL_String(part.Description)); 9235 res.Add(new LSL_String(part.Description));
8416 break; 9236 break;
9237
8417 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9238 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8418 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9239 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8419 break; 9240 break;
9241
8420 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9242 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8421 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9243 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8422 break; 9244 break;
@@ -9027,8 +9849,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9027 // The function returns an ordered list 9849 // The function returns an ordered list
9028 // representing the tokens found in the supplied 9850 // representing the tokens found in the supplied
9029 // sources string. If two successive tokenizers 9851 // sources string. If two successive tokenizers
9030 // are encountered, then a NULL entry is added 9852 // are encountered, then a null-string entry is
9031 // to the list. 9853 // added to the list.
9032 // 9854 //
9033 // It is a precondition that the source and 9855 // It is a precondition that the source and
9034 // toekizer lisst are non-null. If they are null, 9856 // toekizer lisst are non-null. If they are null,
@@ -9036,7 +9858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9036 // while their lengths are being determined. 9858 // while their lengths are being determined.
9037 // 9859 //
9038 // A small amount of working memoryis required 9860 // A small amount of working memoryis required
9039 // of approximately 8*#tokenizers. 9861 // of approximately 8*#tokenizers + 8*srcstrlen.
9040 // 9862 //
9041 // There are many ways in which this function 9863 // There are many ways in which this function
9042 // can be implemented, this implementation is 9864 // can be implemented, this implementation is
@@ -9052,155 +9874,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 // and eliminates redundant tokenizers as soon 9874 // and eliminates redundant tokenizers as soon
9053 // as is possible. 9875 // as is possible.
9054 // 9876 //
9055 // The implementation tries to avoid any copying 9877 // The implementation tries to minimize temporary
9056 // of arrays or other objects. 9878 // garbage generation.
9057 // </remarks> 9879 // </remarks>
9058 9880
9059 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9881 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9060 { 9882 {
9061 int beginning = 0; 9883 return ParseString2List(src, separators, spacers, true);
9062 int srclen = src.Length; 9884 }
9063 int seplen = separators.Length;
9064 object[] separray = separators.Data;
9065 int spclen = spacers.Length;
9066 object[] spcarray = spacers.Data;
9067 int mlen = seplen+spclen;
9068
9069 int[] offset = new int[mlen+1];
9070 bool[] active = new bool[mlen];
9071
9072 int best;
9073 int j;
9074
9075 // Initial capacity reduces resize cost
9076 9885
9077 LSL_List tokens = new LSL_List(); 9886 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9887 {
9888 int srclen = src.Length;
9889 int seplen = separators.Length;
9890 object[] separray = separators.Data;
9891 int spclen = spacers.Length;
9892 object[] spcarray = spacers.Data;
9893 int dellen = 0;
9894 string[] delarray = new string[seplen+spclen];
9078 9895
9079 // All entries are initially valid 9896 int outlen = 0;
9897 string[] outarray = new string[srclen*2+1];
9080 9898
9081 for (int i = 0; i < mlen; i++) 9899 int i, j;
9082 active[i] = true; 9900 string d;
9083 9901
9084 offset[mlen] = srclen; 9902 m_host.AddScriptLPS(1);
9085 9903
9086 while (beginning < srclen) 9904 /*
9905 * Convert separator and spacer lists to C# strings.
9906 * Also filter out null strings so we don't hang.
9907 */
9908 for (i = 0; i < seplen; i ++)
9087 { 9909 {
9910 d = separray[i].ToString();
9911 if (d.Length > 0)
9912 {
9913 delarray[dellen++] = d;
9914 }
9915 }
9916 seplen = dellen;
9088 9917
9089 best = mlen; // as bad as it gets 9918 for (i = 0; i < spclen; i ++)
9919 {
9920 d = spcarray[i].ToString();
9921 if (d.Length > 0)
9922 {
9923 delarray[dellen++] = d;
9924 }
9925 }
9090 9926
9091 // Scan for separators 9927 /*
9928 * Scan through source string from beginning to end.
9929 */
9930 for (i = 0;;)
9931 {
9092 9932
9093 for (j = 0; j < seplen; j++) 9933 /*
9934 * Find earliest delimeter in src starting at i (if any).
9935 */
9936 int earliestDel = -1;
9937 int earliestSrc = srclen;
9938 string earliestStr = null;
9939 for (j = 0; j < dellen; j ++)
9094 { 9940 {
9095 if (separray[j].ToString() == String.Empty) 9941 d = delarray[j];
9096 active[j] = false; 9942 if (d != null)
9097
9098 if (active[j])
9099 { 9943 {
9100 // scan all of the markers 9944 int index = src.IndexOf(d, i);
9101 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9945 if (index < 0)
9102 { 9946 {
9103 // not present at all 9947 delarray[j] = null; // delim nowhere in src, don't check it anymore
9104 active[j] = false;
9105 } 9948 }
9106 else 9949 else if (index < earliestSrc)
9107 { 9950 {
9108 // present and correct 9951 earliestSrc = index; // where delimeter starts in source string
9109 if (offset[j] < offset[best]) 9952 earliestDel = j; // where delimeter is in delarray[]
9110 { 9953 earliestStr = d; // the delimeter string from delarray[]
9111 // closest so far 9954 if (index == i) break; // can't do any better than found at beg of string
9112 best = j;
9113 if (offset[best] == beginning)
9114 break;
9115 }
9116 } 9955 }
9117 } 9956 }
9118 } 9957 }
9119 9958
9120 // Scan for spacers 9959 /*
9121 9960 * Output source string starting at i through start of earliest delimeter.
9122 if (offset[best] != beginning) 9961 */
9962 if (keepNulls || (earliestSrc > i))
9123 { 9963 {
9124 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9964 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9125 {
9126 if (spcarray[j-seplen].ToString() == String.Empty)
9127 active[j] = false;
9128
9129 if (active[j])
9130 {
9131 // scan all of the markers
9132 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9133 {
9134 // not present at all
9135 active[j] = false;
9136 }
9137 else
9138 {
9139 // present and correct
9140 if (offset[j] < offset[best])
9141 {
9142 // closest so far
9143 best = j;
9144 }
9145 }
9146 }
9147 }
9148 } 9965 }
9149 9966
9150 // This is the normal exit from the scanning loop 9967 /*
9968 * If no delimeter found at or after i, we're done scanning.
9969 */
9970 if (earliestDel < 0) break;
9151 9971
9152 if (best == mlen) 9972 /*
9973 * If delimeter was a spacer, output the spacer.
9974 */
9975 if (earliestDel >= seplen)
9153 { 9976 {
9154 // no markers were found on this pass 9977 outarray[outlen++] = earliestStr;
9155 // so we're pretty much done
9156 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9157 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9158 break;
9159 } 9978 }
9160 9979
9161 // Otherwise we just add the newly delimited token 9980 /*
9162 // and recalculate where the search should continue. 9981 * Look at rest of src string following delimeter.
9163 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9982 */
9164 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9983 i = earliestSrc + earliestStr.Length;
9165
9166 if (best < seplen)
9167 {
9168 beginning = offset[best] + (separray[best].ToString()).Length;
9169 }
9170 else
9171 {
9172 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9173 string str = spcarray[best - seplen].ToString();
9174 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9175 tokens.Add(new LSL_String(str));
9176 }
9177 } 9984 }
9178 9985
9179 // This an awkward an not very intuitive boundary case. If the 9986 /*
9180 // last substring is a tokenizer, then there is an implied trailing 9987 * Make up an exact-sized output array suitable for an LSL_List object.
9181 // null list entry. Hopefully the single comparison will not be too 9988 */
9182 // arduous. Alternatively the 'break' could be replced with a return 9989 object[] outlist = new object[outlen];
9183 // but that's shabby programming. 9990 for (i = 0; i < outlen; i ++)
9184
9185 if ((beginning == srclen) && (keepNulls))
9186 { 9991 {
9187 if (srclen != 0) 9992 outlist[i] = new LSL_String(outarray[i]);
9188 tokens.Add(new LSL_String(""));
9189 } 9993 }
9190 9994 return new LSL_List(outlist);
9191 return tokens;
9192 }
9193
9194 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9195 {
9196 m_host.AddScriptLPS(1);
9197 return this.ParseString(src, separators, spacers, false);
9198 }
9199
9200 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9201 {
9202 m_host.AddScriptLPS(1);
9203 return this.ParseString(src, separators, spacers, true);
9204 } 9995 }
9205 9996
9206 public LSL_Integer llGetObjectPermMask(int mask) 9997 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9295,6 +10086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9295 case 4: 10086 case 4:
9296 return (int)item.NextPermissions; 10087 return (int)item.NextPermissions;
9297 } 10088 }
10089 m_host.TaskInventory.LockItemsForRead(false);
9298 10090
9299 return -1; 10091 return -1;
9300 } 10092 }
@@ -9497,31 +10289,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9497 UUID key = new UUID(); 10289 UUID key = new UUID();
9498 if (UUID.TryParse(id, out key)) 10290 if (UUID.TryParse(id, out key))
9499 { 10291 {
9500 try 10292 // return total object mass
9501 { 10293 SceneObjectPart part = World.GetSceneObjectPart(key);
9502 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10294 if (part != null)
9503 if (obj != null) 10295 return part.ParentGroup.GetMass();
9504 return (double)obj.GetMass(); 10296
9505 // the object is null so the key is for an avatar 10297 // the object is null so the key is for an avatar
9506 ScenePresence avatar = World.GetScenePresence(key); 10298 ScenePresence avatar = World.GetScenePresence(key);
9507 if (avatar != null) 10299 if (avatar != null)
9508 if (avatar.IsChildAgent)
9509 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9510 // child agents have a mass of 1.0
9511 return 1;
9512 else
9513 return (double)avatar.GetMass();
9514 }
9515 catch (KeyNotFoundException)
9516 { 10300 {
9517 return 0; // The Object/Agent not in the region so just return zero 10301 if (avatar.IsChildAgent)
10302 {
10303 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10304 // child agents have a mass of 1.0
10305 return 1;
10306 }
10307 else
10308 {
10309 return (double)avatar.GetMass();
10310 }
9518 } 10311 }
9519 } 10312 }
9520 return 0; 10313 return 0;
9521 } 10314 }
9522 10315
9523 /// <summary> 10316 /// <summary>
9524 /// illListReplaceList removes the sub-list defined by the inclusive indices 10317 /// llListReplaceList removes the sub-list defined by the inclusive indices
9525 /// start and end and inserts the src list in its place. The inclusive 10318 /// start and end and inserts the src list in its place. The inclusive
9526 /// nature of the indices means that at least one element must be deleted 10319 /// nature of the indices means that at least one element must be deleted
9527 /// if the indices are within the bounds of the existing list. I.e. 2,2 10320 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9578,16 +10371,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9578 // based upon end. Note that if end exceeds the upper 10371 // based upon end. Note that if end exceeds the upper
9579 // bound in this case, the entire destination list 10372 // bound in this case, the entire destination list
9580 // is removed. 10373 // is removed.
9581 else 10374 else if (start == 0)
9582 { 10375 {
9583 if (end + 1 < dest.Length) 10376 if (end + 1 < dest.Length)
9584 {
9585 return src + dest.GetSublist(end + 1, -1); 10377 return src + dest.GetSublist(end + 1, -1);
9586 }
9587 else 10378 else
9588 {
9589 return src; 10379 return src;
9590 } 10380 }
10381 else // Start < 0
10382 {
10383 if (end + 1 < dest.Length)
10384 return dest.GetSublist(end + 1, -1);
10385 else
10386 return new LSL_List();
9591 } 10387 }
9592 } 10388 }
9593 // Finally, if start > end, we strip away a prefix and 10389 // Finally, if start > end, we strip away a prefix and
@@ -9638,17 +10434,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9638 int width = 0; 10434 int width = 0;
9639 int height = 0; 10435 int height = 0;
9640 10436
9641 ParcelMediaCommandEnum? commandToSend = null; 10437 uint commandToSend = 0;
9642 float time = 0.0f; // default is from start 10438 float time = 0.0f; // default is from start
9643 10439
9644 ScenePresence presence = null; 10440 ScenePresence presence = null;
9645 10441
9646 for (int i = 0; i < commandList.Data.Length; i++) 10442 for (int i = 0; i < commandList.Data.Length; i++)
9647 { 10443 {
9648 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10444 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9649 switch (command) 10445 switch (command)
9650 { 10446 {
9651 case ParcelMediaCommandEnum.Agent: 10447 case (uint)ParcelMediaCommandEnum.Agent:
9652 // we send only to one agent 10448 // we send only to one agent
9653 if ((i + 1) < commandList.Length) 10449 if ((i + 1) < commandList.Length)
9654 { 10450 {
@@ -9665,25 +10461,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9665 } 10461 }
9666 break; 10462 break;
9667 10463
9668 case ParcelMediaCommandEnum.Loop: 10464 case (uint)ParcelMediaCommandEnum.Loop:
9669 loop = 1; 10465 loop = 1;
9670 commandToSend = command; 10466 commandToSend = command;
9671 update = true; //need to send the media update packet to set looping 10467 update = true; //need to send the media update packet to set looping
9672 break; 10468 break;
9673 10469
9674 case ParcelMediaCommandEnum.Play: 10470 case (uint)ParcelMediaCommandEnum.Play:
9675 loop = 0; 10471 loop = 0;
9676 commandToSend = command; 10472 commandToSend = command;
9677 update = true; //need to send the media update packet to make sure it doesn't loop 10473 update = true; //need to send the media update packet to make sure it doesn't loop
9678 break; 10474 break;
9679 10475
9680 case ParcelMediaCommandEnum.Pause: 10476 case (uint)ParcelMediaCommandEnum.Pause:
9681 case ParcelMediaCommandEnum.Stop: 10477 case (uint)ParcelMediaCommandEnum.Stop:
9682 case ParcelMediaCommandEnum.Unload: 10478 case (uint)ParcelMediaCommandEnum.Unload:
9683 commandToSend = command; 10479 commandToSend = command;
9684 break; 10480 break;
9685 10481
9686 case ParcelMediaCommandEnum.Url: 10482 case (uint)ParcelMediaCommandEnum.Url:
9687 if ((i + 1) < commandList.Length) 10483 if ((i + 1) < commandList.Length)
9688 { 10484 {
9689 if (commandList.Data[i + 1] is LSL_String) 10485 if (commandList.Data[i + 1] is LSL_String)
@@ -9696,7 +10492,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9696 } 10492 }
9697 break; 10493 break;
9698 10494
9699 case ParcelMediaCommandEnum.Texture: 10495 case (uint)ParcelMediaCommandEnum.Texture:
9700 if ((i + 1) < commandList.Length) 10496 if ((i + 1) < commandList.Length)
9701 { 10497 {
9702 if (commandList.Data[i + 1] is LSL_String) 10498 if (commandList.Data[i + 1] is LSL_String)
@@ -9709,7 +10505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9709 } 10505 }
9710 break; 10506 break;
9711 10507
9712 case ParcelMediaCommandEnum.Time: 10508 case (uint)ParcelMediaCommandEnum.Time:
9713 if ((i + 1) < commandList.Length) 10509 if ((i + 1) < commandList.Length)
9714 { 10510 {
9715 if (commandList.Data[i + 1] is LSL_Float) 10511 if (commandList.Data[i + 1] is LSL_Float)
@@ -9721,7 +10517,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9721 } 10517 }
9722 break; 10518 break;
9723 10519
9724 case ParcelMediaCommandEnum.AutoAlign: 10520 case (uint)ParcelMediaCommandEnum.AutoAlign:
9725 if ((i + 1) < commandList.Length) 10521 if ((i + 1) < commandList.Length)
9726 { 10522 {
9727 if (commandList.Data[i + 1] is LSL_Integer) 10523 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9735,7 +10531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9735 } 10531 }
9736 break; 10532 break;
9737 10533
9738 case ParcelMediaCommandEnum.Type: 10534 case (uint)ParcelMediaCommandEnum.Type:
9739 if ((i + 1) < commandList.Length) 10535 if ((i + 1) < commandList.Length)
9740 { 10536 {
9741 if (commandList.Data[i + 1] is LSL_String) 10537 if (commandList.Data[i + 1] is LSL_String)
@@ -9748,7 +10544,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9748 } 10544 }
9749 break; 10545 break;
9750 10546
9751 case ParcelMediaCommandEnum.Desc: 10547 case (uint)ParcelMediaCommandEnum.Desc:
9752 if ((i + 1) < commandList.Length) 10548 if ((i + 1) < commandList.Length)
9753 { 10549 {
9754 if (commandList.Data[i + 1] is LSL_String) 10550 if (commandList.Data[i + 1] is LSL_String)
@@ -9761,7 +10557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9761 } 10557 }
9762 break; 10558 break;
9763 10559
9764 case ParcelMediaCommandEnum.Size: 10560 case (uint)ParcelMediaCommandEnum.Size:
9765 if ((i + 2) < commandList.Length) 10561 if ((i + 2) < commandList.Length)
9766 { 10562 {
9767 if (commandList.Data[i + 1] is LSL_Integer) 10563 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9831,7 +10627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9831 } 10627 }
9832 } 10628 }
9833 10629
9834 if (commandToSend != null) 10630 if (commandToSend != 0)
9835 { 10631 {
9836 // the commandList contained a start/stop/... command, too 10632 // the commandList contained a start/stop/... command, too
9837 if (presence == null) 10633 if (presence == null)
@@ -9868,7 +10664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9868 10664
9869 if (aList.Data[i] != null) 10665 if (aList.Data[i] != null)
9870 { 10666 {
9871 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10667 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9872 { 10668 {
9873 case ParcelMediaCommandEnum.Url: 10669 case ParcelMediaCommandEnum.Url:
9874 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10670 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9925,15 +10721,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9925 10721
9926 if (quick_pay_buttons.Data.Length < 4) 10722 if (quick_pay_buttons.Data.Length < 4)
9927 { 10723 {
9928 LSLError("List must have at least 4 elements"); 10724 int x;
9929 return; 10725 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10726 {
10727 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10728 }
9930 } 10729 }
9931 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10730 int[] nPrice = new int[5];
9932 10731 nPrice[0] = price;
9933 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10732 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9934 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10733 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9935 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10734 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9936 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10735 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10736 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9937 m_host.ParentGroup.HasGroupChanged = true; 10737 m_host.ParentGroup.HasGroupChanged = true;
9938 } 10738 }
9939 10739
@@ -9950,7 +10750,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9950 return new LSL_Vector(); 10750 return new LSL_Vector();
9951 } 10751 }
9952 10752
9953 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10753// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10754 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9954 if (presence != null) 10755 if (presence != null)
9955 { 10756 {
9956 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10757 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9972,7 +10773,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9972 return new LSL_Rotation(); 10773 return new LSL_Rotation();
9973 } 10774 }
9974 10775
9975 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10776// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10777 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9976 if (presence != null) 10778 if (presence != null)
9977 { 10779 {
9978 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10780 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10032,14 +10834,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10032 { 10834 {
10033 m_host.AddScriptLPS(1); 10835 m_host.AddScriptLPS(1);
10034 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10836 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10035 if (detectedParams == null) return; // only works on the first detected avatar 10837 if (detectedParams == null)
10036 10838 {
10839 if (m_host.ParentGroup.IsAttachment == true)
10840 {
10841 detectedParams = new DetectParams();
10842 detectedParams.Key = m_host.OwnerID;
10843 }
10844 else
10845 {
10846 return;
10847 }
10848 }
10849
10037 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10850 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10038 if (avatar != null) 10851 if (avatar != null)
10039 { 10852 {
10040 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10853 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10041 simname, pos, lookAt); 10854 simname, pos, lookAt);
10042 } 10855 }
10856
10043 ScriptSleep(1000); 10857 ScriptSleep(1000);
10044 } 10858 }
10045 10859
@@ -10163,12 +10977,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10163 10977
10164 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10978 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10165 object[] data = rules.Data; 10979 object[] data = rules.Data;
10166 for (int i = 0; i < data.Length; ++i) { 10980 for (int i = 0; i < data.Length; ++i)
10981 {
10167 int type = Convert.ToInt32(data[i++].ToString()); 10982 int type = Convert.ToInt32(data[i++].ToString());
10168 if (i >= data.Length) break; // odd number of entries => ignore the last 10983 if (i >= data.Length) break; // odd number of entries => ignore the last
10169 10984
10170 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10985 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10171 switch (type) { 10986 switch (type)
10987 {
10172 case ScriptBaseClass.CAMERA_FOCUS: 10988 case ScriptBaseClass.CAMERA_FOCUS:
10173 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10989 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10174 case ScriptBaseClass.CAMERA_POSITION: 10990 case ScriptBaseClass.CAMERA_POSITION:
@@ -10273,19 +11089,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10273 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11089 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10274 { 11090 {
10275 m_host.AddScriptLPS(1); 11091 m_host.AddScriptLPS(1);
10276 string ret = String.Empty; 11092
10277 string src1 = llBase64ToString(str1); 11093 if (str1 == String.Empty)
10278 string src2 = llBase64ToString(str2); 11094 return String.Empty;
10279 int c = 0; 11095 if (str2 == String.Empty)
10280 for (int i = 0; i < src1.Length; i++) 11096 return str1;
11097
11098 int len = str2.Length;
11099 if ((len % 4) != 0) // LL is EVIL!!!!
10281 { 11100 {
10282 ret += (char) (src1[i] ^ src2[c]); 11101 while (str2.EndsWith("="))
11102 str2 = str2.Substring(0, str2.Length - 1);
11103
11104 len = str2.Length;
11105 int mod = len % 4;
11106
11107 if (mod == 1)
11108 str2 = str2.Substring(0, str2.Length - 1);
11109 else if (mod == 2)
11110 str2 += "==";
11111 else if (mod == 3)
11112 str2 += "=";
11113 }
10283 11114
10284 c++; 11115 byte[] data1;
10285 if (c >= src2.Length) 11116 byte[] data2;
10286 c = 0; 11117 try
11118 {
11119 data1 = Convert.FromBase64String(str1);
11120 data2 = Convert.FromBase64String(str2);
10287 } 11121 }
10288 return llStringToBase64(ret); 11122 catch (Exception)
11123 {
11124 return new LSL_String(String.Empty);
11125 }
11126
11127 byte[] d2 = new Byte[data1.Length];
11128 int pos = 0;
11129
11130 if (data1.Length <= data2.Length)
11131 {
11132 Array.Copy(data2, 0, d2, 0, data1.Length);
11133 }
11134 else
11135 {
11136 while (pos < data1.Length)
11137 {
11138 len = data1.Length - pos;
11139 if (len > data2.Length)
11140 len = data2.Length;
11141
11142 Array.Copy(data2, 0, d2, pos, len);
11143 pos += len;
11144 }
11145 }
11146
11147 for (pos = 0 ; pos < data1.Length ; pos++ )
11148 data1[pos] ^= d2[pos];
11149
11150 return Convert.ToBase64String(data1);
10289 } 11151 }
10290 11152
10291 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11153 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10338,16 +11200,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10338 if (userAgent != null) 11200 if (userAgent != null)
10339 httpHeaders["User-Agent"] = userAgent; 11201 httpHeaders["User-Agent"] = userAgent;
10340 11202
11203 // See if the URL contains any header hacks
11204 string[] urlParts = url.Split(new char[] {'\n'});
11205 if (urlParts.Length > 1)
11206 {
11207 // Iterate the passed headers and parse them
11208 for (int i = 1 ; i < urlParts.Length ; i++ )
11209 {
11210 // The rest of those would be added to the body in SL.
11211 // Let's not do that.
11212 if (urlParts[i] == String.Empty)
11213 break;
11214
11215 // See if this could be a valid header
11216 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11217 if (headerParts.Length != 2)
11218 continue;
11219
11220 string headerName = headerParts[0].Trim();
11221 string headerValue = headerParts[1].Trim();
11222
11223 // Filter out headers that could be used to abuse
11224 // another system or cloak the request
11225 if (headerName.ToLower() == "x-secondlife-shard" ||
11226 headerName.ToLower() == "x-secondlife-object-name" ||
11227 headerName.ToLower() == "x-secondlife-object-key" ||
11228 headerName.ToLower() == "x-secondlife-region" ||
11229 headerName.ToLower() == "x-secondlife-local-position" ||
11230 headerName.ToLower() == "x-secondlife-local-velocity" ||
11231 headerName.ToLower() == "x-secondlife-local-rotation" ||
11232 headerName.ToLower() == "x-secondlife-owner-name" ||
11233 headerName.ToLower() == "x-secondlife-owner-key" ||
11234 headerName.ToLower() == "connection" ||
11235 headerName.ToLower() == "content-length" ||
11236 headerName.ToLower() == "from" ||
11237 headerName.ToLower() == "host" ||
11238 headerName.ToLower() == "proxy-authorization" ||
11239 headerName.ToLower() == "referer" ||
11240 headerName.ToLower() == "trailer" ||
11241 headerName.ToLower() == "transfer-encoding" ||
11242 headerName.ToLower() == "via" ||
11243 headerName.ToLower() == "authorization")
11244 continue;
11245
11246 httpHeaders[headerName] = headerValue;
11247 }
11248
11249 // Finally, strip any protocol specifier from the URL
11250 url = urlParts[0].Trim();
11251 int idx = url.IndexOf(" HTTP/");
11252 if (idx != -1)
11253 url = url.Substring(0, idx);
11254 }
11255
10341 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11256 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10342 Regex r = new Regex(authregex); 11257 Regex r = new Regex(authregex);
10343 int[] gnums = r.GetGroupNumbers(); 11258 int[] gnums = r.GetGroupNumbers();
10344 Match m = r.Match(url); 11259 Match m = r.Match(url);
10345 if (m.Success) { 11260 if (m.Success)
10346 for (int i = 1; i < gnums.Length; i++) { 11261 {
11262 for (int i = 1; i < gnums.Length; i++)
11263 {
10347 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11264 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10348 //CaptureCollection cc = g.Captures; 11265 //CaptureCollection cc = g.Captures;
10349 } 11266 }
10350 if (m.Groups.Count == 5) { 11267 if (m.Groups.Count == 5)
11268 {
10351 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11269 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10352 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11270 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10353 } 11271 }
@@ -10550,6 +11468,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10550 11468
10551 LSL_List ret = new LSL_List(); 11469 LSL_List ret = new LSL_List();
10552 UUID key = new UUID(); 11470 UUID key = new UUID();
11471
11472
10553 if (UUID.TryParse(id, out key)) 11473 if (UUID.TryParse(id, out key))
10554 { 11474 {
10555 ScenePresence av = World.GetScenePresence(key); 11475 ScenePresence av = World.GetScenePresence(key);
@@ -10567,13 +11487,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10567 ret.Add(new LSL_String("")); 11487 ret.Add(new LSL_String(""));
10568 break; 11488 break;
10569 case ScriptBaseClass.OBJECT_POS: 11489 case ScriptBaseClass.OBJECT_POS:
10570 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11490 Vector3 avpos;
11491
11492 if (av.ParentID != 0 && av.ParentPart != null)
11493 {
11494 avpos = av.OffsetPosition;
11495
11496 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11497 avpos -= sitOffset;
11498
11499 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11500 }
11501 else
11502 avpos = av.AbsolutePosition;
11503
11504 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10571 break; 11505 break;
10572 case ScriptBaseClass.OBJECT_ROT: 11506 case ScriptBaseClass.OBJECT_ROT:
10573 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11507 Quaternion avrot = av.Rotation;
11508 if (av.ParentID != 0 && av.ParentPart != null)
11509 {
11510 avrot = av.ParentPart.GetWorldRotation() * avrot;
11511 }
11512 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10574 break; 11513 break;
10575 case ScriptBaseClass.OBJECT_VELOCITY: 11514 case ScriptBaseClass.OBJECT_VELOCITY:
10576 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11515 Vector3 avvel = av.Velocity;
11516 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10577 break; 11517 break;
10578 case ScriptBaseClass.OBJECT_OWNER: 11518 case ScriptBaseClass.OBJECT_OWNER:
10579 ret.Add(new LSL_String(id)); 11519 ret.Add(new LSL_String(id));
@@ -10658,11 +11598,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10658 case ScriptBaseClass.OBJECT_NAME: 11598 case ScriptBaseClass.OBJECT_NAME:
10659 ret.Add(new LSL_String(obj.Name)); 11599 ret.Add(new LSL_String(obj.Name));
10660 break; 11600 break;
10661 case ScriptBaseClass.OBJECT_DESC: 11601 case ScriptBaseClass.OBJECT_DESC:
10662 ret.Add(new LSL_String(obj.Description)); 11602 ret.Add(new LSL_String(obj.Description));
10663 break; 11603 break;
10664 case ScriptBaseClass.OBJECT_POS: 11604 case ScriptBaseClass.OBJECT_POS:
10665 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11605 Vector3 opos = obj.AbsolutePosition;
11606 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10666 break; 11607 break;
10667 case ScriptBaseClass.OBJECT_ROT: 11608 case ScriptBaseClass.OBJECT_ROT:
10668 { 11609 {
@@ -10712,9 +11653,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10712 // The value returned in SL for normal prims is prim count 11653 // The value returned in SL for normal prims is prim count
10713 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11654 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10714 break; 11655 break;
10715 // The following 3 costs I have intentionaly coded to return zero. They are part of 11656
10716 // "Land Impact" calculations. These calculations are probably not applicable 11657 // costs below may need to be diferent for root parts, need to check
10717 // to OpenSim and are not yet complete in SL
10718 case ScriptBaseClass.OBJECT_SERVER_COST: 11658 case ScriptBaseClass.OBJECT_SERVER_COST:
10719 // The linden calculation is here 11659 // The linden calculation is here
10720 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11660 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10722,16 +11662,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10722 ret.Add(new LSL_Float(0)); 11662 ret.Add(new LSL_Float(0));
10723 break; 11663 break;
10724 case ScriptBaseClass.OBJECT_STREAMING_COST: 11664 case ScriptBaseClass.OBJECT_STREAMING_COST:
10725 // The linden calculation is here 11665 // The value returned in SL for normal prims is prim count * 0.06
10726 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11666 ret.Add(new LSL_Float(obj.StreamingCost));
10727 // The value returned in SL for normal prims looks like the prim count * 0.06
10728 ret.Add(new LSL_Float(0));
10729 break; 11667 break;
10730 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11668 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10731 // The linden calculation is here 11669 // The value returned in SL for normal prims is prim count
10732 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11670 ret.Add(new LSL_Float(obj.PhysicsCost));
10733 // The value returned in SL for normal prims looks like the prim count
10734 ret.Add(new LSL_Float(0));
10735 break; 11671 break;
10736 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11672 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10737 ret.Add(new LSL_Float(0)); 11673 ret.Add(new LSL_Float(0));
@@ -10988,15 +11924,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10988 return result; 11924 return result;
10989 } 11925 }
10990 11926
10991 public void print(string str) 11927 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10992 { 11928 {
10993 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11929 List<SceneObjectPart> parts = GetLinkParts(link);
10994 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11930 if (parts.Count < 1)
10995 if (ossl != null) 11931 return 0;
10996 { 11932
10997 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11933 return GetNumberOfSides(parts[0]);
10998 m_log.Info("LSL print():" + str);
10999 }
11000 } 11934 }
11001 11935
11002 private string Name2Username(string name) 11936 private string Name2Username(string name)
@@ -11041,7 +11975,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11041 11975
11042 return rq.ToString(); 11976 return rq.ToString();
11043 } 11977 }
11044 11978/*
11979 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11980 {
11981 m_SayShoutCount = 0;
11982 }
11983*/
11045 private struct Tri 11984 private struct Tri
11046 { 11985 {
11047 public Vector3 p1; 11986 public Vector3 p1;
@@ -11190,9 +12129,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11190 12129
11191 ContactResult result = new ContactResult (); 12130 ContactResult result = new ContactResult ();
11192 result.ConsumerID = group.LocalId; 12131 result.ConsumerID = group.LocalId;
11193 result.Depth = intersection.distance; 12132// result.Depth = intersection.distance;
11194 result.Normal = intersection.normal; 12133 result.Normal = intersection.normal;
11195 result.Pos = intersection.ipoint; 12134 result.Pos = intersection.ipoint;
12135 result.Depth = Vector3.Mag(rayStart - result.Pos);
11196 12136
11197 contacts.Add(result); 12137 contacts.Add(result);
11198 }); 12138 });
@@ -11325,6 +12265,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11325 12265
11326 return contacts[0]; 12266 return contacts[0];
11327 } 12267 }
12268/*
12269 // not done:
12270 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12271 {
12272 ContactResult[] contacts = null;
12273 World.ForEachSOG(delegate(SceneObjectGroup group)
12274 {
12275 if (m_host.ParentGroup == group)
12276 return;
12277
12278 if (group.IsAttachment)
12279 return;
12280
12281 if(group.RootPart.PhysActor != null)
12282 return;
12283
12284 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12285 });
12286 return contacts;
12287 }
12288*/
11328 12289
11329 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12290 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11330 { 12291 {
@@ -11448,18 +12409,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11448 } 12409 }
11449 } 12410 }
11450 12411
12412 // Double check this
11451 if (checkTerrain) 12413 if (checkTerrain)
11452 { 12414 {
11453 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12415 bool skipGroundCheck = false;
11454 if (groundContact != null) 12416
11455 results.Add((ContactResult)groundContact); 12417 foreach (ContactResult c in results)
12418 {
12419 if (c.ConsumerID == 0) // Physics gave us a ground collision
12420 skipGroundCheck = true;
12421 }
12422
12423 if (!skipGroundCheck)
12424 {
12425 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12426 if (groundContact != null)
12427 results.Add((ContactResult)groundContact);
12428 }
11456 } 12429 }
11457 12430
11458 results.Sort(delegate(ContactResult a, ContactResult b) 12431 results.Sort(delegate(ContactResult a, ContactResult b)
11459 { 12432 {
11460 return a.Depth.CompareTo(b.Depth); 12433 return a.Depth.CompareTo(b.Depth);
11461 }); 12434 });
11462 12435
11463 int values = 0; 12436 int values = 0;
11464 SceneObjectGroup thisgrp = m_host.ParentGroup; 12437 SceneObjectGroup thisgrp = m_host.ParentGroup;
11465 12438
@@ -11552,7 +12525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11552 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12525 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11553 if (!isAccount) return 0; 12526 if (!isAccount) return 0;
11554 if (estate.HasAccess(id)) return 1; 12527 if (estate.HasAccess(id)) return 1;
11555 if (estate.IsBanned(id)) 12528 if (estate.IsBanned(id, World.GetUserFlags(id)))
11556 estate.RemoveBan(id); 12529 estate.RemoveBan(id);
11557 estate.AddEstateUser(id); 12530 estate.AddEstateUser(id);
11558 break; 12531 break;
@@ -11571,14 +12544,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11571 break; 12544 break;
11572 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12545 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11573 if (!isAccount) return 0; 12546 if (!isAccount) return 0;
11574 if (estate.IsBanned(id)) return 1; 12547 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11575 EstateBan ban = new EstateBan(); 12548 EstateBan ban = new EstateBan();
11576 ban.EstateID = estate.EstateID; 12549 ban.EstateID = estate.EstateID;
11577 ban.BannedUserID = id; 12550 ban.BannedUserID = id;
11578 estate.AddBan(ban); 12551 estate.AddBan(ban);
11579 break; 12552 break;
11580 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12553 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11581 if (!isAccount || !estate.IsBanned(id)) return 0; 12554 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11582 estate.RemoveBan(id); 12555 estate.RemoveBan(id);
11583 break; 12556 break;
11584 default: return 0; 12557 default: return 0;
@@ -11607,7 +12580,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11607 return 16384; 12580 return 16384;
11608 } 12581 }
11609 12582
11610 public LSL_Integer llGetUsedMemory() 12583 public virtual LSL_Integer llGetUsedMemory()
11611 { 12584 {
11612 m_host.AddScriptLPS(1); 12585 m_host.AddScriptLPS(1);
11613 // The value returned for LSO scripts in SL 12586 // The value returned for LSO scripts in SL
@@ -11635,19 +12608,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11635 public void llSetSoundQueueing(int queue) 12608 public void llSetSoundQueueing(int queue)
11636 { 12609 {
11637 m_host.AddScriptLPS(1); 12610 m_host.AddScriptLPS(1);
11638 NotImplemented("llSetSoundQueueing");
11639 } 12611 }
11640 12612
11641 public void llCollisionSprite(string impact_sprite) 12613 public void llCollisionSprite(string impact_sprite)
11642 { 12614 {
11643 m_host.AddScriptLPS(1); 12615 m_host.AddScriptLPS(1);
11644 NotImplemented("llCollisionSprite"); 12616 // Viewer 2.0 broke this and it's likely LL has no intention
12617 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11645 } 12618 }
11646 12619
11647 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12620 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11648 { 12621 {
11649 m_host.AddScriptLPS(1); 12622 m_host.AddScriptLPS(1);
11650 NotImplemented("llGodLikeRezObject"); 12623
12624 if (!World.Permissions.IsGod(m_host.OwnerID))
12625 NotImplemented("llGodLikeRezObject");
12626
12627 AssetBase rezAsset = World.AssetService.Get(inventory);
12628 if (rezAsset == null)
12629 {
12630 llSay(0, "Asset not found");
12631 return;
12632 }
12633
12634 SceneObjectGroup group = null;
12635
12636 try
12637 {
12638 string xmlData = Utils.BytesToString(rezAsset.Data);
12639 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12640 }
12641 catch
12642 {
12643 llSay(0, "Asset not found");
12644 return;
12645 }
12646
12647 if (group == null)
12648 {
12649 llSay(0, "Asset not found");
12650 return;
12651 }
12652
12653 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12654 group.RootPart.AttachOffset = group.AbsolutePosition;
12655
12656 group.ResetIDs();
12657
12658 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12659 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12660 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12661 group.ScheduleGroupForFullUpdate();
12662
12663 // objects rezzed with this method are die_at_edge by default.
12664 group.RootPart.SetDieAtEdge(true);
12665
12666 group.ResumeScripts();
12667
12668 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12669 "object_rez", new Object[] {
12670 new LSL_String(
12671 group.RootPart.UUID.ToString()) },
12672 new DetectParams[0]));
11651 } 12673 }
11652 12674
11653 public LSL_String llTransferLindenDollars(string destination, int amount) 12675 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11699,7 +12721,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11699 } 12721 }
11700 12722
11701 bool result = money.ObjectGiveMoney( 12723 bool result = money.ObjectGiveMoney(
11702 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12724 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11703 12725
11704 if (result) 12726 if (result)
11705 { 12727 {
@@ -11724,6 +12746,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11724 } 12746 }
11725 12747
11726 #endregion 12748 #endregion
12749
12750 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12751 {
12752 SceneObjectGroup group = m_host.ParentGroup;
12753
12754 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12755 return;
12756 if (group.IsAttachment)
12757 return;
12758
12759 if (frames.Data.Length > 0) // We are getting a new motion
12760 {
12761 if (group.RootPart.KeyframeMotion != null)
12762 group.RootPart.KeyframeMotion.Delete();
12763 group.RootPart.KeyframeMotion = null;
12764
12765 int idx = 0;
12766
12767 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12768 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12769
12770 while (idx < options.Data.Length)
12771 {
12772 int option = (int)options.GetLSLIntegerItem(idx++);
12773 int remain = options.Data.Length - idx;
12774
12775 switch (option)
12776 {
12777 case ScriptBaseClass.KFM_MODE:
12778 if (remain < 1)
12779 break;
12780 int modeval = (int)options.GetLSLIntegerItem(idx++);
12781 switch(modeval)
12782 {
12783 case ScriptBaseClass.KFM_FORWARD:
12784 mode = KeyframeMotion.PlayMode.Forward;
12785 break;
12786 case ScriptBaseClass.KFM_REVERSE:
12787 mode = KeyframeMotion.PlayMode.Reverse;
12788 break;
12789 case ScriptBaseClass.KFM_LOOP:
12790 mode = KeyframeMotion.PlayMode.Loop;
12791 break;
12792 case ScriptBaseClass.KFM_PING_PONG:
12793 mode = KeyframeMotion.PlayMode.PingPong;
12794 break;
12795 }
12796 break;
12797 case ScriptBaseClass.KFM_DATA:
12798 if (remain < 1)
12799 break;
12800 int dataval = (int)options.GetLSLIntegerItem(idx++);
12801 data = (KeyframeMotion.DataFormat)dataval;
12802 break;
12803 }
12804 }
12805
12806 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12807
12808 idx = 0;
12809
12810 int elemLength = 2;
12811 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12812 elemLength = 3;
12813
12814 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12815 while (idx < frames.Data.Length)
12816 {
12817 int remain = frames.Data.Length - idx;
12818
12819 if (remain < elemLength)
12820 break;
12821
12822 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12823 frame.Position = null;
12824 frame.Rotation = null;
12825
12826 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12827 {
12828 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12829 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12830 }
12831 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12832 {
12833 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12834 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12835 q.Normalize();
12836 frame.Rotation = q;
12837 }
12838
12839 float tempf = (float)frames.GetLSLFloatItem(idx++);
12840 frame.TimeMS = (int)(tempf * 1000.0f);
12841
12842 keyframes.Add(frame);
12843 }
12844
12845 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12846 group.RootPart.KeyframeMotion.Start();
12847 }
12848 else
12849 {
12850 if (group.RootPart.KeyframeMotion == null)
12851 return;
12852
12853 if (options.Data.Length == 0)
12854 {
12855 group.RootPart.KeyframeMotion.Stop();
12856 return;
12857 }
12858
12859 int code = (int)options.GetLSLIntegerItem(0);
12860
12861 int idx = 0;
12862
12863 while (idx < options.Data.Length)
12864 {
12865 int option = (int)options.GetLSLIntegerItem(idx++);
12866 int remain = options.Data.Length - idx;
12867
12868 switch (option)
12869 {
12870 case ScriptBaseClass.KFM_COMMAND:
12871 int cmd = (int)options.GetLSLIntegerItem(idx++);
12872 switch (cmd)
12873 {
12874 case ScriptBaseClass.KFM_CMD_PLAY:
12875 group.RootPart.KeyframeMotion.Start();
12876 break;
12877 case ScriptBaseClass.KFM_CMD_STOP:
12878 group.RootPart.KeyframeMotion.Stop();
12879 break;
12880 case ScriptBaseClass.KFM_CMD_PAUSE:
12881 group.RootPart.KeyframeMotion.Pause();
12882 break;
12883 }
12884 break;
12885 }
12886 }
12887 }
12888 }
12889
12890 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12891 {
12892 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12893
12894 int idx = 0;
12895 int idxStart = 0;
12896
12897 bool positionChanged = false;
12898 Vector3 finalPos = Vector3.Zero;
12899
12900 try
12901 {
12902 while (idx < rules.Length)
12903 {
12904 ++rulesParsed;
12905 int code = rules.GetLSLIntegerItem(idx++);
12906
12907 int remain = rules.Length - idx;
12908 idxStart = idx;
12909
12910 switch (code)
12911 {
12912 case (int)ScriptBaseClass.PRIM_POSITION:
12913 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12914 {
12915 if (remain < 1)
12916 return null;
12917
12918 LSL_Vector v;
12919 v = rules.GetVector3Item(idx++);
12920
12921 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12922 if (part == null)
12923 break;
12924
12925 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12926 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12927 if (part.LinkNum > 1)
12928 {
12929 localRot = GetPartLocalRot(part);
12930 localPos = GetPartLocalPos(part);
12931 }
12932
12933 v -= localPos;
12934 v /= localRot;
12935
12936 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12937
12938 v = v + 2 * sitOffset;
12939
12940 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12941 av.SendAvatarDataToAllAgents();
12942
12943 }
12944 break;
12945
12946 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12947 case (int)ScriptBaseClass.PRIM_ROTATION:
12948 {
12949 if (remain < 1)
12950 return null;
12951
12952 LSL_Rotation r;
12953 r = rules.GetQuaternionItem(idx++);
12954
12955 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12956 if (part == null)
12957 break;
12958
12959 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12960 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12961
12962 if (part.LinkNum > 1)
12963 localRot = GetPartLocalRot(part);
12964
12965 r = r * llGetRootRotation() / localRot;
12966 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12967 av.SendAvatarDataToAllAgents();
12968 }
12969 break;
12970
12971 // parse rest doing nothing but number of parameters error check
12972 case (int)ScriptBaseClass.PRIM_SIZE:
12973 case (int)ScriptBaseClass.PRIM_MATERIAL:
12974 case (int)ScriptBaseClass.PRIM_PHANTOM:
12975 case (int)ScriptBaseClass.PRIM_PHYSICS:
12976 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12977 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12978 case (int)ScriptBaseClass.PRIM_NAME:
12979 case (int)ScriptBaseClass.PRIM_DESC:
12980 if (remain < 1)
12981 return null;
12982 idx++;
12983 break;
12984
12985 case (int)ScriptBaseClass.PRIM_GLOW:
12986 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12987 case (int)ScriptBaseClass.PRIM_TEXGEN:
12988 if (remain < 2)
12989 return null;
12990 idx += 2;
12991 break;
12992
12993 case (int)ScriptBaseClass.PRIM_TYPE:
12994 if (remain < 3)
12995 return null;
12996 code = (int)rules.GetLSLIntegerItem(idx++);
12997 remain = rules.Length - idx;
12998 switch (code)
12999 {
13000 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13001 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13002 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13003 if (remain < 6)
13004 return null;
13005 idx += 6;
13006 break;
13007
13008 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13009 if (remain < 5)
13010 return null;
13011 idx += 5;
13012 break;
13013
13014 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13015 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13016 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13017 if (remain < 11)
13018 return null;
13019 idx += 11;
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13023 if (remain < 2)
13024 return null;
13025 idx += 2;
13026 break;
13027 }
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_COLOR:
13031 case (int)ScriptBaseClass.PRIM_TEXT:
13032 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13033 case (int)ScriptBaseClass.PRIM_OMEGA:
13034 if (remain < 3)
13035 return null;
13036 idx += 3;
13037 break;
13038
13039 case (int)ScriptBaseClass.PRIM_TEXTURE:
13040 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13041 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13042 if (remain < 5)
13043 return null;
13044 idx += 5;
13045 break;
13046
13047 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13048 if (remain < 7)
13049 return null;
13050
13051 idx += 7;
13052 break;
13053
13054 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13055 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13056 return null;
13057
13058 return rules.GetSublist(idx, -1);
13059 }
13060 }
13061 }
13062 catch (InvalidCastException e)
13063 {
13064 ShoutError(string.Format(
13065 "{0} error running rule #{1}: arg #{2} ",
13066 originFunc, rulesParsed, idx - idxStart) + e.Message);
13067 }
13068 finally
13069 {
13070 if (positionChanged)
13071 {
13072 av.OffsetPosition = finalPos;
13073// av.SendAvatarDataToAllAgents();
13074 av.SendTerseUpdateToAllClients();
13075 positionChanged = false;
13076 }
13077 }
13078 return null;
13079 }
13080
13081 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13082 {
13083 // avatars case
13084 // replies as SL wiki
13085
13086// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13087 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13088
13089 int idx = 0;
13090 while (idx < rules.Length)
13091 {
13092 int code = (int)rules.GetLSLIntegerItem(idx++);
13093 int remain = rules.Length - idx;
13094
13095 switch (code)
13096 {
13097 case (int)ScriptBaseClass.PRIM_MATERIAL:
13098 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_PHYSICS:
13102 res.Add(new LSL_Integer(0));
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13106 res.Add(new LSL_Integer(0));
13107 break;
13108
13109 case (int)ScriptBaseClass.PRIM_PHANTOM:
13110 res.Add(new LSL_Integer(0));
13111 break;
13112
13113 case (int)ScriptBaseClass.PRIM_POSITION:
13114
13115 Vector3 pos = avatar.OffsetPosition;
13116
13117 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13118 pos -= sitOffset;
13119
13120 if( sitPart != null)
13121 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13122
13123 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13124 break;
13125
13126 case (int)ScriptBaseClass.PRIM_SIZE:
13127 // as in llGetAgentSize above
13128// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13129 Vector3 s = avatar.Appearance.AvatarSize;
13130 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13131
13132 break;
13133
13134 case (int)ScriptBaseClass.PRIM_ROTATION:
13135 Quaternion rot = avatar.Rotation;
13136 if (sitPart != null)
13137 {
13138 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13139 }
13140
13141 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13142 break;
13143
13144 case (int)ScriptBaseClass.PRIM_TYPE:
13145 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13146 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13147 res.Add(new LSL_Vector(0f,1.0f,0f));
13148 res.Add(new LSL_Float(0.0f));
13149 res.Add(new LSL_Vector(0, 0, 0));
13150 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13151 res.Add(new LSL_Vector(0, 0, 0));
13152 break;
13153
13154 case (int)ScriptBaseClass.PRIM_TEXTURE:
13155 if (remain < 1)
13156 return null;
13157
13158 int face = (int)rules.GetLSLIntegerItem(idx++);
13159 if (face == ScriptBaseClass.ALL_SIDES)
13160 {
13161 for (face = 0; face < 21; face++)
13162 {
13163 res.Add(new LSL_String(""));
13164 res.Add(new LSL_Vector(0,0,0));
13165 res.Add(new LSL_Vector(0,0,0));
13166 res.Add(new LSL_Float(0.0));
13167 }
13168 }
13169 else
13170 {
13171 if (face >= 0 && face < 21)
13172 {
13173 res.Add(new LSL_String(""));
13174 res.Add(new LSL_Vector(0,0,0));
13175 res.Add(new LSL_Vector(0,0,0));
13176 res.Add(new LSL_Float(0.0));
13177 }
13178 }
13179 break;
13180
13181 case (int)ScriptBaseClass.PRIM_COLOR:
13182 if (remain < 1)
13183 return null;
13184
13185 face = (int)rules.GetLSLIntegerItem(idx++);
13186
13187 if (face == ScriptBaseClass.ALL_SIDES)
13188 {
13189 for (face = 0; face < 21; face++)
13190 {
13191 res.Add(new LSL_Vector(0,0,0));
13192 res.Add(new LSL_Float(0));
13193 }
13194 }
13195 else
13196 {
13197 res.Add(new LSL_Vector(0,0,0));
13198 res.Add(new LSL_Float(0));
13199 }
13200 break;
13201
13202 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13203 if (remain < 1)
13204 return null;
13205 face = (int)rules.GetLSLIntegerItem(idx++);
13206
13207 if (face == ScriptBaseClass.ALL_SIDES)
13208 {
13209 for (face = 0; face < 21; face++)
13210 {
13211 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13212 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13213 }
13214 }
13215 else
13216 {
13217 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13218 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13219 }
13220 break;
13221
13222 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13223 if (remain < 1)
13224 return null;
13225 face = (int)rules.GetLSLIntegerItem(idx++);
13226
13227 if (face == ScriptBaseClass.ALL_SIDES)
13228 {
13229 for (face = 0; face < 21; face++)
13230 {
13231 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13232 }
13233 }
13234 else
13235 {
13236 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13237 }
13238 break;
13239
13240 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13241 res.Add(new LSL_Integer(0));
13242 res.Add(new LSL_Integer(0));// softness
13243 res.Add(new LSL_Float(0.0f)); // gravity
13244 res.Add(new LSL_Float(0.0f)); // friction
13245 res.Add(new LSL_Float(0.0f)); // wind
13246 res.Add(new LSL_Float(0.0f)); // tension
13247 res.Add(new LSL_Vector(0f,0f,0f));
13248 break;
13249
13250 case (int)ScriptBaseClass.PRIM_TEXGEN:
13251 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13252 if (remain < 1)
13253 return null;
13254 face = (int)rules.GetLSLIntegerItem(idx++);
13255
13256 if (face == ScriptBaseClass.ALL_SIDES)
13257 {
13258 for (face = 0; face < 21; face++)
13259 {
13260 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13261 }
13262 }
13263 else
13264 {
13265 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13266 }
13267 break;
13268
13269 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13270 res.Add(new LSL_Integer(0));
13271 res.Add(new LSL_Vector(0f,0f,0f));
13272 res.Add(new LSL_Float(0f)); // intensity
13273 res.Add(new LSL_Float(0f)); // radius
13274 res.Add(new LSL_Float(0f)); // falloff
13275 break;
13276
13277 case (int)ScriptBaseClass.PRIM_GLOW:
13278 if (remain < 1)
13279 return null;
13280 face = (int)rules.GetLSLIntegerItem(idx++);
13281
13282 if (face == ScriptBaseClass.ALL_SIDES)
13283 {
13284 for (face = 0; face < 21; face++)
13285 {
13286 res.Add(new LSL_Float(0f));
13287 }
13288 }
13289 else
13290 {
13291 res.Add(new LSL_Float(0f));
13292 }
13293 break;
13294
13295 case (int)ScriptBaseClass.PRIM_TEXT:
13296 res.Add(new LSL_String(""));
13297 res.Add(new LSL_Vector(0f,0f,0f));
13298 res.Add(new LSL_Float(1.0f));
13299 break;
13300
13301 case (int)ScriptBaseClass.PRIM_NAME:
13302 res.Add(new LSL_String(avatar.Name));
13303 break;
13304
13305 case (int)ScriptBaseClass.PRIM_DESC:
13306 res.Add(new LSL_String(""));
13307 break;
13308
13309 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13310 Quaternion lrot = avatar.Rotation;
13311
13312 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13313 {
13314 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13315 }
13316 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13317 break;
13318
13319 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13320 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13321 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13322 lpos -= lsitOffset;
13323
13324 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13325 {
13326 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13327 }
13328 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13329 break;
13330
13331 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13332 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13333 return null;
13334
13335 return rules.GetSublist(idx, -1);
13336 }
13337 }
13338
13339 return null;
13340 }
11727 } 13341 }
11728 13342
11729 public class NotecardCache 13343 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 1426070..6ff6b00 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -211,7 +213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 213
212 internal void OSSLError(string msg) 214 internal void OSSLError(string msg)
213 { 215 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 216 if (m_debuggerSafe)
217 {
218 OSSLShoutError(msg);
219 }
220 else
221 {
222 throw new ScriptException("OSSL Runtime Error: " + msg);
223 }
215 } 224 }
216 225
217 /// <summary> 226 /// <summary>
@@ -930,18 +939,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 939 if (target != null)
931 { 940 {
932 UUID animID=UUID.Zero; 941 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 942 m_host.TaskInventory.LockItemsForRead(true);
943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 944 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 945 if (inv.Value.Name == animation)
936 { 946 {
937 if (inv.Value.Name == animation) 947 if (inv.Value.Type == (int)AssetType.Animation)
938 { 948 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 949 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 950 }
944 } 951 }
952 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 954 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 955 else
@@ -982,6 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 990 else
983 animID = UUID.Zero; 991 animID = UUID.Zero;
984 } 992 }
993 m_host.TaskInventory.LockItemsForRead(false);
985 994
986 if (animID == UUID.Zero) 995 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 996 target.Animator.RemoveAnimation(animation);
@@ -1848,15 +1857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 { 1857 {
1849 UUID assetID = UUID.Zero; 1858 UUID assetID = UUID.Zero;
1850 1859
1851 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1860 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1861
1862 if (!notecardNameIsUUID)
1852 { 1863 {
1853 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1864 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1854 {
1855 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1856 {
1857 assetID = item.AssetID;
1858 }
1859 }
1860 } 1865 }
1861 1866
1862 if (assetID == UUID.Zero) 1867 if (assetID == UUID.Zero)
@@ -1867,7 +1872,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1867 AssetBase a = World.AssetService.Get(assetID.ToString()); 1872 AssetBase a = World.AssetService.Get(assetID.ToString());
1868 1873
1869 if (a == null) 1874 if (a == null)
1870 return UUID.Zero; 1875 {
1876 // Whoops, it's still possible here that the notecard name was properly
1877 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1878 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1879 if (assetID == UUID.Zero)
1880 return UUID.Zero;
1881
1882 if (!NotecardCache.IsCached(assetID))
1883 {
1884 a = World.AssetService.Get(assetID.ToString());
1885
1886 if (a == null)
1887 {
1888 return UUID.Zero;
1889 }
1890 }
1891 }
1871 1892
1872 string data = Encoding.UTF8.GetString(a.Data); 1893 string data = Encoding.UTF8.GetString(a.Data);
1873 NotecardCache.Cache(assetID, data); 1894 NotecardCache.Cache(assetID, data);
@@ -1875,6 +1896,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 1896
1876 return assetID; 1897 return assetID;
1877 } 1898 }
1899 protected UUID SearchTaskInventoryForAssetId(string name)
1900 {
1901 UUID assetId = UUID.Zero;
1902 m_host.TaskInventory.LockItemsForRead(true);
1903 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1904 {
1905 if (item.Type == 7 && item.Name == name)
1906 {
1907 assetId = item.AssetID;
1908 }
1909 }
1910 m_host.TaskInventory.LockItemsForRead(false);
1911 return assetId;
1912 }
1878 1913
1879 /// <summary> 1914 /// <summary>
1880 /// Directly get an entire notecard at once. 1915 /// Directly get an entire notecard at once.
@@ -2342,7 +2377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2377 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2343 m_host.AddScriptLPS(1); 2378 m_host.AddScriptLPS(1);
2344 2379
2345 return NpcCreate(firstname, lastname, position, notecard, false, false); 2380 return NpcCreate(firstname, lastname, position, notecard, true, false);
2346 } 2381 }
2347 2382
2348 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2383 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2353,24 +2388,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 return NpcCreate( 2388 return NpcCreate(
2354 firstname, lastname, position, notecard, 2389 firstname, lastname, position, notecard,
2355 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2390 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2356 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2391 false);
2392// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2357 } 2393 }
2358 2394
2359 private LSL_Key NpcCreate( 2395 private LSL_Key NpcCreate(
2360 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2396 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2361 { 2397 {
2398 if (!owned)
2399 OSSLError("Unowned NPCs are unsupported");
2400
2401 string groupTitle = String.Empty;
2402
2403 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2404 return new LSL_Key(UUID.Zero.ToString());
2405
2406 if (firstname != String.Empty || lastname != String.Empty)
2407 {
2408 if (firstname != "Shown outfit:")
2409 groupTitle = "- NPC -";
2410 }
2411
2362 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2412 INPCModule module = World.RequestModuleInterface<INPCModule>();
2363 if (module != null) 2413 if (module != null)
2364 { 2414 {
2365 AvatarAppearance appearance = null; 2415 AvatarAppearance appearance = null;
2366 2416
2367 UUID id; 2417// UUID id;
2368 if (UUID.TryParse(notecard, out id)) 2418// if (UUID.TryParse(notecard, out id))
2369 { 2419// {
2370 ScenePresence clonePresence = World.GetScenePresence(id); 2420// ScenePresence clonePresence = World.GetScenePresence(id);
2371 if (clonePresence != null) 2421// if (clonePresence != null)
2372 appearance = clonePresence.Appearance; 2422// appearance = clonePresence.Appearance;
2373 } 2423// }
2374 2424
2375 if (appearance == null) 2425 if (appearance == null)
2376 { 2426 {
@@ -2378,9 +2428,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2378 2428
2379 if (appearanceSerialized != null) 2429 if (appearanceSerialized != null)
2380 { 2430 {
2381 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2431 try
2382 appearance = new AvatarAppearance(); 2432 {
2383 appearance.Unpack(appearanceOsd); 2433 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2434 appearance = new AvatarAppearance();
2435 appearance.Unpack(appearanceOsd);
2436 }
2437 catch
2438 {
2439 return UUID.Zero.ToString();
2440 }
2384 } 2441 }
2385 else 2442 else
2386 { 2443 {
@@ -2399,6 +2456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 World, 2456 World,
2400 appearance); 2457 appearance);
2401 2458
2459 ScenePresence sp;
2460 if (World.TryGetScenePresence(x, out sp))
2461 {
2462 sp.Grouptitle = groupTitle;
2463 sp.SendAvatarDataToAllAgents();
2464 }
2402 return new LSL_Key(x.ToString()); 2465 return new LSL_Key(x.ToString());
2403 } 2466 }
2404 2467
@@ -2702,16 +2765,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2765 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2703 m_host.AddScriptLPS(1); 2766 m_host.AddScriptLPS(1);
2704 2767
2705 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2768 ManualResetEvent ev = new ManualResetEvent(false);
2706 if (module != null)
2707 {
2708 UUID npcId = new UUID(npc.m_string);
2709 2769
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2770 Util.FireAndForget(delegate(object x) {
2711 return; 2771 try
2772 {
2773 INPCModule module = World.RequestModuleInterface<INPCModule>();
2774 if (module != null)
2775 {
2776 UUID npcId = new UUID(npc.m_string);
2712 2777
2713 module.DeleteNPC(npcId, World); 2778 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2714 } 2779 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2780 {
2781 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2782 return;
2783 }
2784
2785 module.DeleteNPC(npcId, World);
2786 }
2787 }
2788 finally
2789 {
2790 ev.Set();
2791 }
2792 });
2793 ev.WaitOne();
2715 } 2794 }
2716 2795
2717 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2796 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index dd45406..d3ef378 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 4ac179a..9bf6f9b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 void llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount); 212 LSL_String llTransferLindenDollars(string destination, int amount);
212 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
213 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
428 432
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 } 436 }
432} 437}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..7eb347e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9bf1a64..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,6 +661,17 @@ 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;
664
665 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
666 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
667 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
668 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
669
670 public const int PRIM_PHYSICS_MATERIAL = 31;
671 public const int DENSITY = 1;
672 public const int FRICTION = 2;
673 public const int RESTITUTION = 4;
674 public const int GRAVITY_MULTIPLIER = 8;
663 675
664 // extra constants for llSetPrimMediaParams 676 // extra constants for llSetPrimMediaParams
665 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 677 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -732,7 +744,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
732 744
733 public static readonly LSLInteger RCERR_UNKNOWN = -1; 745 public static readonly LSLInteger RCERR_UNKNOWN = -1;
734 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
735 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;
736 761
737 /// <summary> 762 /// <summary>
738 /// 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 669cc37..c8ced43 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 d483219..6e04e79 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;
@@ -149,6 +150,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
149 private Dictionary<UUID, IScriptInstance> m_Scripts = 150 private Dictionary<UUID, IScriptInstance> m_Scripts =
150 new Dictionary<UUID, IScriptInstance>(); 151 new Dictionary<UUID, IScriptInstance>();
151 152
153 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
154
152 // Maps the asset ID to the assembly 155 // Maps the asset ID to the assembly
153 156
154 private Dictionary<UUID, string> m_Assemblies = 157 private Dictionary<UUID, string> m_Assemblies =
@@ -171,6 +174,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
171 IWorkItemResult m_CurrentCompile = null; 174 IWorkItemResult m_CurrentCompile = null;
172 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 175 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
173 176
177 private void lockScriptsForRead(bool locked)
178 {
179 if (locked)
180 {
181 if (m_scriptsLock.RecursiveReadCount > 0)
182 {
183 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.");
184 m_scriptsLock.ExitReadLock();
185 }
186 if (m_scriptsLock.RecursiveWriteCount > 0)
187 {
188 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
189 m_scriptsLock.ExitWriteLock();
190 }
191
192 while (!m_scriptsLock.TryEnterReadLock(60000))
193 {
194 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.");
195 if (m_scriptsLock.IsWriteLockHeld)
196 {
197 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
198 }
199 }
200 }
201 else
202 {
203 if (m_scriptsLock.RecursiveReadCount > 0)
204 {
205 m_scriptsLock.ExitReadLock();
206 }
207 }
208 }
209 private void lockScriptsForWrite(bool locked)
210 {
211 if (locked)
212 {
213 if (m_scriptsLock.RecursiveReadCount > 0)
214 {
215 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.");
216 m_scriptsLock.ExitReadLock();
217 }
218 if (m_scriptsLock.RecursiveWriteCount > 0)
219 {
220 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
221 m_scriptsLock.ExitWriteLock();
222 }
223
224 while (!m_scriptsLock.TryEnterWriteLock(60000))
225 {
226 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.");
227 if (m_scriptsLock.IsWriteLockHeld)
228 {
229 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
230 }
231 }
232 }
233 else
234 {
235 if (m_scriptsLock.RecursiveWriteCount > 0)
236 {
237 m_scriptsLock.ExitWriteLock();
238 }
239 }
240 }
241
174 private ScriptEngineConsoleCommands m_consoleCommands; 242 private ScriptEngineConsoleCommands m_consoleCommands;
175 243
176 public string ScriptEngineName 244 public string ScriptEngineName
@@ -701,64 +769,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
701 { 769 {
702 if (!m_Enabled) 770 if (!m_Enabled)
703 return; 771 return;
772 lockScriptsForRead(true);
704 773
705 lock (m_Scripts) 774 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
706 {
707 m_log.InfoFormat(
708 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
709 775
710 foreach (IScriptInstance instance in m_Scripts.Values) 776// foreach (IScriptInstance instance in m_Scripts.Values)
777 foreach (IScriptInstance instance in instancesToDel)
778 {
779 // Force a final state save
780 //
781 if (m_Assemblies.ContainsKey(instance.AssetID))
711 { 782 {
712 // Force a final state save 783 string assembly = m_Assemblies[instance.AssetID];
713 //
714 if (m_Assemblies.ContainsKey(instance.AssetID))
715 {
716 string assembly = m_Assemblies[instance.AssetID];
717 784
718 try 785 try
719 { 786 {
720 instance.SaveState(assembly); 787 instance.SaveState(assembly);
721 }
722 catch (Exception e)
723 {
724 m_log.Error(
725 string.Format(
726 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
727 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
728 , e);
729 }
730 } 788 }
789 catch (Exception e)
790 {
791 m_log.Error(
792 string.Format(
793 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
794 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
795 , e);
796 }
797 }
731 798
732 // Clear the event queue and abort the instance thread 799 // Clear the event queue and abort the instance thread
733 // 800 //
734 instance.ClearQueue(); 801 instance.ClearQueue();
735 instance.Stop(0); 802 instance.Stop(0);
736 803
737 // Release events, timer, etc 804 // Release events, timer, etc
738 // 805 //
739 instance.DestroyScriptInstance(); 806 instance.DestroyScriptInstance();
740 807
741 // Unload scripts and app domains. 808 // Unload scripts and app domains
742 // Must be done explicitly because they have infinite 809 // Must be done explicitly because they have infinite
743 // lifetime. 810 // lifetime
744 // However, don't bother to do this if the simulator is shutting 811 //
745 // down since it takes a long time with many scripts. 812// if (!m_SimulatorShuttingDown)
746 if (!m_SimulatorShuttingDown) 813 {
814 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
815 if (m_DomainScripts[instance.AppDomain].Count == 0)
747 { 816 {
748 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 817 m_DomainScripts.Remove(instance.AppDomain);
749 if (m_DomainScripts[instance.AppDomain].Count == 0) 818 UnloadAppDomain(instance.AppDomain);
750 {
751 m_DomainScripts.Remove(instance.AppDomain);
752 UnloadAppDomain(instance.AppDomain);
753 }
754 } 819 }
755 } 820 }
756 821
757 m_Scripts.Clear(); 822// m_Scripts.Clear();
758 m_PrimObjects.Clear(); 823// m_PrimObjects.Clear();
759 m_Assemblies.Clear(); 824// m_Assemblies.Clear();
760 m_DomainScripts.Clear(); 825// m_DomainScripts.Clear();
761 } 826 }
827 lockScriptsForRead(false);
828 lockScriptsForWrite(true);
829 m_Scripts.Clear();
830 lockScriptsForWrite(false);
831 m_PrimObjects.Clear();
832 m_Assemblies.Clear();
833 m_DomainScripts.Clear();
834
762 lock (m_ScriptEngines) 835 lock (m_ScriptEngines)
763 { 836 {
764 m_ScriptEngines.Remove(this); 837 m_ScriptEngines.Remove(this);
@@ -827,22 +900,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
827 900
828 List<IScriptInstance> instances = new List<IScriptInstance>(); 901 List<IScriptInstance> instances = new List<IScriptInstance>();
829 902
830 lock (m_Scripts) 903 lockScriptsForRead(true);
831 { 904 foreach (IScriptInstance instance in m_Scripts.Values)
832 foreach (IScriptInstance instance in m_Scripts.Values)
833 instances.Add(instance); 905 instances.Add(instance);
834 } 906 lockScriptsForRead(false);
835 907
836 foreach (IScriptInstance i in instances) 908 foreach (IScriptInstance i in instances)
837 { 909 {
838 string assembly = String.Empty; 910 string assembly = String.Empty;
839 911
840 lock (m_Scripts) 912
841 {
842 if (!m_Assemblies.ContainsKey(i.AssetID)) 913 if (!m_Assemblies.ContainsKey(i.AssetID))
843 continue; 914 continue;
844 assembly = m_Assemblies[i.AssetID]; 915 assembly = m_Assemblies[i.AssetID];
845 } 916
846 917
847 try 918 try
848 { 919 {
@@ -1246,97 +1317,93 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1246 } 1317 }
1247 1318
1248 ScriptInstance instance = null; 1319 ScriptInstance instance = null;
1249 lock (m_Scripts) 1320 // Create the object record
1321 lockScriptsForRead(true);
1322 if ((!m_Scripts.ContainsKey(itemID)) ||
1323 (m_Scripts[itemID].AssetID != assetID))
1250 { 1324 {
1251 // Create the object record 1325 lockScriptsForRead(false);
1252 if ((!m_Scripts.ContainsKey(itemID)) ||
1253 (m_Scripts[itemID].AssetID != assetID))
1254 {
1255 UUID appDomain = assetID;
1256 1326
1257 if (part.ParentGroup.IsAttachment) 1327 UUID appDomain = assetID;
1258 appDomain = part.ParentGroup.RootPart.UUID;
1259 1328
1260 if (!m_AppDomains.ContainsKey(appDomain)) 1329 if (part.ParentGroup.IsAttachment)
1261 { 1330 appDomain = part.ParentGroup.RootPart.UUID;
1262 try
1263 {
1264 AppDomainSetup appSetup = new AppDomainSetup();
1265 appSetup.PrivateBinPath = Path.Combine(
1266 m_ScriptEnginesPath,
1267 m_Scene.RegionInfo.RegionID.ToString());
1268 1331
1269 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1332 if (!m_AppDomains.ContainsKey(appDomain))
1270 Evidence evidence = new Evidence(baseEvidence); 1333 {
1334 try
1335 {
1336 AppDomainSetup appSetup = new AppDomainSetup();
1337 appSetup.PrivateBinPath = Path.Combine(
1338 m_ScriptEnginesPath,
1339 m_Scene.RegionInfo.RegionID.ToString());
1271 1340
1272 AppDomain sandbox; 1341 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1273 if (m_AppDomainLoading) 1342 Evidence evidence = new Evidence(baseEvidence);
1274 {
1275 sandbox = AppDomain.CreateDomain(
1276 m_Scene.RegionInfo.RegionID.ToString(),
1277 evidence, appSetup);
1278 sandbox.AssemblyResolve +=
1279 new ResolveEventHandler(
1280 AssemblyResolver.OnAssemblyResolve);
1281 }
1282 else
1283 {
1284 sandbox = AppDomain.CurrentDomain;
1285 }
1286
1287 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1288 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1289 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1290 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1291 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1292 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1293 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1294
1295 m_AppDomains[appDomain] = sandbox;
1296 1343
1297 m_DomainScripts[appDomain] = new List<UUID>(); 1344 AppDomain sandbox;
1345 if (m_AppDomainLoading)
1346 {
1347 sandbox = AppDomain.CreateDomain(
1348 m_Scene.RegionInfo.RegionID.ToString(),
1349 evidence, appSetup);
1350 m_AppDomains[appDomain].AssemblyResolve +=
1351 new ResolveEventHandler(
1352 AssemblyResolver.OnAssemblyResolve);
1298 } 1353 }
1299 catch (Exception e) 1354 else
1300 { 1355 {
1301 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1356 sandbox = AppDomain.CurrentDomain;
1302 m_ScriptErrorMessage += "Exception creating app domain:\n";
1303 m_ScriptFailCount++;
1304 lock (m_AddingAssemblies)
1305 {
1306 m_AddingAssemblies[assembly]--;
1307 }
1308 return false;
1309 } 1357 }
1310 }
1311 m_DomainScripts[appDomain].Add(itemID);
1312
1313 instance = new ScriptInstance(this, part,
1314 item,
1315 startParam, postOnRez,
1316 m_MaxScriptQueue);
1317 1358
1318 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) 1359 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1319 return false; 1360 return false;
1320 1361
1321// if (DebugLevel >= 1) 1362 m_AppDomains[appDomain] = sandbox;
1322// m_log.DebugFormat(
1323// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1324// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1325// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1326 1363
1327 if (presence != null) 1364 m_DomainScripts[appDomain] = new List<UUID>();
1365 }
1366 catch (Exception e)
1328 { 1367 {
1329 ShowScriptSaveResponse(item.OwnerID, 1368 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1330 assetID, "Compile successful", true); 1369 m_ScriptErrorMessage += "Exception creating app domain:\n";
1370 m_ScriptFailCount++;
1371 lock (m_AddingAssemblies)
1372 {
1373 m_AddingAssemblies[assembly]--;
1374 }
1375 return false;
1331 } 1376 }
1377 }
1378 m_DomainScripts[appDomain].Add(itemID);
1379
1380 instance = new ScriptInstance(this, part,
1381 item,
1382 startParam, postOnRez,
1383 m_MaxScriptQueue);
1332 1384
1333 instance.AppDomain = appDomain; 1385 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1334 instance.LineMap = linemap; 1386// m_log.DebugFormat(
1387// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1388// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1389// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1335 1390
1336 m_Scripts[itemID] = instance; 1391 if (presence != null)
1392 {
1393 ShowScriptSaveResponse(item.OwnerID,
1394 assetID, "Compile successful", true);
1337 } 1395 }
1338 }
1339 1396
1397 instance.AppDomain = appDomain;
1398 instance.LineMap = linemap;
1399 lockScriptsForWrite(true);
1400 m_Scripts[itemID] = instance;
1401 lockScriptsForWrite(false);
1402 }
1403 else
1404 {
1405 lockScriptsForRead(false);
1406 }
1340 lock (m_PrimObjects) 1407 lock (m_PrimObjects)
1341 { 1408 {
1342 if (!m_PrimObjects.ContainsKey(localID)) 1409 if (!m_PrimObjects.ContainsKey(localID))
@@ -1354,7 +1421,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1354 m_AddingAssemblies[assembly]--; 1421 m_AddingAssemblies[assembly]--;
1355 } 1422 }
1356 1423
1357 if (instance != null) 1424 if (instance!=null)
1358 instance.Init(); 1425 instance.Init();
1359 1426
1360 bool runIt; 1427 bool runIt;
@@ -1377,18 +1444,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1377 m_CompileDict.Remove(itemID); 1444 m_CompileDict.Remove(itemID);
1378 } 1445 }
1379 1446
1380 IScriptInstance instance = null; 1447 lockScriptsForRead(true);
1381 1448 // Do we even have it?
1382 lock (m_Scripts) 1449 if (!m_Scripts.ContainsKey(itemID))
1383 { 1450 {
1384 // Do we even have it? 1451 // Do we even have it?
1385 if (!m_Scripts.ContainsKey(itemID)) 1452 if (!m_Scripts.ContainsKey(itemID))
1386 return; 1453 return;
1387 1454
1388 instance = m_Scripts[itemID]; 1455 lockScriptsForRead(false);
1456 lockScriptsForWrite(true);
1389 m_Scripts.Remove(itemID); 1457 m_Scripts.Remove(itemID);
1458 lockScriptsForWrite(false);
1459
1460 return;
1390 } 1461 }
1462
1391 1463
1464 IScriptInstance instance=m_Scripts[itemID];
1465 lockScriptsForRead(false);
1466 lockScriptsForWrite(true);
1467 m_Scripts.Remove(itemID);
1468 lockScriptsForWrite(false);
1392 instance.ClearQueue(); 1469 instance.ClearQueue();
1393 1470
1394 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1471 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1425,8 +1502,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1425 1502
1426 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1503 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1427 if (handlerObjectRemoved != null) 1504 if (handlerObjectRemoved != null)
1428 handlerObjectRemoved(instance.ObjectID); 1505 {
1506 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1507 handlerObjectRemoved(part.UUID);
1508 }
1429 1509
1510 CleanAssemblies();
1511
1430 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1512 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1431 if (handlerScriptRemoved != null) 1513 if (handlerScriptRemoved != null)
1432 handlerScriptRemoved(itemID); 1514 handlerScriptRemoved(itemID);
@@ -1687,12 +1769,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1687 private IScriptInstance GetInstance(UUID itemID) 1769 private IScriptInstance GetInstance(UUID itemID)
1688 { 1770 {
1689 IScriptInstance instance; 1771 IScriptInstance instance;
1690 lock (m_Scripts) 1772 lockScriptsForRead(true);
1773 if (!m_Scripts.ContainsKey(itemID))
1691 { 1774 {
1692 if (!m_Scripts.ContainsKey(itemID)) 1775 lockScriptsForRead(false);
1693 return null; 1776 return null;
1694 instance = m_Scripts[itemID];
1695 } 1777 }
1778 instance = m_Scripts[itemID];
1779 lockScriptsForRead(false);
1696 return instance; 1780 return instance;
1697 } 1781 }
1698 1782
@@ -1716,6 +1800,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1716 return false; 1800 return false;
1717 } 1801 }
1718 1802
1803 [DebuggerNonUserCode]
1719 public void ApiResetScript(UUID itemID) 1804 public void ApiResetScript(UUID itemID)
1720 { 1805 {
1721 IScriptInstance instance = GetInstance(itemID); 1806 IScriptInstance instance = GetInstance(itemID);
@@ -1777,6 +1862,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1777 return UUID.Zero; 1862 return UUID.Zero;
1778 } 1863 }
1779 1864
1865 [DebuggerNonUserCode]
1780 public void SetState(UUID itemID, string newState) 1866 public void SetState(UUID itemID, string newState)
1781 { 1867 {
1782 IScriptInstance instance = GetInstance(itemID); 1868 IScriptInstance instance = GetInstance(itemID);
@@ -1799,11 +1885,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1799 1885
1800 List<IScriptInstance> instances = new List<IScriptInstance>(); 1886 List<IScriptInstance> instances = new List<IScriptInstance>();
1801 1887
1802 lock (m_Scripts) 1888 lockScriptsForRead(true);
1803 { 1889 foreach (IScriptInstance instance in m_Scripts.Values)
1804 foreach (IScriptInstance instance in m_Scripts.Values)
1805 instances.Add(instance); 1890 instances.Add(instance);
1806 } 1891 lockScriptsForRead(false);
1807 1892
1808 foreach (IScriptInstance i in instances) 1893 foreach (IScriptInstance i in instances)
1809 { 1894 {