aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3195
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs113
-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.cs12
-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.cs56
-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.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs378
19 files changed, 3238 insertions, 1041 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ 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 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 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..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
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.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0fa247d..3bbdbe8 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{
@@ -104,16 +108,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
110 protected ISoundModule m_SoundModule = null; 116 protected ISoundModule m_SoundModule = null;
111 117
118// protected Timer m_ShoutSayTimer;
119 protected int m_SayShoutCount = 0;
120 DateTime m_lastSayShoutCheck;
121
122 private Dictionary<string, string> MovementAnimationsForLSL =
123 new Dictionary<string, string> {
124 {"FLY", "Flying"},
125 {"FLYSLOW", "FlyingSlow"},
126 {"HOVER_UP", "Hovering Up"},
127 {"HOVER_DOWN", "Hovering Down"},
128 {"HOVER", "Hovering"},
129 {"LAND", "Landing"},
130 {"FALLDOWN", "Falling Down"},
131 {"PREJUMP", "PreJumping"},
132 {"JUMP", "Jumping"},
133 {"STANDUP", "Standing Up"},
134 {"SOFT_LAND", "Soft Landing"},
135 {"STAND", "Standing"},
136 {"CROUCHWALK", "CrouchWalking"},
137 {"RUN", "Running"},
138 {"WALK", "Walking"},
139 {"CROUCH", "Crouching"},
140 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"}
142 };
143
112 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
113 { 145 {
146/*
147 m_ShoutSayTimer = new Timer(1000);
148 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
149 m_ShoutSayTimer.AutoReset = true;
150 m_ShoutSayTimer.Start();
151*/
152 m_lastSayShoutCheck = DateTime.UtcNow;
153
114 m_ScriptEngine = ScriptEngine; 154 m_ScriptEngine = ScriptEngine;
115 m_host = host; 155 m_host = host;
116 m_item = item; 156 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
117 158
118 LoadLimits(); // read script limits from config. 159 LoadLimits(); // read script limits from config.
119 160
@@ -174,6 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
174 get { return m_ScriptEngine.World; } 215 get { return m_ScriptEngine.World; }
175 } 216 }
176 217
218 [DebuggerNonUserCode]
177 public void state(string newState) 219 public void state(string newState)
178 { 220 {
179 m_ScriptEngine.SetState(m_item.ItemID, newState); 221 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -183,6 +225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
183 /// Reset the named script. The script must be present 225 /// Reset the named script. The script must be present
184 /// in the same prim. 226 /// in the same prim.
185 /// </summary> 227 /// </summary>
228 [DebuggerNonUserCode]
186 public void llResetScript() 229 public void llResetScript()
187 { 230 {
188 m_host.AddScriptLPS(1); 231 m_host.AddScriptLPS(1);
@@ -245,6 +288,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
245 } 288 }
246 } 289 }
247 290
291 public List<ScenePresence> GetLinkAvatars(int linkType)
292 {
293 List<ScenePresence> ret = new List<ScenePresence>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
296
297 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
298
299 switch (linkType)
300 {
301 case ScriptBaseClass.LINK_SET:
302 return avs;
303
304 case ScriptBaseClass.LINK_ROOT:
305 return ret;
306
307 case ScriptBaseClass.LINK_ALL_OTHERS:
308 return avs;
309
310 case ScriptBaseClass.LINK_ALL_CHILDREN:
311 return avs;
312
313 case ScriptBaseClass.LINK_THIS:
314 return ret;
315
316 default:
317 if (linkType < 0)
318 return ret;
319
320 int partCount = m_host.ParentGroup.GetPartCount();
321
322 if (linkType <= partCount)
323 {
324 return ret;
325 }
326 else
327 {
328 linkType = linkType - partCount;
329 if (linkType > avs.Count)
330 {
331 return ret;
332 }
333 else
334 {
335 ret.Add(avs[linkType-1]);
336 return ret;
337 }
338 }
339 }
340 }
341
248 public List<SceneObjectPart> GetLinkParts(int linkType) 342 public List<SceneObjectPart> GetLinkParts(int linkType)
249 { 343 {
250 return GetLinkParts(m_host, linkType); 344 return GetLinkParts(m_host, linkType);
@@ -253,6 +347,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
253 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 347 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
254 { 348 {
255 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 349 List<SceneObjectPart> ret = new List<SceneObjectPart>();
350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
351 return ret;
256 ret.Add(part); 352 ret.Add(part);
257 353
258 switch (linkType) 354 switch (linkType)
@@ -479,31 +575,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
479 575
480 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 576 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
481 577
482 /// <summary> 578 // Utility function for llRot2Euler
483 /// Convert an LSL rotation to a Euler vector. 579
484 /// </summary> 580 // normalize an angle between -PI and PI (-180 to +180 degrees)
485 /// <remarks> 581 protected double NormalizeAngle(double angle)
486 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
487 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
488 /// </remarks>
489 /// <param name="r"></param>
490 /// <returns></returns>
491 public LSL_Vector llRot2Euler(LSL_Rotation r)
492 { 582 {
493 m_host.AddScriptLPS(1); 583 if (angle > -Math.PI && angle < Math.PI)
584 return angle;
494 585
495 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 586 int numPis = (int)(Math.PI / angle);
496 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 587 double remainder = angle - Math.PI * numPis;
497 if (m == 0.0) return new LSL_Vector(); 588 if (numPis % 2 == 1)
498 double x = Math.Atan2(-v.y, v.z); 589 return Math.PI - angle;
499 double sin = v.x / m; 590 return remainder;
500 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 591 }
501 double y = Math.Asin(sin);
502 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
503 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)));
504 double z = Math.Atan2(v.y, v.x);
505 592
506 return new LSL_Vector(x, y, z); 593 public LSL_Vector llRot2Euler(LSL_Rotation q1)
594 {
595 m_host.AddScriptLPS(1);
596 LSL_Vector eul = new LSL_Vector();
597
598 double sqw = q1.s*q1.s;
599 double sqx = q1.x*q1.x;
600 double sqy = q1.z*q1.z;
601 double sqz = q1.y*q1.y;
602 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
603 double test = q1.x*q1.z + q1.y*q1.s;
604 if (test > 0.4999*unit) { // singularity at north pole
605 eul.z = 2 * Math.Atan2(q1.x,q1.s);
606 eul.y = Math.PI/2;
607 eul.x = 0;
608 return eul;
609 }
610 if (test < -0.4999*unit) { // singularity at south pole
611 eul.z = -2 * Math.Atan2(q1.x,q1.s);
612 eul.y = -Math.PI/2;
613 eul.x = 0;
614 return eul;
615 }
616 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
617 eul.y = Math.Asin(2*test/unit);
618 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
619 return eul;
507 } 620 }
508 621
509 /* From wiki: 622 /* From wiki:
@@ -556,18 +669,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
556 m_host.AddScriptLPS(1); 669 m_host.AddScriptLPS(1);
557 670
558 double x,y,z,s; 671 double x,y,z,s;
559 672 v.x *= 0.5;
560 double c1 = Math.Cos(v.x * 0.5); 673 v.y *= 0.5;
561 double c2 = Math.Cos(v.y * 0.5); 674 v.z *= 0.5;
562 double c3 = Math.Cos(v.z * 0.5); 675 double c1 = Math.Cos(v.x);
563 double s1 = Math.Sin(v.x * 0.5); 676 double c2 = Math.Cos(v.y);
564 double s2 = Math.Sin(v.y * 0.5); 677 double c1c2 = c1 * c2;
565 double s3 = Math.Sin(v.z * 0.5); 678 double s1 = Math.Sin(v.x);
566 679 double s2 = Math.Sin(v.y);
567 x = s1 * c2 * c3 + c1 * s2 * s3; 680 double s1s2 = s1 * s2;
568 y = c1 * s2 * c3 - s1 * c2 * s3; 681 double c1s2 = c1 * s2;
569 z = s1 * s2 * c3 + c1 * c2 * s3; 682 double s1c2 = s1 * c2;
570 s = c1 * c2 * c3 - s1 * s2 * s3; 683 double c3 = Math.Cos(v.z);
684 double s3 = Math.Sin(v.z);
685
686 x = s1c2 * c3 + c1s2 * s3;
687 y = c1s2 * c3 - s1c2 * s3;
688 z = s1s2 * c3 + c1c2 * s3;
689 s = c1c2 * c3 - s1s2 * s3;
571 690
572 return new LSL_Rotation(x, y, z, s); 691 return new LSL_Rotation(x, y, z, s);
573 } 692 }
@@ -705,77 +824,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 824 {
706 //A and B should both be normalized 825 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 826 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 827 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 828 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 829
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 830 double dotProduct = LSL_Vector.Dot(a, b);
831 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
832 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
833 double angle = Math.Acos(dotProduct / magProduct);
834 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
835 double s = Math.Sin(angle / 2);
836
837 double x = axis.x * s;
838 double y = axis.y * s;
839 double z = axis.z * s;
840 double w = Math.Cos(angle / 2);
841
842 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
844
845 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
846 */
847
848 // This method mimics the 180 errors found in SL
849 // See www.euclideanspace.com... angleBetween
850 LSL_Vector vec_a = a;
851 LSL_Vector vec_b = b;
852
853 // Eliminate zero length
854 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
855 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
856 if (vec_a_mag < 0.00001 ||
857 vec_b_mag < 0.00001)
712 { 858 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 859 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 860 }
715 else 861
862 // Normalize
863 vec_a = llVecNorm(vec_a);
864 vec_b = llVecNorm(vec_b);
865
866 // Calculate axis and rotation angle
867 LSL_Vector axis = vec_a % vec_b;
868 LSL_Float cos_theta = vec_a * vec_b;
869
870 // Check if parallel
871 if (cos_theta > 0.99999)
716 { 872 {
717 a = LSL_Vector.Norm(a); 873 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 874 }
719 double dotProduct = LSL_Vector.Dot(a, b); 875
720 // There are two degenerate cases possible. These are for vectors 180 or 876 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 877 else if (cos_theta < -0.99999)
722 // 878 {
723 // Check for vectors 180 degrees apart. 879 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 880 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 881 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 882 }
727 // First assume X axis is orthogonal to the vectors. 883 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 884 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 885 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 886 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 887 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 888 s = Math.Cos(theta);
733 { 889 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 890 x = axis.x * t;
735 } 891 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 892 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 893 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 894 }
776 return rotBetween;
777 } 895 }
778 896
779 public void llWhisper(int channelID, string text) 897 public void llWhisper(int channelID, string text)
780 { 898 {
781 m_host.AddScriptLPS(1); 899 m_host.AddScriptLPS(1);
@@ -791,10 +909,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
791 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 909 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
792 } 910 }
793 911
912 private void CheckSayShoutTime()
913 {
914 DateTime now = DateTime.UtcNow;
915 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
916 {
917 m_lastSayShoutCheck = now;
918 m_SayShoutCount = 0;
919 }
920 else
921 m_SayShoutCount++;
922 }
923
794 public void llSay(int channelID, string text) 924 public void llSay(int channelID, string text)
795 { 925 {
796 m_host.AddScriptLPS(1); 926 m_host.AddScriptLPS(1);
797 927
928 if (channelID == 0)
929// m_SayShoutCount++;
930 CheckSayShoutTime();
931
932 if (m_SayShoutCount >= 11)
933 ScriptSleep(2000);
934
798 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 935 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
799 { 936 {
800 Console.WriteLine(text); 937 Console.WriteLine(text);
@@ -817,6 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 { 954 {
818 m_host.AddScriptLPS(1); 955 m_host.AddScriptLPS(1);
819 956
957 if (channelID == 0)
958// m_SayShoutCount++;
959 CheckSayShoutTime();
960
961 if (m_SayShoutCount >= 11)
962 ScriptSleep(2000);
963
820 if (text.Length > 1023) 964 if (text.Length > 1023)
821 text = text.Substring(0, 1023); 965 text = text.Substring(0, 1023);
822 966
@@ -848,22 +992,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 992
849 public void llRegionSayTo(string target, int channel, string msg) 993 public void llRegionSayTo(string target, int channel, string msg)
850 { 994 {
995 string error = String.Empty;
996
851 if (msg.Length > 1023) 997 if (msg.Length > 1023)
852 msg = msg.Substring(0, 1023); 998 msg = msg.Substring(0, 1023);
853 999
854 m_host.AddScriptLPS(1); 1000 m_host.AddScriptLPS(1);
855 1001
856 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
857 {
858 return;
859 }
860
861 UUID TargetID; 1002 UUID TargetID;
862 UUID.TryParse(target, out TargetID); 1003 UUID.TryParse(target, out TargetID);
863 1004
864 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1005 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
865 if (wComm != null) 1006 if (wComm != null)
866 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1007 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1008 LSLError(error);
867 } 1009 }
868 1010
869 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1011 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1119,10 +1261,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1119 return detectedParams.TouchUV; 1261 return detectedParams.TouchUV;
1120 } 1262 }
1121 1263
1264 [DebuggerNonUserCode]
1122 public virtual void llDie() 1265 public virtual void llDie()
1123 { 1266 {
1124 m_host.AddScriptLPS(1); 1267 m_host.AddScriptLPS(1);
1125 throw new SelfDeleteException(); 1268 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1126 } 1269 }
1127 1270
1128 public LSL_Float llGround(LSL_Vector offset) 1271 public LSL_Float llGround(LSL_Vector offset)
@@ -1193,6 +1336,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1193 1336
1194 public void llSetStatus(int status, int value) 1337 public void llSetStatus(int status, int value)
1195 { 1338 {
1339 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1340 return;
1196 m_host.AddScriptLPS(1); 1341 m_host.AddScriptLPS(1);
1197 1342
1198 int statusrotationaxis = 0; 1343 int statusrotationaxis = 0;
@@ -1216,6 +1361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1216 if (!allow) 1361 if (!allow)
1217 return; 1362 return;
1218 1363
1364 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1365 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1366 return;
1367
1219 m_host.ScriptSetPhysicsStatus(true); 1368 m_host.ScriptSetPhysicsStatus(true);
1220 } 1369 }
1221 else 1370 else
@@ -1415,6 +1564,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1415 { 1564 {
1416 m_host.AddScriptLPS(1); 1565 m_host.AddScriptLPS(1);
1417 1566
1567 SetColor(m_host, color, face);
1568 }
1569
1570 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1571 {
1572 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1573 return;
1574
1575 Primitive.TextureEntry tex = part.Shape.Textures;
1576 Color4 texcolor;
1577 if (face >= 0 && face < GetNumberOfSides(part))
1578 {
1579 texcolor = tex.CreateFace((uint)face).RGBA;
1580 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1581 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1582 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1583 tex.FaceTextures[face].RGBA = texcolor;
1584 part.UpdateTextureEntry(tex.GetBytes());
1585 return;
1586 }
1587 else if (face == ScriptBaseClass.ALL_SIDES)
1588 {
1589 for (uint i = 0; i < GetNumberOfSides(part); i++)
1590 {
1591 if (tex.FaceTextures[i] != null)
1592 {
1593 texcolor = tex.FaceTextures[i].RGBA;
1594 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1595 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1596 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1597 tex.FaceTextures[i].RGBA = texcolor;
1598 }
1599 texcolor = tex.DefaultTexture.RGBA;
1600 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1601 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1602 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1603 tex.DefaultTexture.RGBA = texcolor;
1604 }
1605 part.UpdateTextureEntry(tex.GetBytes());
1606 return;
1607 }
1608
1418 if (face == ScriptBaseClass.ALL_SIDES) 1609 if (face == ScriptBaseClass.ALL_SIDES)
1419 face = SceneObjectPart.ALL_SIDES; 1610 face = SceneObjectPart.ALL_SIDES;
1420 1611
@@ -1423,6 +1614,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1614
1424 public void SetTexGen(SceneObjectPart part, int face,int style) 1615 public void SetTexGen(SceneObjectPart part, int face,int style)
1425 { 1616 {
1617 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1618 return;
1619
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1620 Primitive.TextureEntry tex = part.Shape.Textures;
1427 MappingType textype; 1621 MappingType textype;
1428 textype = MappingType.Default; 1622 textype = MappingType.Default;
@@ -1453,6 +1647,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1453 1647
1454 public void SetGlow(SceneObjectPart part, int face, float glow) 1648 public void SetGlow(SceneObjectPart part, int face, float glow)
1455 { 1649 {
1650 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return;
1652
1456 Primitive.TextureEntry tex = part.Shape.Textures; 1653 Primitive.TextureEntry tex = part.Shape.Textures;
1457 if (face >= 0 && face < GetNumberOfSides(part)) 1654 if (face >= 0 && face < GetNumberOfSides(part))
1458 { 1655 {
@@ -1478,6 +1675,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1478 1675
1479 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1676 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1480 { 1677 {
1678 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1679 return;
1481 1680
1482 Shininess sval = new Shininess(); 1681 Shininess sval = new Shininess();
1483 1682
@@ -1528,6 +1727,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1528 1727
1529 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1728 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1530 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1732
1531 Primitive.TextureEntry tex = part.Shape.Textures; 1733 Primitive.TextureEntry tex = part.Shape.Textures;
1532 if (face >= 0 && face < GetNumberOfSides(part)) 1734 if (face >= 0 && face < GetNumberOfSides(part))
1533 { 1735 {
@@ -1588,13 +1790,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1588 m_host.AddScriptLPS(1); 1790 m_host.AddScriptLPS(1);
1589 1791
1590 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1792 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1591 1793 if (parts.Count > 0)
1592 foreach (SceneObjectPart part in parts) 1794 {
1593 SetAlpha(part, alpha, face); 1795 try
1796 {
1797 foreach (SceneObjectPart part in parts)
1798 SetAlpha(part, alpha, face);
1799 }
1800 finally
1801 {
1802 }
1803 }
1594 } 1804 }
1595 1805
1596 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1806 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1597 { 1807 {
1808 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1809 return;
1810
1598 Primitive.TextureEntry tex = part.Shape.Textures; 1811 Primitive.TextureEntry tex = part.Shape.Textures;
1599 Color4 texcolor; 1812 Color4 texcolor;
1600 if (face >= 0 && face < GetNumberOfSides(part)) 1813 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1647,7 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1860 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1648 float wind, float tension, LSL_Vector Force) 1861 float wind, float tension, LSL_Vector Force)
1649 { 1862 {
1650 if (part == null) 1863 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return; 1864 return;
1652 1865
1653 if (flexi) 1866 if (flexi)
@@ -1681,7 +1894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1681 /// <param name="falloff"></param> 1894 /// <param name="falloff"></param>
1682 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1895 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1683 { 1896 {
1684 if (part == null) 1897 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return; 1898 return;
1686 1899
1687 if (light) 1900 if (light)
@@ -1714,11 +1927,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 Primitive.TextureEntry tex = part.Shape.Textures; 1927 Primitive.TextureEntry tex = part.Shape.Textures;
1715 Color4 texcolor; 1928 Color4 texcolor;
1716 LSL_Vector rgb = new LSL_Vector(); 1929 LSL_Vector rgb = new LSL_Vector();
1930 int nsides = GetNumberOfSides(part);
1931
1717 if (face == ScriptBaseClass.ALL_SIDES) 1932 if (face == ScriptBaseClass.ALL_SIDES)
1718 { 1933 {
1719 int i; 1934 int i;
1720 1935 for (i = 0; i < nsides; i++)
1721 for (i = 0 ; i < GetNumberOfSides(part); i++)
1722 { 1936 {
1723 texcolor = tex.GetFace((uint)i).RGBA; 1937 texcolor = tex.GetFace((uint)i).RGBA;
1724 rgb.x += texcolor.R; 1938 rgb.x += texcolor.R;
@@ -1726,14 +1940,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1726 rgb.z += texcolor.B; 1940 rgb.z += texcolor.B;
1727 } 1941 }
1728 1942
1729 rgb.x /= (float)GetNumberOfSides(part); 1943 float invnsides = 1.0f / (float)nsides;
1730 rgb.y /= (float)GetNumberOfSides(part); 1944
1731 rgb.z /= (float)GetNumberOfSides(part); 1945 rgb.x *= invnsides;
1946 rgb.y *= invnsides;
1947 rgb.z *= invnsides;
1732 1948
1733 return rgb; 1949 return rgb;
1734 } 1950 }
1735 1951 if (face >= 0 && face < nsides)
1736 if (face >= 0 && face < GetNumberOfSides(part))
1737 { 1952 {
1738 texcolor = tex.GetFace((uint)face).RGBA; 1953 texcolor = tex.GetFace((uint)face).RGBA;
1739 rgb.x = texcolor.R; 1954 rgb.x = texcolor.R;
@@ -1760,15 +1975,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1760 m_host.AddScriptLPS(1); 1975 m_host.AddScriptLPS(1);
1761 1976
1762 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1977 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1763 1978 if (parts.Count > 0)
1764 foreach (SceneObjectPart part in parts) 1979 {
1765 SetTexture(part, texture, face); 1980 try
1766 1981 {
1982 foreach (SceneObjectPart part in parts)
1983 SetTexture(part, texture, face);
1984 }
1985 finally
1986 {
1987 }
1988 }
1767 ScriptSleep(200); 1989 ScriptSleep(200);
1768 } 1990 }
1769 1991
1770 protected void SetTexture(SceneObjectPart part, string texture, int face) 1992 protected void SetTexture(SceneObjectPart part, string texture, int face)
1771 { 1993 {
1994 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1995 return;
1996
1772 UUID textureID = new UUID(); 1997 UUID textureID = new UUID();
1773 1998
1774 textureID = InventoryKey(texture, (int)AssetType.Texture); 1999 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1813,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2038
1814 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2046 {
@@ -1849,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2077
1850 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2078 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1851 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2085 {
@@ -1885,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 2116
1886 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2117 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1887 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1888 Primitive.TextureEntry tex = part.Shape.Textures; 2122 Primitive.TextureEntry tex = part.Shape.Textures;
1889 if (face >= 0 && face < GetNumberOfSides(part)) 2123 if (face >= 0 && face < GetNumberOfSides(part))
1890 { 2124 {
@@ -2055,24 +2289,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2289 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2056 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2290 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2057 { 2291 {
2058 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2292 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2293 return;
2294
2059 LSL_Vector currentPos = GetPartLocalPos(part); 2295 LSL_Vector currentPos = GetPartLocalPos(part);
2296 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2060 2297
2061 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2062 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2063 2298
2064 if (part.ParentGroup.RootPart == part) 2299 if (part.ParentGroup.RootPart == part)
2065 { 2300 {
2066 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2067 targetPos.z = ground;
2068 SceneObjectGroup parent = part.ParentGroup; 2301 SceneObjectGroup parent = part.ParentGroup;
2069 parent.UpdateGroupPosition(!adjust ? targetPos : 2302 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2070 SetPosAdjust(currentPos, targetPos)); 2303 return;
2304 Util.FireAndForget(delegate(object x) {
2305 parent.UpdateGroupPosition((Vector3)toPos);
2306 });
2071 } 2307 }
2072 else 2308 else
2073 { 2309 {
2074 part.OffsetPosition = !adjust ? targetPos : 2310 part.OffsetPosition = (Vector3)toPos;
2075 SetPosAdjust(currentPos, targetPos);
2076 SceneObjectGroup parent = part.ParentGroup; 2311 SceneObjectGroup parent = part.ParentGroup;
2077 parent.HasGroupChanged = true; 2312 parent.HasGroupChanged = true;
2078 parent.ScheduleGroupForTerseUpdate(); 2313 parent.ScheduleGroupForTerseUpdate();
@@ -2104,13 +2339,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2104 else 2339 else
2105 { 2340 {
2106 if (part.ParentGroup.IsAttachment) 2341 if (part.ParentGroup.IsAttachment)
2107 {
2108 pos = part.AttachedPos; 2342 pos = part.AttachedPos;
2109 }
2110 else 2343 else
2111 {
2112 pos = part.AbsolutePosition; 2344 pos = part.AbsolutePosition;
2113 }
2114 } 2345 }
2115 2346
2116// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2347// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2150,25 +2381,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2150 2381
2151 protected void SetRot(SceneObjectPart part, Quaternion rot) 2382 protected void SetRot(SceneObjectPart part, Quaternion rot)
2152 { 2383 {
2153 part.UpdateRotation(rot); 2384 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2154 // Update rotation does not move the object in the physics scene if it's a linkset. 2385 return;
2155 2386
2156//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2387 bool isroot = (part == part.ParentGroup.RootPart);
2157// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2388 bool isphys;
2158 2389
2159 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2160 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2161 // It's perfectly okay when the object is not an active physical body though.
2162 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2163 // but only if the object is not physial and active. This is important for rotating doors.
2164 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2165 // scene
2166 PhysicsActor pa = part.PhysActor; 2390 PhysicsActor pa = part.PhysActor;
2167 2391
2168 if (pa != null && !pa.IsPhysical) 2392 // keep using physactor ideia of isphysical
2393 // it should be SOP ideia of that
2394 // not much of a issue with ubitODE
2395 if (pa != null && pa.IsPhysical)
2396 isphys = true;
2397 else
2398 isphys = false;
2399
2400 // SL doesn't let scripts rotate root of physical linksets
2401 if (isroot && isphys)
2402 return;
2403
2404 part.UpdateRotation(rot);
2405
2406 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2407 // so do a nasty update of parts positions if is a root part rotation
2408 if (isroot && pa != null) // with if above implies non physical root part
2169 { 2409 {
2170 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2410 part.ParentGroup.ResetChildPrimPhysicsPositions();
2171 } 2411 }
2412 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2413 {
2414 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2415 if (sittingavas.Count > 0)
2416 {
2417 foreach (ScenePresence av in sittingavas)
2418 {
2419 if (isroot || part.LocalId == av.ParentID)
2420 av.SendTerseUpdateToAllClients();
2421 }
2422 }
2423 }
2172 } 2424 }
2173 2425
2174 /// <summary> 2426 /// <summary>
@@ -2216,8 +2468,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2468
2217 public LSL_Rotation llGetLocalRot() 2469 public LSL_Rotation llGetLocalRot()
2218 { 2470 {
2471 return GetPartLocalRot(m_host);
2472 }
2473
2474 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2475 {
2219 m_host.AddScriptLPS(1); 2476 m_host.AddScriptLPS(1);
2220 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2477 Quaternion rot = part.RotationOffset;
2478 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2221 } 2479 }
2222 2480
2223 public void llSetForce(LSL_Vector force, int local) 2481 public void llSetForce(LSL_Vector force, int local)
@@ -2297,16 +2555,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 m_host.ApplyImpulse(v, local != 0); 2555 m_host.ApplyImpulse(v, local != 0);
2298 } 2556 }
2299 2557
2558
2300 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2559 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2301 { 2560 {
2302 m_host.AddScriptLPS(1); 2561 m_host.AddScriptLPS(1);
2303 m_host.ApplyAngularImpulse(force, local != 0); 2562 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2304 } 2563 }
2305 2564
2306 public void llSetTorque(LSL_Vector torque, int local) 2565 public void llSetTorque(LSL_Vector torque, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.SetAngularImpulse(torque, local != 0); 2568 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2310 } 2569 }
2311 2570
2312 public LSL_Vector llGetTorque() 2571 public LSL_Vector llGetTorque()
@@ -2323,20 +2582,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2323 llSetTorque(torque, local); 2582 llSetTorque(torque, local);
2324 } 2583 }
2325 2584
2585 public void llSetVelocity(LSL_Vector vel, int local)
2586 {
2587 m_host.AddScriptLPS(1);
2588 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2589 }
2590
2326 public LSL_Vector llGetVel() 2591 public LSL_Vector llGetVel()
2327 { 2592 {
2328 m_host.AddScriptLPS(1); 2593 m_host.AddScriptLPS(1);
2329 2594
2330 Vector3 vel; 2595 Vector3 vel = Vector3.Zero;
2331 2596
2332 if (m_host.ParentGroup.IsAttachment) 2597 if (m_host.ParentGroup.IsAttachment)
2333 { 2598 {
2334 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2599 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2335 vel = avatar.Velocity; 2600 if (avatar != null)
2601 vel = avatar.Velocity;
2336 } 2602 }
2337 else 2603 else
2338 { 2604 {
2339 vel = m_host.Velocity; 2605 vel = m_host.ParentGroup.RootPart.Velocity;
2340 } 2606 }
2341 2607
2342 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2608 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2348,10 +2614,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2348 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2614 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2349 } 2615 }
2350 2616
2617 public void llSetAngularVelocity(LSL_Vector avel, int local)
2618 {
2619 m_host.AddScriptLPS(1);
2620 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2621 }
2622
2351 public LSL_Vector llGetOmega() 2623 public LSL_Vector llGetOmega()
2352 { 2624 {
2353 m_host.AddScriptLPS(1); 2625 m_host.AddScriptLPS(1);
2354 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2626 Vector3 avel = m_host.AngularVelocity;
2627 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2355 } 2628 }
2356 2629
2357 public LSL_Float llGetTimeOfDay() 2630 public LSL_Float llGetTimeOfDay()
@@ -2824,16 +3097,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 new_group.RootPart.UUID.ToString()) }, 3097 new_group.RootPart.UUID.ToString()) },
2825 new DetectParams[0])); 3098 new DetectParams[0]));
2826 3099
2827 float groupmass = new_group.GetMass(); 3100 // do recoil
3101 SceneObjectGroup hostgrp = m_host.ParentGroup;
3102 if (hostgrp == null)
3103 return;
3104
3105 if (hostgrp.IsAttachment) // don't recoil avatars
3106 return;
2828 3107
2829 PhysicsActor pa = new_group.RootPart.PhysActor; 3108 PhysicsActor pa = new_group.RootPart.PhysActor;
2830 3109
2831 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3110 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2832 { 3111 {
2833 //Recoil. 3112 float groupmass = new_group.GetMass();
2834 llApplyImpulse(vel * groupmass, 0); 3113 vel *= -groupmass;
3114 llApplyImpulse(vel, 0);
2835 } 3115 }
2836 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3116 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3117 return;
3118
2837 }); 3119 });
2838 3120
2839 //ScriptSleep((int)((groupmass * velmag) / 10)); 3121 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2848,35 +3130,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2848 public void llLookAt(LSL_Vector target, double strength, double damping) 3130 public void llLookAt(LSL_Vector target, double strength, double damping)
2849 { 3131 {
2850 m_host.AddScriptLPS(1); 3132 m_host.AddScriptLPS(1);
2851 // Determine where we are looking from
2852 LSL_Vector from = llGetPos();
2853 3133
2854 // Work out the normalised vector from the source to the target 3134 // Get the normalized vector to the target
2855 LSL_Vector delta = llVecNorm(target - from); 3135 LSL_Vector d1 = llVecNorm(target - llGetPos());
2856 LSL_Vector angle = new LSL_Vector(0,0,0);
2857 3136
2858 // Calculate the yaw 3137 // Get the bearing (yaw)
2859 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3138 LSL_Vector a1 = new LSL_Vector(0,0,0);
2860 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3139 a1.z = llAtan2(d1.y, d1.x);
2861 3140
2862 // Calculate pitch 3141 // Get the elevation (pitch)
2863 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3142 LSL_Vector a2 = new LSL_Vector(0,0,0);
3143 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2864 3144
2865 // we need to convert from a vector describing 3145 LSL_Rotation r1 = llEuler2Rot(a1);
2866 // the angles of rotation in radians into rotation value 3146 LSL_Rotation r2 = llEuler2Rot(a2);
2867 LSL_Rotation rot = llEuler2Rot(angle); 3147 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2868
2869 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2870 // set the rotation of the object, copy that behavior
2871 PhysicsActor pa = m_host.PhysActor;
2872 3148
2873 if (strength == 0 || pa == null || !pa.IsPhysical) 3149 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2874 { 3150 {
2875 llSetRot(rot); 3151 // Do nothing if either value is 0 (this has been checked in SL)
3152 if (strength <= 0.0 || damping <= 0.0)
3153 return;
3154
3155 llSetRot(r3 * r2 * r1);
2876 } 3156 }
2877 else 3157 else
2878 { 3158 {
2879 m_host.StartLookAt(rot, (float)strength, (float)damping); 3159 if (strength == 0)
3160 {
3161 llSetRot(r3 * r2 * r1);
3162 return;
3163 }
3164
3165 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2880 } 3166 }
2881 } 3167 }
2882 3168
@@ -2922,17 +3208,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 } 3208 }
2923 else 3209 else
2924 { 3210 {
2925 if (m_host.IsRoot) 3211 // new SL always returns object mass
2926 { 3212// if (m_host.IsRoot)
3213// {
2927 return m_host.ParentGroup.GetMass(); 3214 return m_host.ParentGroup.GetMass();
2928 } 3215// }
2929 else 3216// else
2930 { 3217// {
2931 return m_host.GetMass(); 3218// return m_host.GetMass();
2932 } 3219// }
2933 } 3220 }
2934 } 3221 }
2935 3222
3223
3224 public LSL_Float llGetMassMKS()
3225 {
3226 return 100f * llGetMass();
3227 }
3228
2936 public void llCollisionFilter(string name, string id, int accept) 3229 public void llCollisionFilter(string name, string id, int accept)
2937 { 3230 {
2938 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
@@ -2980,8 +3273,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 { 3273 {
2981 // Unregister controls from Presence 3274 // Unregister controls from Presence
2982 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3275 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2983 // Remove Take Control permission.
2984 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2985 } 3276 }
2986 } 3277 }
2987 } 3278 }
@@ -3007,7 +3298,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3007 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3298 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3008 3299
3009 if (attachmentsModule != null) 3300 if (attachmentsModule != null)
3010 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3301 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3011 else 3302 else
3012 return false; 3303 return false;
3013 } 3304 }
@@ -3037,9 +3328,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 { 3328 {
3038 m_host.AddScriptLPS(1); 3329 m_host.AddScriptLPS(1);
3039 3330
3040// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3041// return;
3042
3043 if (m_item.PermsGranter != m_host.OwnerID) 3331 if (m_item.PermsGranter != m_host.OwnerID)
3044 return; 3332 return;
3045 3333
@@ -3082,6 +3370,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 3370
3083 public void llInstantMessage(string user, string message) 3371 public void llInstantMessage(string user, string message)
3084 { 3372 {
3373 UUID result;
3374 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3375 {
3376 ShoutError("An invalid key was passed to llInstantMessage");
3377 ScriptSleep(2000);
3378 return;
3379 }
3380
3381
3085 m_host.AddScriptLPS(1); 3382 m_host.AddScriptLPS(1);
3086 3383
3087 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3384 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3096,14 +3393,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3096 UUID friendTransactionID = UUID.Random(); 3393 UUID friendTransactionID = UUID.Random();
3097 3394
3098 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3395 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3099 3396
3100 GridInstantMessage msg = new GridInstantMessage(); 3397 GridInstantMessage msg = new GridInstantMessage();
3101 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3398 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3102 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3399 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3103 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3400 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3104// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3401// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3105// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3402// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3106 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3403// DateTime dt = DateTime.UtcNow;
3404//
3405// // Ticks from UtcNow, but make it look like local. Evil, huh?
3406// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3407//
3408// try
3409// {
3410// // Convert that to the PST timezone
3411// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3412// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3413// }
3414// catch
3415// {
3416// // No logging here, as it could be VERY spammy
3417// }
3418//
3419// // And make it look local again to fool the unix time util
3420// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3421
3422 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3423
3107 //if (client != null) 3424 //if (client != null)
3108 //{ 3425 //{
3109 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3426 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3117,12 +3434,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3117 msg.message = message.Substring(0, 1024); 3434 msg.message = message.Substring(0, 1024);
3118 else 3435 else
3119 msg.message = message; 3436 msg.message = message;
3120 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3437 msg.dialog = (byte)19; // MessageFromObject
3121 msg.fromGroup = false;// fromGroup; 3438 msg.fromGroup = false;// fromGroup;
3122 msg.offline = (byte)0; //offline; 3439 msg.offline = (byte)0; //offline;
3123 msg.ParentEstateID = 0; //ParentEstateID; 3440 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3124 msg.Position = new Vector3(m_host.AbsolutePosition); 3441 msg.Position = new Vector3(m_host.AbsolutePosition);
3125 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3442 msg.RegionID = World.RegionInfo.RegionID.Guid;
3126 msg.binaryBucket 3443 msg.binaryBucket
3127 = Util.StringToBytes256( 3444 = Util.StringToBytes256(
3128 "{0}/{1}/{2}/{3}", 3445 "{0}/{1}/{2}/{3}",
@@ -3150,7 +3467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3150 } 3467 }
3151 3468
3152 emailModule.SendEmail(m_host.UUID, address, subject, message); 3469 emailModule.SendEmail(m_host.UUID, address, subject, message);
3153 llSleep(EMAIL_PAUSE_TIME); 3470 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3154 } 3471 }
3155 3472
3156 public void llGetNextEmail(string address, string subject) 3473 public void llGetNextEmail(string address, string subject)
@@ -3396,7 +3713,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3396 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3713 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3397 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3714 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3398 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3715 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3716 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3399 ScriptBaseClass.PERMISSION_ATTACH; 3717 ScriptBaseClass.PERMISSION_ATTACH;
3718
3400 } 3719 }
3401 else 3720 else
3402 { 3721 {
@@ -3427,15 +3746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3427 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3746 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3428 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3747 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3429 } 3748 }
3749 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3750 {
3751 implicitPerms = perm;
3752 }
3430 } 3753 }
3431 3754
3432 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3755 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3433 { 3756 {
3434 lock (m_host.TaskInventory) 3757 m_host.TaskInventory.LockItemsForWrite(true);
3435 { 3758 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3436 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3759 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3437 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3760 m_host.TaskInventory.LockItemsForWrite(false);
3438 }
3439 3761
3440 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3762 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3441 "run_time_permissions", new Object[] { 3763 "run_time_permissions", new Object[] {
@@ -3478,11 +3800,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 3800
3479 if (!m_waitingForScriptAnswer) 3801 if (!m_waitingForScriptAnswer)
3480 { 3802 {
3481 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForWrite(true);
3482 { 3804 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3483 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3805 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3484 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3806 m_host.TaskInventory.LockItemsForWrite(false);
3485 }
3486 3807
3487 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3808 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3488 m_waitingForScriptAnswer=true; 3809 m_waitingForScriptAnswer=true;
@@ -3511,14 +3832,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3832 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3512 llReleaseControls(); 3833 llReleaseControls();
3513 3834
3514 lock (m_host.TaskInventory) 3835 m_host.TaskInventory.LockItemsForWrite(true);
3515 { 3836 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3516 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3837 m_host.TaskInventory.LockItemsForWrite(false);
3517 } 3838
3518 3839 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3519 m_ScriptEngine.PostScriptEvent( 3840 "run_time_permissions", new Object[] {
3520 m_item.ItemID, 3841 new LSL_Integer(answer) },
3521 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3842 new DetectParams[0]));
3522 } 3843 }
3523 3844
3524 public LSL_String llGetPermissionsKey() 3845 public LSL_String llGetPermissionsKey()
@@ -3557,14 +3878,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3557 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3878 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3558 { 3879 {
3559 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3880 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3560 3881 if (parts.Count > 0)
3561 foreach (SceneObjectPart part in parts) 3882 {
3562 part.SetFaceColorAlpha(face, color, null); 3883 try
3884 {
3885 foreach (SceneObjectPart part in parts)
3886 part.SetFaceColorAlpha(face, color, null);
3887 }
3888 finally
3889 {
3890 }
3891 }
3563 } 3892 }
3564 3893
3565 public void llCreateLink(string target, int parent) 3894 public void llCreateLink(string target, int parent)
3566 { 3895 {
3567 m_host.AddScriptLPS(1); 3896 m_host.AddScriptLPS(1);
3897
3568 UUID targetID; 3898 UUID targetID;
3569 3899
3570 if (!UUID.TryParse(target, out targetID)) 3900 if (!UUID.TryParse(target, out targetID))
@@ -3670,10 +4000,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3670 // Restructuring Multiple Prims. 4000 // Restructuring Multiple Prims.
3671 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4001 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3672 parts.Remove(parentPrim.RootPart); 4002 parts.Remove(parentPrim.RootPart);
3673 foreach (SceneObjectPart part in parts) 4003 if (parts.Count > 0)
3674 { 4004 {
3675 parentPrim.DelinkFromGroup(part.LocalId, true); 4005 try
4006 {
4007 foreach (SceneObjectPart part in parts)
4008 {
4009 parentPrim.DelinkFromGroup(part.LocalId, true);
4010 }
4011 }
4012 finally
4013 {
4014 }
3676 } 4015 }
4016
3677 parentPrim.HasGroupChanged = true; 4017 parentPrim.HasGroupChanged = true;
3678 parentPrim.ScheduleGroupForFullUpdate(); 4018 parentPrim.ScheduleGroupForFullUpdate();
3679 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4019 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3682,12 +4022,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 { 4022 {
3683 SceneObjectPart newRoot = parts[0]; 4023 SceneObjectPart newRoot = parts[0];
3684 parts.Remove(newRoot); 4024 parts.Remove(newRoot);
3685 foreach (SceneObjectPart part in parts) 4025
4026 try
3686 { 4027 {
3687 // Required for linking 4028 foreach (SceneObjectPart part in parts)
3688 part.ClearUpdateSchedule(); 4029 {
3689 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4030 part.ClearUpdateSchedule();
4031 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4032 }
3690 } 4033 }
4034 finally
4035 {
4036 }
4037
4038
3691 newRoot.ParentGroup.HasGroupChanged = true; 4039 newRoot.ParentGroup.HasGroupChanged = true;
3692 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4040 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3693 } 4041 }
@@ -3707,6 +4055,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 public void llBreakAllLinks() 4055 public void llBreakAllLinks()
3708 { 4056 {
3709 m_host.AddScriptLPS(1); 4057 m_host.AddScriptLPS(1);
4058
4059 TaskInventoryItem item = m_item;
4060
4061 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4062 && !m_automaticLinkPermission)
4063 {
4064 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4065 return;
4066 }
4067
3710 SceneObjectGroup parentPrim = m_host.ParentGroup; 4068 SceneObjectGroup parentPrim = m_host.ParentGroup;
3711 if (parentPrim.AttachmentPoint != 0) 4069 if (parentPrim.AttachmentPoint != 0)
3712 return; // Fail silently if attached 4070 return; // Fail silently if attached
@@ -3726,25 +4084,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 public LSL_String llGetLinkKey(int linknum) 4084 public LSL_String llGetLinkKey(int linknum)
3727 { 4085 {
3728 m_host.AddScriptLPS(1); 4086 m_host.AddScriptLPS(1);
3729 List<UUID> keytable = new List<UUID>();
3730 // parse for sitting avatare-uuids
3731 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3732 {
3733 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3734 keytable.Add(presence.UUID);
3735 });
3736
3737 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3738 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3739 {
3740 return keytable[totalprims - linknum].ToString();
3741 }
3742
3743 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3744 {
3745 return m_host.UUID.ToString();
3746 }
3747
3748 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4087 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3749 if (part != null) 4088 if (part != null)
3750 { 4089 {
@@ -3752,6 +4091,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3752 } 4091 }
3753 else 4092 else
3754 { 4093 {
4094 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4095 {
4096 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4097
4098 if (linknum < 0)
4099 return UUID.Zero.ToString();
4100
4101 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4102 if (avatars.Count > linknum)
4103 {
4104 return avatars[linknum].UUID.ToString();
4105 }
4106 }
3755 return UUID.Zero.ToString(); 4107 return UUID.Zero.ToString();
3756 } 4108 }
3757 } 4109 }
@@ -3861,17 +4213,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3861 m_host.AddScriptLPS(1); 4213 m_host.AddScriptLPS(1);
3862 int count = 0; 4214 int count = 0;
3863 4215
3864 lock (m_host.TaskInventory) 4216 m_host.TaskInventory.LockItemsForRead(true);
4217 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3865 { 4218 {
3866 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4219 if (inv.Value.Type == type || type == -1)
3867 { 4220 {
3868 if (inv.Value.Type == type || type == -1) 4221 count = count + 1;
3869 {
3870 count = count + 1;
3871 }
3872 } 4222 }
3873 } 4223 }
3874 4224
4225 m_host.TaskInventory.LockItemsForRead(false);
3875 return count; 4226 return count;
3876 } 4227 }
3877 4228
@@ -3880,16 +4231,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3880 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3881 ArrayList keys = new ArrayList(); 4232 ArrayList keys = new ArrayList();
3882 4233
3883 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3884 { 4236 {
3885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Type == type || type == -1)
3886 { 4238 {
3887 if (inv.Value.Type == type || type == -1) 4239 keys.Add(inv.Value.Name);
3888 {
3889 keys.Add(inv.Value.Name);
3890 }
3891 } 4240 }
3892 } 4241 }
4242 m_host.TaskInventory.LockItemsForRead(false);
3893 4243
3894 if (keys.Count == 0) 4244 if (keys.Count == 0)
3895 { 4245 {
@@ -3927,7 +4277,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 if (item == null) 4277 if (item == null)
3928 { 4278 {
3929 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4279 llSay(0, String.Format("Could not find object '{0}'", inventory));
3930 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4280 return;
4281// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3931 } 4282 }
3932 4283
3933 UUID objId = item.ItemID; 4284 UUID objId = item.ItemID;
@@ -3955,33 +4306,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 return; 4306 return;
3956 } 4307 }
3957 } 4308 }
4309
3958 // destination is an avatar 4310 // destination is an avatar
3959 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4311 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3960 4312
3961 if (agentItem == null) 4313 if (agentItem == null)
3962 return; 4314 return;
3963 4315
3964 if (m_TransferModule != null) 4316 byte[] bucket = new byte[1];
3965 { 4317 bucket[0] = (byte)item.Type;
3966 byte[] bucket = new byte[] { (byte)item.Type }; 4318 //byte[] objBytes = agentItem.ID.GetBytes();
4319 //Array.Copy(objBytes, 0, bucket, 1, 16);
3967 4320
3968 GridInstantMessage msg = new GridInstantMessage(World, 4321 GridInstantMessage msg = new GridInstantMessage(World,
3969 m_host.UUID, m_host.Name + ", an object owned by " + 4322 m_host.OwnerID, m_host.Name, destId,
3970 resolveName(m_host.OwnerID) + ",", destId, 4323 (byte)InstantMessageDialog.TaskInventoryOffered,
3971 (byte)InstantMessageDialog.TaskInventoryOffered, 4324 false, item.Name+". "+m_host.Name+" is located at "+
3972 false, item.Name + "\n" + m_host.Name + " is located at " + 4325 World.RegionInfo.RegionName+" "+
3973 World.RegionInfo.RegionName+" "+ 4326 m_host.AbsolutePosition.ToString(),
3974 m_host.AbsolutePosition.ToString(), 4327 agentItem.ID, true, m_host.AbsolutePosition,
3975 agentItem.ID, true, m_host.AbsolutePosition, 4328 bucket, true);
3976 bucket, true); // TODO: May actually send no timestamp
3977 4329
3978 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4330 ScenePresence sp;
3979 }
3980 4331
4332 if (World.TryGetScenePresence(destId, out sp))
4333 {
4334 sp.ControllingClient.SendInstantMessage(msg);
4335 }
4336 else
4337 {
4338 if (m_TransferModule != null)
4339 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4340 }
4341
4342 //This delay should only occur when giving inventory to avatars.
3981 ScriptSleep(3000); 4343 ScriptSleep(3000);
3982 } 4344 }
3983 } 4345 }
3984 4346
4347 [DebuggerNonUserCode]
3985 public void llRemoveInventory(string name) 4348 public void llRemoveInventory(string name)
3986 { 4349 {
3987 m_host.AddScriptLPS(1); 4350 m_host.AddScriptLPS(1);
@@ -4036,109 +4399,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4036 { 4399 {
4037 m_host.AddScriptLPS(1); 4400 m_host.AddScriptLPS(1);
4038 4401
4039 UUID uuid = (UUID)id; 4402 UUID uuid;
4040 PresenceInfo pinfo = null; 4403 if (UUID.TryParse(id, out uuid))
4041 UserAccount account;
4042
4043 UserInfoCacheEntry ce;
4044 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4045 { 4404 {
4046 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4405 PresenceInfo pinfo = null;
4047 if (account == null) 4406 UserAccount account;
4407
4408 UserInfoCacheEntry ce;
4409 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4048 { 4410 {
4049 m_userInfoCache[uuid] = null; // Cache negative 4411 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4050 return UUID.Zero.ToString(); 4412 if (account == null)
4051 } 4413 {
4414 m_userInfoCache[uuid] = null; // Cache negative
4415 return UUID.Zero.ToString();
4416 }
4052 4417
4053 4418
4054 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4419 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4055 if (pinfos != null && pinfos.Length > 0) 4420 if (pinfos != null && pinfos.Length > 0)
4056 {
4057 foreach (PresenceInfo p in pinfos)
4058 { 4421 {
4059 if (p.RegionID != UUID.Zero) 4422 foreach (PresenceInfo p in pinfos)
4060 { 4423 {
4061 pinfo = p; 4424 if (p.RegionID != UUID.Zero)
4425 {
4426 pinfo = p;
4427 }
4062 } 4428 }
4063 } 4429 }
4064 }
4065 4430
4066 ce = new UserInfoCacheEntry(); 4431 ce = new UserInfoCacheEntry();
4067 ce.time = Util.EnvironmentTickCount(); 4432 ce.time = Util.EnvironmentTickCount();
4068 ce.account = account; 4433 ce.account = account;
4069 ce.pinfo = pinfo; 4434 ce.pinfo = pinfo;
4070 } 4435 m_userInfoCache[uuid] = ce;
4071 else 4436 }
4072 { 4437 else
4073 if (ce == null) 4438 {
4074 return UUID.Zero.ToString(); 4439 if (ce == null)
4440 return UUID.Zero.ToString();
4075 4441
4076 account = ce.account; 4442 account = ce.account;
4077 pinfo = ce.pinfo; 4443 pinfo = ce.pinfo;
4078 } 4444 }
4079 4445
4080 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4446 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4081 {
4082 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4083 if (pinfos != null && pinfos.Length > 0)
4084 { 4447 {
4085 foreach (PresenceInfo p in pinfos) 4448 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4449 if (pinfos != null && pinfos.Length > 0)
4086 { 4450 {
4087 if (p.RegionID != UUID.Zero) 4451 foreach (PresenceInfo p in pinfos)
4088 { 4452 {
4089 pinfo = p; 4453 if (p.RegionID != UUID.Zero)
4454 {
4455 pinfo = p;
4456 }
4090 } 4457 }
4091 } 4458 }
4092 } 4459 else
4093 else 4460 pinfo = null;
4094 pinfo = null;
4095 4461
4096 ce.time = Util.EnvironmentTickCount(); 4462 ce.time = Util.EnvironmentTickCount();
4097 ce.pinfo = pinfo; 4463 ce.pinfo = pinfo;
4098 } 4464 }
4099 4465
4100 string reply = String.Empty; 4466 string reply = String.Empty;
4101 4467
4102 switch (data) 4468 switch (data)
4103 { 4469 {
4104 case 1: // DATA_ONLINE (0|1) 4470 case 1: // DATA_ONLINE (0|1)
4105 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4471 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4106 reply = "1"; 4472 reply = "1";
4107 else 4473 else
4108 reply = "0"; 4474 reply = "0";
4109 break; 4475 break;
4110 case 2: // DATA_NAME (First Last) 4476 case 2: // DATA_NAME (First Last)
4111 reply = account.FirstName + " " + account.LastName; 4477 reply = account.FirstName + " " + account.LastName;
4112 break; 4478 break;
4113 case 3: // DATA_BORN (YYYY-MM-DD) 4479 case 3: // DATA_BORN (YYYY-MM-DD)
4114 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4480 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4115 born = born.AddSeconds(account.Created); 4481 born = born.AddSeconds(account.Created);
4116 reply = born.ToString("yyyy-MM-dd"); 4482 reply = born.ToString("yyyy-MM-dd");
4117 break; 4483 break;
4118 case 4: // DATA_RATING (0,0,0,0,0,0) 4484 case 4: // DATA_RATING (0,0,0,0,0,0)
4119 reply = "0,0,0,0,0,0"; 4485 reply = "0,0,0,0,0,0";
4120 break; 4486 break;
4121 case 7: // DATA_USERLEVEL (integer) 4487 case 8: // DATA_PAYINFO (0|1|2|3)
4122 reply = account.UserLevel.ToString(); 4488 reply = "0";
4123 break; 4489 break;
4124 case 8: // DATA_PAYINFO (0|1|2|3) 4490 default:
4125 reply = "0"; 4491 return UUID.Zero.ToString(); // Raise no event
4126 break; 4492 }
4127 default:
4128 return UUID.Zero.ToString(); // Raise no event
4129 }
4130 4493
4131 UUID rq = UUID.Random(); 4494 UUID rq = UUID.Random();
4132 4495
4133 UUID tid = AsyncCommands. 4496 UUID tid = AsyncCommands.
4134 DataserverPlugin.RegisterRequest(m_host.LocalId, 4497 DataserverPlugin.RegisterRequest(m_host.LocalId,
4135 m_item.ItemID, rq.ToString()); 4498 m_item.ItemID, rq.ToString());
4136 4499
4137 AsyncCommands. 4500 AsyncCommands.
4138 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4501 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4139 4502
4140 ScriptSleep(100); 4503 ScriptSleep(100);
4141 return tid.ToString(); 4504 return tid.ToString();
4505 }
4506 else
4507 {
4508 ShoutError("Invalid UUID passed to llRequestAgentData.");
4509 }
4510 return "";
4142 } 4511 }
4143 4512
4144 public LSL_String llRequestInventoryData(string name) 4513 public LSL_String llRequestInventoryData(string name)
@@ -4195,13 +4564,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4195 if (UUID.TryParse(agent, out agentId)) 4564 if (UUID.TryParse(agent, out agentId))
4196 { 4565 {
4197 ScenePresence presence = World.GetScenePresence(agentId); 4566 ScenePresence presence = World.GetScenePresence(agentId);
4198 if (presence != null) 4567 if (presence != null && presence.PresenceType != PresenceType.Npc)
4199 { 4568 {
4569 // agent must not be a god
4570 if (presence.UserLevel >= 200) return;
4571
4200 // agent must be over the owners land 4572 // agent must be over the owners land
4201 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4573 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4202 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4574 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4203 { 4575 {
4204 World.TeleportClientHome(agentId, presence.ControllingClient); 4576 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4577 {
4578 // They can't be teleported home for some reason
4579 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4580 if (regionInfo != null)
4581 {
4582 World.RequestTeleportLocation(
4583 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4584 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4585 }
4586 }
4205 } 4587 }
4206 } 4588 }
4207 } 4589 }
@@ -4308,7 +4690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4308 UUID av = new UUID(); 4690 UUID av = new UUID();
4309 if (!UUID.TryParse(agent,out av)) 4691 if (!UUID.TryParse(agent,out av))
4310 { 4692 {
4311 LSLError("First parameter to llDialog needs to be a key"); 4693 //LSLError("First parameter to llDialog needs to be a key");
4312 return; 4694 return;
4313 } 4695 }
4314 4696
@@ -4340,10 +4722,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4340 public void llCollisionSound(string impact_sound, double impact_volume) 4722 public void llCollisionSound(string impact_sound, double impact_volume)
4341 { 4723 {
4342 m_host.AddScriptLPS(1); 4724 m_host.AddScriptLPS(1);
4343 4725
4726 if(impact_sound == "")
4727 {
4728 m_host.CollisionSoundVolume = (float)impact_volume;
4729 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4730 m_host.CollisionSoundType = 0;
4731 return;
4732 }
4344 // TODO: Parameter check logic required. 4733 // TODO: Parameter check logic required.
4345 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4734 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4346 m_host.CollisionSoundVolume = (float)impact_volume; 4735 m_host.CollisionSoundVolume = (float)impact_volume;
4736 m_host.CollisionSoundType = 1;
4347 } 4737 }
4348 4738
4349 public LSL_String llGetAnimation(string id) 4739 public LSL_String llGetAnimation(string id)
@@ -4357,14 +4747,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4357 4747
4358 if (m_host.RegionHandle == presence.RegionHandle) 4748 if (m_host.RegionHandle == presence.RegionHandle)
4359 { 4749 {
4360 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4361
4362 if (presence != null) 4750 if (presence != null)
4363 { 4751 {
4364 AnimationSet currentAnims = presence.Animator.Animations; 4752 if (presence.SitGround)
4365 string currentAnimationState = String.Empty; 4753 return "Sitting on Ground";
4366 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4754 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4367 return currentAnimationState; 4755 return "Sitting";
4756
4757 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4758 string lslMovementAnimation;
4759
4760 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4761 return lslMovementAnimation;
4368 } 4762 }
4369 } 4763 }
4370 4764
@@ -4511,7 +4905,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4511 { 4905 {
4512 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4906 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4513 float distance_term = distance * distance * distance; // Script Energy 4907 float distance_term = distance * distance * distance; // Script Energy
4514 float pusher_mass = m_host.GetMass(); 4908 // use total object mass and not part
4909 float pusher_mass = m_host.ParentGroup.GetMass();
4515 4910
4516 float PUSH_ATTENUATION_DISTANCE = 17f; 4911 float PUSH_ATTENUATION_DISTANCE = 17f;
4517 float PUSH_ATTENUATION_SCALE = 5f; 4912 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4761,6 +5156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5156 {
4762 return item.AssetID.ToString(); 5157 return item.AssetID.ToString();
4763 } 5158 }
5159 m_host.TaskInventory.LockItemsForRead(false);
4764 5160
4765 return UUID.Zero.ToString(); 5161 return UUID.Zero.ToString();
4766 } 5162 }
@@ -4894,7 +5290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4894 public LSL_Vector llGetCenterOfMass() 5290 public LSL_Vector llGetCenterOfMass()
4895 { 5291 {
4896 m_host.AddScriptLPS(1); 5292 m_host.AddScriptLPS(1);
4897 Vector3 center = m_host.GetGeometricCenter(); 5293 Vector3 center = m_host.GetCenterOfMass();
4898 return new LSL_Vector(center.X,center.Y,center.Z); 5294 return new LSL_Vector(center.X,center.Y,center.Z);
4899 } 5295 }
4900 5296
@@ -4913,14 +5309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4913 { 5309 {
4914 m_host.AddScriptLPS(1); 5310 m_host.AddScriptLPS(1);
4915 5311
4916 if (src == null) 5312 return src.Length;
4917 {
4918 return 0;
4919 }
4920 else
4921 {
4922 return src.Length;
4923 }
4924 } 5313 }
4925 5314
4926 public LSL_Integer llList2Integer(LSL_List src, int index) 5315 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4991,7 +5380,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4991 else if (src.Data[index] is LSL_Float) 5380 else if (src.Data[index] is LSL_Float)
4992 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5381 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4993 else if (src.Data[index] is LSL_String) 5382 else if (src.Data[index] is LSL_String)
4994 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5383 {
5384 string str = ((LSL_String) src.Data[index]).m_string;
5385 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5386 if (m != Match.Empty)
5387 {
5388 str = m.Value;
5389 double d = 0.0;
5390 if (!Double.TryParse(str, out d))
5391 return 0.0;
5392
5393 return d;
5394 }
5395 return 0.0;
5396 }
4995 return Convert.ToDouble(src.Data[index]); 5397 return Convert.ToDouble(src.Data[index]);
4996 } 5398 }
4997 catch (FormatException) 5399 catch (FormatException)
@@ -5033,7 +5435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5033 // for completion and should LSL_Key ever be implemented 5435 // for completion and should LSL_Key ever be implemented
5034 // as it's own struct 5436 // as it's own struct
5035 else if (!(src.Data[index] is LSL_String || 5437 else if (!(src.Data[index] is LSL_String ||
5036 src.Data[index] is LSL_Key)) 5438 src.Data[index] is LSL_Key ||
5439 src.Data[index] is String))
5037 { 5440 {
5038 return ""; 5441 return "";
5039 } 5442 }
@@ -5291,7 +5694,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5291 } 5694 }
5292 } 5695 }
5293 } 5696 }
5294 else { 5697 else
5698 {
5295 object[] array = new object[src.Length]; 5699 object[] array = new object[src.Length];
5296 Array.Copy(src.Data, 0, array, 0, src.Length); 5700 Array.Copy(src.Data, 0, array, 0, src.Length);
5297 result = new LSL_List(array); 5701 result = new LSL_List(array);
@@ -5398,7 +5802,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5398 public LSL_Integer llGetRegionAgentCount() 5802 public LSL_Integer llGetRegionAgentCount()
5399 { 5803 {
5400 m_host.AddScriptLPS(1); 5804 m_host.AddScriptLPS(1);
5401 return new LSL_Integer(World.GetRootAgentCount()); 5805
5806 int count = 0;
5807 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5808 count++;
5809 });
5810
5811 return new LSL_Integer(count);
5402 } 5812 }
5403 5813
5404 public LSL_Vector llGetRegionCorner() 5814 public LSL_Vector llGetRegionCorner()
@@ -5639,6 +6049,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5639 flags |= ScriptBaseClass.AGENT_AWAY; 6049 flags |= ScriptBaseClass.AGENT_AWAY;
5640 } 6050 }
5641 6051
6052 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6053 UUID[] anims = agent.Animator.GetAnimationArray();
6054 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6055 {
6056 flags |= ScriptBaseClass.AGENT_BUSY;
6057 }
6058
5642 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6059 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5643 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6060 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5644 { 6061 {
@@ -5686,6 +6103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5686 flags |= ScriptBaseClass.AGENT_SITTING; 6103 flags |= ScriptBaseClass.AGENT_SITTING;
5687 } 6104 }
5688 6105
6106 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6107 {
6108 flags |= ScriptBaseClass.AGENT_MALE;
6109 }
6110
5689 return flags; 6111 return flags;
5690 } 6112 }
5691 6113
@@ -5833,9 +6255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5833 6255
5834 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6256 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5835 6257
5836 foreach (SceneObjectPart part in parts) 6258 try
6259 {
6260 foreach (SceneObjectPart part in parts)
6261 {
6262 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6263 }
6264 }
6265 finally
5837 { 6266 {
5838 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5839 } 6267 }
5840 } 6268 }
5841 6269
@@ -5889,13 +6317,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5889 6317
5890 if (m_host.OwnerID == land.LandData.OwnerID) 6318 if (m_host.OwnerID == land.LandData.OwnerID)
5891 { 6319 {
5892 World.TeleportClientHome(agentID, presence.ControllingClient); 6320 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6321 presence.TeleportWithMomentum(pos, null);
6322 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5893 } 6323 }
5894 } 6324 }
5895 } 6325 }
5896 ScriptSleep(5000); 6326 ScriptSleep(5000);
5897 } 6327 }
5898 6328
6329 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6330 {
6331 return ParseString2List(str, separators, in_spacers, false);
6332 }
6333
5899 public LSL_Integer llOverMyLand(string id) 6334 public LSL_Integer llOverMyLand(string id)
5900 { 6335 {
5901 m_host.AddScriptLPS(1); 6336 m_host.AddScriptLPS(1);
@@ -5954,20 +6389,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5954 return agentSize; 6389 return agentSize;
5955 } 6390 }
5956 6391
5957 public LSL_Integer llSameGroup(string agent) 6392 public LSL_Integer llSameGroup(string id)
5958 { 6393 {
5959 m_host.AddScriptLPS(1); 6394 m_host.AddScriptLPS(1);
5960 UUID agentId = new UUID(); 6395 UUID uuid = new UUID();
5961 if (!UUID.TryParse(agent, out agentId)) 6396 if (!UUID.TryParse(id, out uuid))
5962 return new LSL_Integer(0);
5963 ScenePresence presence = World.GetScenePresence(agentId);
5964 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5965 return new LSL_Integer(0); 6397 return new LSL_Integer(0);
5966 IClientAPI client = presence.ControllingClient; 6398
5967 if (m_host.GroupID == client.ActiveGroupId) 6399 // Check if it's a group key
6400 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5968 return new LSL_Integer(1); 6401 return new LSL_Integer(1);
5969 else 6402
6403 // We got passed a UUID.Zero
6404 if (uuid == UUID.Zero)
5970 return new LSL_Integer(0); 6405 return new LSL_Integer(0);
6406
6407 // Handle the case where id names an avatar
6408 ScenePresence presence = World.GetScenePresence(uuid);
6409 if (presence != null)
6410 {
6411 if (presence.IsChildAgent)
6412 return new LSL_Integer(0);
6413
6414 IClientAPI client = presence.ControllingClient;
6415 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6416 return new LSL_Integer(1);
6417
6418 return new LSL_Integer(0);
6419 }
6420
6421 // Handle object case
6422 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6423 if (part != null)
6424 {
6425 // This will handle both deed and non-deed and also the no
6426 // group case
6427 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6428 return new LSL_Integer(1);
6429
6430 return new LSL_Integer(0);
6431 }
6432
6433 return new LSL_Integer(0);
5971 } 6434 }
5972 6435
5973 public void llUnSit(string id) 6436 public void llUnSit(string id)
@@ -6092,7 +6555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6092 return m_host.ParentGroup.AttachmentPoint; 6555 return m_host.ParentGroup.AttachmentPoint;
6093 } 6556 }
6094 6557
6095 public LSL_Integer llGetFreeMemory() 6558 public virtual LSL_Integer llGetFreeMemory()
6096 { 6559 {
6097 m_host.AddScriptLPS(1); 6560 m_host.AddScriptLPS(1);
6098 // Make scripts designed for LSO happy 6561 // Make scripts designed for LSO happy
@@ -6209,7 +6672,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6209 SetParticleSystem(m_host, rules); 6672 SetParticleSystem(m_host, rules);
6210 } 6673 }
6211 6674
6212 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6675 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6676 {
6213 6677
6214 6678
6215 if (rules.Length == 0) 6679 if (rules.Length == 0)
@@ -6524,6 +6988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 6988
6525 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6989 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6526 { 6990 {
6991 // LSL quaternions can normalize to 0, normal Quaternions can't.
6992 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6993 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6994
6527 part.SitTargetPosition = offset; 6995 part.SitTargetPosition = offset;
6528 part.SitTargetOrientation = rot; 6996 part.SitTargetOrientation = rot;
6529 part.ParentGroup.HasGroupChanged = true; 6997 part.ParentGroup.HasGroupChanged = true;
@@ -6679,13 +7147,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6679 UUID av = new UUID(); 7147 UUID av = new UUID();
6680 if (!UUID.TryParse(avatar,out av)) 7148 if (!UUID.TryParse(avatar,out av))
6681 { 7149 {
6682 LSLError("First parameter to llDialog needs to be a key"); 7150 //LSLError("First parameter to llDialog needs to be a key");
6683 return; 7151 return;
6684 } 7152 }
6685 if (buttons.Length < 1) 7153 if (buttons.Length < 1)
6686 { 7154 {
6687 LSLError("No less than 1 button can be shown"); 7155 buttons.Add("OK");
6688 return;
6689 } 7156 }
6690 if (buttons.Length > 12) 7157 if (buttons.Length > 12)
6691 { 7158 {
@@ -6702,7 +7169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6702 } 7169 }
6703 if (buttons.Data[i].ToString().Length > 24) 7170 if (buttons.Data[i].ToString().Length > 24)
6704 { 7171 {
6705 LSLError("button label cannot be longer than 24 characters"); 7172 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6706 return; 7173 return;
6707 } 7174 }
6708 buts[i] = buttons.Data[i].ToString(); 7175 buts[i] = buttons.Data[i].ToString();
@@ -6769,9 +7236,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6769 return; 7236 return;
6770 } 7237 }
6771 7238
6772 // the rest of the permission checks are done in RezScript, so check the pin there as well 7239 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6773 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7240 if (dest != null)
7241 {
7242 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7243 {
7244 // the rest of the permission checks are done in RezScript, so check the pin there as well
7245 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6774 7246
7247 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7248 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7249 }
7250 }
6775 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7251 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6776 ScriptSleep(3000); 7252 ScriptSleep(3000);
6777 } 7253 }
@@ -6834,19 +7310,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6834 public LSL_String llMD5String(string src, int nonce) 7310 public LSL_String llMD5String(string src, int nonce)
6835 { 7311 {
6836 m_host.AddScriptLPS(1); 7312 m_host.AddScriptLPS(1);
6837 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7313 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6838 } 7314 }
6839 7315
6840 public LSL_String llSHA1String(string src) 7316 public LSL_String llSHA1String(string src)
6841 { 7317 {
6842 m_host.AddScriptLPS(1); 7318 m_host.AddScriptLPS(1);
6843 return Util.SHA1Hash(src).ToLower(); 7319 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6844 } 7320 }
6845 7321
6846 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7322 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6847 { 7323 {
6848 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7324 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7325 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7326 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7327 return shapeBlock;
6850 7328
6851 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7329 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6852 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7330 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6951,6 +7429,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type box, cylinder and prism. 7429 // Prim type box, cylinder and prism.
6952 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) 7430 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)
6953 { 7431 {
7432 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7433 return;
7434
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7435 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7436 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7437
@@ -7004,6 +7485,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7004 // Prim type sphere. 7485 // Prim type sphere.
7005 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7486 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7006 { 7487 {
7488 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7489 return;
7490
7007 ObjectShapePacket.ObjectDataBlock shapeBlock; 7491 ObjectShapePacket.ObjectDataBlock shapeBlock;
7008 7492
7009 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7493 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7045,6 +7529,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7045 // Prim type torus, tube and ring. 7529 // Prim type torus, tube and ring.
7046 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) 7530 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)
7047 { 7531 {
7532 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7533 return;
7534
7048 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7535 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7049 ObjectShapePacket.ObjectDataBlock shapeBlock; 7536 ObjectShapePacket.ObjectDataBlock shapeBlock;
7050 7537
@@ -7180,6 +7667,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7180 // Prim type sculpt. 7667 // Prim type sculpt.
7181 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7668 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7182 { 7669 {
7670 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7671 return;
7672
7183 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7673 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7184 UUID sculptId; 7674 UUID sculptId;
7185 7675
@@ -7204,7 +7694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7204 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7694 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7205 { 7695 {
7206 // default 7696 // default
7207 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7697 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7208 } 7698 }
7209 7699
7210 part.Shape.SetSculptProperties((byte)type, sculptId); 7700 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7221,48 +7711,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 ScriptSleep(200); 7711 ScriptSleep(200);
7222 } 7712 }
7223 7713
7224 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7714 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7225 { 7715 {
7226 m_host.AddScriptLPS(1); 7716 m_host.AddScriptLPS(1);
7227 7717
7228 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7718 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7229 7719
7230 ScriptSleep(200); 7720 ScriptSleep(200);
7231 } 7721 }
7232 7722
7233 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7723 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7234 { 7724 {
7235 m_host.AddScriptLPS(1); 7725 List<object> parts = new List<object>();
7726 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7727 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7728 foreach (SceneObjectPart p in prims)
7729 parts.Add(p);
7730 foreach (ScenePresence p in avatars)
7731 parts.Add(p);
7236 7732
7237 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7733 LSL_List remaining = null;
7734 uint rulesParsed = 0;
7735
7736 if (parts.Count > 0)
7737 {
7738 foreach (object part in parts)
7739 {
7740 if (part is SceneObjectPart)
7741 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7742 else
7743 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7744 }
7745
7746 while ((object)remaining != null && remaining.Length > 2)
7747 {
7748 linknumber = remaining.GetLSLIntegerItem(0);
7749 rules = remaining.GetSublist(1, -1);
7750 parts.Clear();
7751 prims = GetLinkParts(linknumber);
7752 avatars = GetLinkAvatars(linknumber);
7753 foreach (SceneObjectPart p in prims)
7754 parts.Add(p);
7755 foreach (ScenePresence p in avatars)
7756 parts.Add(p);
7757
7758 remaining = null;
7759 foreach (object part in parts)
7760 {
7761 if (part is SceneObjectPart)
7762 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7763 else
7764 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7765 }
7766 }
7767 }
7238 } 7768 }
7239 7769
7240 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7770 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7771 float material_density, float material_friction,
7772 float material_restitution, float material_gravity_modifier)
7241 { 7773 {
7242 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7774 ExtraPhysicsData physdata = new ExtraPhysicsData();
7775 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7776 physdata.Density = part.Density;
7777 physdata.Friction = part.Friction;
7778 physdata.Bounce = part.Bounciness;
7779 physdata.GravitationModifier = part.GravityModifier;
7243 7780
7244 LSL_List remaining = null; 7781 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7245 uint rulesParsed = 0; 7782 physdata.Density = material_density;
7783 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7784 physdata.Friction = material_friction;
7785 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7786 physdata.Bounce = material_restitution;
7787 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7788 physdata.GravitationModifier = material_gravity_modifier;
7246 7789
7247 foreach (SceneObjectPart part in parts) 7790 part.UpdateExtraPhysics(physdata);
7248 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7791 }
7249 7792
7250 while (remaining != null && remaining.Length > 2) 7793 public void llSetPhysicsMaterial(int material_bits,
7251 { 7794 float material_gravity_modifier, float material_restitution,
7252 linknumber = remaining.GetLSLIntegerItem(0); 7795 float material_friction, float material_density)
7253 rules = remaining.GetSublist(1, -1); 7796 {
7254 parts = GetLinkParts(linknumber); 7797 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7798 }
7255 7799
7256 foreach (SceneObjectPart part in parts) 7800 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7257 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7801 {
7802 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7803 llSetLinkPrimitiveParamsFast(linknumber, rules);
7804 ScriptSleep(200);
7805 }
7806
7807 // vector up using libomv (c&p from sop )
7808 // vector up rotated by r
7809 private Vector3 Zrot(Quaternion r)
7810 {
7811 double x, y, z, m;
7812
7813 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7814 if (Math.Abs(1.0 - m) > 0.000001)
7815 {
7816 m = 1.0 / Math.Sqrt(m);
7817 r.X *= (float)m;
7818 r.Y *= (float)m;
7819 r.Z *= (float)m;
7820 r.W *= (float)m;
7258 } 7821 }
7822
7823 x = 2 * (r.X * r.Z + r.Y * r.W);
7824 y = 2 * (-r.X * r.W + r.Y * r.Z);
7825 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7826
7827 return new Vector3((float)x, (float)y, (float)z);
7259 } 7828 }
7260 7829
7261 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7830 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7262 { 7831 {
7832 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7833 return null;
7834
7263 int idx = 0; 7835 int idx = 0;
7264 int idxStart = 0; 7836 int idxStart = 0;
7265 7837
7838 SceneObjectGroup parentgrp = part.ParentGroup;
7839
7266 bool positionChanged = false; 7840 bool positionChanged = false;
7267 LSL_Vector currentPosition = GetPartLocalPos(part); 7841 LSL_Vector currentPosition = GetPartLocalPos(part);
7268 7842
@@ -7287,8 +7861,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7287 return null; 7861 return null;
7288 7862
7289 v=rules.GetVector3Item(idx++); 7863 v=rules.GetVector3Item(idx++);
7290 positionChanged = true;
7291 currentPosition = GetSetPosTarget(part, v, currentPosition); 7864 currentPosition = GetSetPosTarget(part, v, currentPosition);
7865 positionChanged = true;
7292 7866
7293 break; 7867 break;
7294 case (int)ScriptBaseClass.PRIM_SIZE: 7868 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7565,7 +8139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7565 return null; 8139 return null;
7566 8140
7567 string ph = rules.Data[idx++].ToString(); 8141 string ph = rules.Data[idx++].ToString();
7568 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8142 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7569 8143
7570 break; 8144 break;
7571 8145
@@ -7583,12 +8157,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7583 part.ScriptSetPhysicsStatus(physics); 8157 part.ScriptSetPhysicsStatus(physics);
7584 break; 8158 break;
7585 8159
8160 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8161 if (remain < 1)
8162 return null;
8163
8164 int shape_type = rules.GetLSLIntegerItem(idx++);
8165
8166 ExtraPhysicsData physdata = new ExtraPhysicsData();
8167 physdata.Density = part.Density;
8168 physdata.Bounce = part.Bounciness;
8169 physdata.GravitationModifier = part.GravityModifier;
8170 physdata.PhysShapeType = (PhysShapeType)shape_type;
8171
8172 part.UpdateExtraPhysics(physdata);
8173
8174 break;
8175
8176 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8177 if (remain < 5)
8178 return null;
8179
8180 int material_bits = rules.GetLSLIntegerItem(idx++);
8181 float material_density = (float)rules.GetLSLFloatItem(idx++);
8182 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8183 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8184 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8185
8186 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8187
8188 break;
8189
7586 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8190 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7587 if (remain < 1) 8191 if (remain < 1)
7588 return null; 8192 return null;
7589 string temp = rules.Data[idx++].ToString(); 8193 string temp = rules.Data[idx++].ToString();
7590 8194
7591 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8195 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7592 8196
7593 break; 8197 break;
7594 8198
@@ -7662,7 +8266,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7662 if (part.ParentGroup.RootPart == part) 8266 if (part.ParentGroup.RootPart == part)
7663 { 8267 {
7664 SceneObjectGroup parent = part.ParentGroup; 8268 SceneObjectGroup parent = part.ParentGroup;
7665 parent.UpdateGroupPosition(currentPosition); 8269 Util.FireAndForget(delegate(object x) {
8270 parent.UpdateGroupPosition(currentPosition);
8271 });
7666 } 8272 }
7667 else 8273 else
7668 { 8274 {
@@ -7707,10 +8313,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7707 8313
7708 public LSL_String llXorBase64Strings(string str1, string str2) 8314 public LSL_String llXorBase64Strings(string str1, string str2)
7709 { 8315 {
7710 m_host.AddScriptLPS(1); 8316 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7711 Deprecated("llXorBase64Strings"); 8317
7712 ScriptSleep(300); 8318 ScriptSleep(300);
7713 return String.Empty; 8319 m_host.AddScriptLPS(1);
8320
8321 if (str1 == String.Empty)
8322 return String.Empty;
8323 if (str2 == String.Empty)
8324 return str1;
8325
8326 int len = str2.Length;
8327 if ((len % 4) != 0) // LL is EVIL!!!!
8328 {
8329 while (str2.EndsWith("="))
8330 str2 = str2.Substring(0, str2.Length - 1);
8331
8332 len = str2.Length;
8333 int mod = len % 4;
8334
8335 if (mod == 1)
8336 str2 = str2.Substring(0, str2.Length - 1);
8337 else if (mod == 2)
8338 str2 += "==";
8339 else if (mod == 3)
8340 str2 += "=";
8341 }
8342
8343 byte[] data1;
8344 byte[] data2;
8345 try
8346 {
8347 data1 = Convert.FromBase64String(str1);
8348 data2 = Convert.FromBase64String(str2);
8349 }
8350 catch (Exception)
8351 {
8352 return new LSL_String(String.Empty);
8353 }
8354
8355 // For cases where the decoded length of s2 is greater
8356 // than the decoded length of s1, simply perform a normal
8357 // decode and XOR
8358 //
8359 if (data2.Length >= data1.Length)
8360 {
8361 for (int pos = 0 ; pos < data1.Length ; pos++ )
8362 data1[pos] ^= data2[pos];
8363
8364 return Convert.ToBase64String(data1);
8365 }
8366
8367 // Remove padding
8368 while (str1.EndsWith("="))
8369 str1 = str1.Substring(0, str1.Length - 1);
8370 while (str2.EndsWith("="))
8371 str2 = str2.Substring(0, str2.Length - 1);
8372
8373 byte[] d1 = new byte[str1.Length];
8374 byte[] d2 = new byte[str2.Length];
8375
8376 for (int i = 0 ; i < str1.Length ; i++)
8377 {
8378 int idx = b64.IndexOf(str1.Substring(i, 1));
8379 if (idx == -1)
8380 idx = 0;
8381 d1[i] = (byte)idx;
8382 }
8383
8384 for (int i = 0 ; i < str2.Length ; i++)
8385 {
8386 int idx = b64.IndexOf(str2.Substring(i, 1));
8387 if (idx == -1)
8388 idx = 0;
8389 d2[i] = (byte)idx;
8390 }
8391
8392 string output = String.Empty;
8393
8394 for (int pos = 0 ; pos < d1.Length ; pos++)
8395 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8396
8397 while (output.Length % 3 > 0)
8398 output += "=";
8399
8400 return output;
7714 } 8401 }
7715 8402
7716 public void llRemoteDataSetRegion() 8403 public void llRemoteDataSetRegion()
@@ -7834,13 +8521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7834 public LSL_Integer llGetNumberOfPrims() 8521 public LSL_Integer llGetNumberOfPrims()
7835 { 8522 {
7836 m_host.AddScriptLPS(1); 8523 m_host.AddScriptLPS(1);
7837 int avatarCount = 0; 8524 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7838 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8525
7839 {
7840 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7841 avatarCount++;
7842 });
7843
7844 return m_host.ParentGroup.PrimCount + avatarCount; 8526 return m_host.ParentGroup.PrimCount + avatarCount;
7845 } 8527 }
7846 8528
@@ -7856,55 +8538,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7856 m_host.AddScriptLPS(1); 8538 m_host.AddScriptLPS(1);
7857 UUID objID = UUID.Zero; 8539 UUID objID = UUID.Zero;
7858 LSL_List result = new LSL_List(); 8540 LSL_List result = new LSL_List();
8541
8542 // If the ID is not valid, return null result
7859 if (!UUID.TryParse(obj, out objID)) 8543 if (!UUID.TryParse(obj, out objID))
7860 { 8544 {
7861 result.Add(new LSL_Vector()); 8545 result.Add(new LSL_Vector());
7862 result.Add(new LSL_Vector()); 8546 result.Add(new LSL_Vector());
7863 return result; 8547 return result;
7864 } 8548 }
8549
8550 // Check if this is an attached prim. If so, replace
8551 // the UUID with the avatar UUID and report it's bounding box
8552 SceneObjectPart part = World.GetSceneObjectPart(objID);
8553 if (part != null && part.ParentGroup.IsAttachment)
8554 objID = part.ParentGroup.AttachedAvatar;
8555
8556 // Find out if this is an avatar ID. If so, return it's box
7865 ScenePresence presence = World.GetScenePresence(objID); 8557 ScenePresence presence = World.GetScenePresence(objID);
7866 if (presence != null) 8558 if (presence != null)
7867 { 8559 {
7868 if (presence.ParentID == 0) // not sat on an object 8560 // As per LSL Wiki, there is no difference between sitting
8561 // and standing avatar since server 1.36
8562 LSL_Vector lower;
8563 LSL_Vector upper;
8564 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8565 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7869 { 8566 {
7870 LSL_Vector lower; 8567 // This is for ground sitting avatars
7871 LSL_Vector upper; 8568 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7872 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8569 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7873 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8570 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7874 {
7875 // This is for ground sitting avatars
7876 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7877 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7878 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7879 }
7880 else
7881 {
7882 // This is for standing/flying avatars
7883 float height = presence.Appearance.AvatarHeight / 2.0f;
7884 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7885 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7886 }
7887 result.Add(lower);
7888 result.Add(upper);
7889 return result;
7890 } 8571 }
7891 else 8572 else
7892 { 8573 {
7893 // sitting on an object so we need the bounding box of that 8574 // This is for standing/flying avatars
7894 // which should include the avatar so set the UUID to the 8575 float height = presence.Appearance.AvatarHeight / 2.0f;
7895 // UUID of the object the avatar is sat on and allow it to fall through 8576 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7896 // to processing an object 8577 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7897 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7898 objID = p.UUID;
7899 } 8578 }
8579
8580 // Adjust to the documented error offsets (see LSL Wiki)
8581 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8582 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8583
8584 if (lower.x > upper.x)
8585 lower.x = upper.x;
8586 if (lower.y > upper.y)
8587 lower.y = upper.y;
8588 if (lower.z > upper.z)
8589 lower.z = upper.z;
8590
8591 result.Add(lower);
8592 result.Add(upper);
8593 return result;
7900 } 8594 }
7901 SceneObjectPart part = World.GetSceneObjectPart(objID); 8595
8596 part = World.GetSceneObjectPart(objID);
7902 // Currently only works for single prims without a sitting avatar 8597 // Currently only works for single prims without a sitting avatar
7903 if (part != null) 8598 if (part != null)
7904 { 8599 {
7905 Vector3 halfSize = part.Scale / 2.0f; 8600 float minX;
7906 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8601 float maxX;
7907 LSL_Vector upper = new LSL_Vector(halfSize); 8602 float minY;
8603 float maxY;
8604 float minZ;
8605 float maxZ;
8606
8607 // This BBox is in sim coordinates, with the offset being
8608 // a contained point.
8609 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8610 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8611
8612 minX -= offsets[0].X;
8613 maxX -= offsets[0].X;
8614 minY -= offsets[0].Y;
8615 maxY -= offsets[0].Y;
8616 minZ -= offsets[0].Z;
8617 maxZ -= offsets[0].Z;
8618
8619 LSL_Vector lower;
8620 LSL_Vector upper;
8621
8622 // Adjust to the documented error offsets (see LSL Wiki)
8623 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8624 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8625
8626 if (lower.x > upper.x)
8627 lower.x = upper.x;
8628 if (lower.y > upper.y)
8629 lower.y = upper.y;
8630 if (lower.z > upper.z)
8631 lower.z = upper.z;
8632
7908 result.Add(lower); 8633 result.Add(lower);
7909 result.Add(upper); 8634 result.Add(upper);
7910 return result; 8635 return result;
@@ -7918,7 +8643,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7918 8643
7919 public LSL_Vector llGetGeometricCenter() 8644 public LSL_Vector llGetGeometricCenter()
7920 { 8645 {
7921 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8646 Vector3 tmp = m_host.GetGeometricCenter();
8647 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7922 } 8648 }
7923 8649
7924 public LSL_List llGetPrimitiveParams(LSL_List rules) 8650 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7946,24 +8672,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7946 { 8672 {
7947 m_host.AddScriptLPS(1); 8673 m_host.AddScriptLPS(1);
7948 8674
7949 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8675 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8676 // keep other options as before
7950 8677
8678 List<SceneObjectPart> parts;
8679 List<ScenePresence> avatars;
8680
7951 LSL_List res = new LSL_List(); 8681 LSL_List res = new LSL_List();
7952 LSL_List remaining = null; 8682 LSL_List remaining = null;
7953 8683
7954 foreach (SceneObjectPart part in parts) 8684 while (rules.Length > 0)
7955 { 8685 {
7956 remaining = GetPrimParams(part, rules, ref res);
7957 }
7958
7959 while (remaining != null && remaining.Length > 2)
7960 {
7961 linknumber = remaining.GetLSLIntegerItem(0);
7962 rules = remaining.GetSublist(1, -1);
7963 parts = GetLinkParts(linknumber); 8686 parts = GetLinkParts(linknumber);
8687 avatars = GetLinkAvatars(linknumber);
7964 8688
8689 remaining = null;
7965 foreach (SceneObjectPart part in parts) 8690 foreach (SceneObjectPart part in parts)
8691 {
7966 remaining = GetPrimParams(part, rules, ref res); 8692 remaining = GetPrimParams(part, rules, ref res);
8693 }
8694 foreach (ScenePresence avatar in avatars)
8695 {
8696 remaining = GetPrimParams(avatar, rules, ref res);
8697 }
8698
8699 if (remaining != null && remaining.Length > 0)
8700 {
8701 linknumber = remaining.GetLSLIntegerItem(0);
8702 rules = remaining.GetSublist(1, -1);
8703 }
7967 } 8704 }
7968 8705
7969 return res; 8706 return res;
@@ -8008,13 +8745,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8745 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8009 part.AbsolutePosition.Y, 8746 part.AbsolutePosition.Y,
8010 part.AbsolutePosition.Z); 8747 part.AbsolutePosition.Z);
8011 // For some reason, the part.AbsolutePosition.* values do not change if the
8012 // linkset is rotated; they always reflect the child prim's world position
8013 // as though the linkset is unrotated. This is incompatible behavior with SL's
8014 // implementation, so will break scripts imported from there (not to mention it
8015 // makes it more difficult to determine a child prim's actual inworld position).
8016 if (part.ParentID != 0)
8017 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8018 res.Add(v); 8748 res.Add(v);
8019 break; 8749 break;
8020 8750
@@ -8186,30 +8916,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8186 if (remain < 1) 8916 if (remain < 1)
8187 return null; 8917 return null;
8188 8918
8189 face=(int)rules.GetLSLIntegerItem(idx++); 8919 face = (int)rules.GetLSLIntegerItem(idx++);
8190 8920
8191 tex = part.Shape.Textures; 8921 tex = part.Shape.Textures;
8922 int shiny;
8192 if (face == ScriptBaseClass.ALL_SIDES) 8923 if (face == ScriptBaseClass.ALL_SIDES)
8193 { 8924 {
8194 for (face = 0; face < GetNumberOfSides(part); face++) 8925 for (face = 0; face < GetNumberOfSides(part); face++)
8195 { 8926 {
8196 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8927 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8197 // Convert Shininess to PRIM_SHINY_* 8928 if (shinyness == Shininess.High)
8198 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8929 {
8199 // PRIM_BUMP_* 8930 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8200 res.Add(new LSL_Integer((int)texface.Bump)); 8931 }
8932 else if (shinyness == Shininess.Medium)
8933 {
8934 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8935 }
8936 else if (shinyness == Shininess.Low)
8937 {
8938 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8939 }
8940 else
8941 {
8942 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8943 }
8944 res.Add(new LSL_Integer(shiny));
8945 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8201 } 8946 }
8202 } 8947 }
8203 else 8948 else
8204 { 8949 {
8205 if (face >= 0 && face < GetNumberOfSides(part)) 8950 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8951 if (shinyness == Shininess.High)
8206 { 8952 {
8207 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8953 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8208 // Convert Shininess to PRIM_SHINY_* 8954 }
8209 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8955 else if (shinyness == Shininess.Medium)
8210 // PRIM_BUMP_* 8956 {
8211 res.Add(new LSL_Integer((int)texface.Bump)); 8957 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8958 }
8959 else if (shinyness == Shininess.Low)
8960 {
8961 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8962 }
8963 else
8964 {
8965 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8212 } 8966 }
8967 res.Add(new LSL_Integer(shiny));
8968 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8213 } 8969 }
8214 break; 8970 break;
8215 8971
@@ -8217,24 +8973,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 if (remain < 1) 8973 if (remain < 1)
8218 return null; 8974 return null;
8219 8975
8220 face=(int)rules.GetLSLIntegerItem(idx++); 8976 face = (int)rules.GetLSLIntegerItem(idx++);
8221 8977
8222 tex = part.Shape.Textures; 8978 tex = part.Shape.Textures;
8979 int fullbright;
8223 if (face == ScriptBaseClass.ALL_SIDES) 8980 if (face == ScriptBaseClass.ALL_SIDES)
8224 { 8981 {
8225 for (face = 0; face < GetNumberOfSides(part); face++) 8982 for (face = 0; face < GetNumberOfSides(part); face++)
8226 { 8983 {
8227 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8984 if (tex.GetFace((uint)face).Fullbright == true)
8228 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8985 {
8986 fullbright = ScriptBaseClass.TRUE;
8987 }
8988 else
8989 {
8990 fullbright = ScriptBaseClass.FALSE;
8991 }
8992 res.Add(new LSL_Integer(fullbright));
8229 } 8993 }
8230 } 8994 }
8231 else 8995 else
8232 { 8996 {
8233 if (face >= 0 && face < GetNumberOfSides(part)) 8997 if (tex.GetFace((uint)face).Fullbright == true)
8234 { 8998 {
8235 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8999 fullbright = ScriptBaseClass.TRUE;
8236 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9000 }
9001 else
9002 {
9003 fullbright = ScriptBaseClass.FALSE;
8237 } 9004 }
9005 res.Add(new LSL_Integer(fullbright));
8238 } 9006 }
8239 break; 9007 break;
8240 9008
@@ -8256,27 +9024,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8256 break; 9024 break;
8257 9025
8258 case (int)ScriptBaseClass.PRIM_TEXGEN: 9026 case (int)ScriptBaseClass.PRIM_TEXGEN:
9027 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8259 if (remain < 1) 9028 if (remain < 1)
8260 return null; 9029 return null;
8261 9030
8262 face=(int)rules.GetLSLIntegerItem(idx++); 9031 face = (int)rules.GetLSLIntegerItem(idx++);
8263 9032
8264 tex = part.Shape.Textures; 9033 tex = part.Shape.Textures;
8265 if (face == ScriptBaseClass.ALL_SIDES) 9034 if (face == ScriptBaseClass.ALL_SIDES)
8266 { 9035 {
8267 for (face = 0; face < GetNumberOfSides(part); face++) 9036 for (face = 0; face < GetNumberOfSides(part); face++)
8268 { 9037 {
8269 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9038 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8270 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9039 {
8271 res.Add(new LSL_Integer((uint)texgen >> 1)); 9040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9041 }
9042 else
9043 {
9044 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9045 }
8272 } 9046 }
8273 } 9047 }
8274 else 9048 else
8275 { 9049 {
8276 if (face >= 0 && face < GetNumberOfSides(part)) 9050 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8277 { 9051 {
8278 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8279 res.Add(new LSL_Integer((uint)texgen >> 1)); 9053 }
9054 else
9055 {
9056 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8280 } 9057 }
8281 } 9058 }
8282 break; 9059 break;
@@ -8300,24 +9077,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8300 if (remain < 1) 9077 if (remain < 1)
8301 return null; 9078 return null;
8302 9079
8303 face=(int)rules.GetLSLIntegerItem(idx++); 9080 face = (int)rules.GetLSLIntegerItem(idx++);
8304 9081
8305 tex = part.Shape.Textures; 9082 tex = part.Shape.Textures;
9083 float primglow;
8306 if (face == ScriptBaseClass.ALL_SIDES) 9084 if (face == ScriptBaseClass.ALL_SIDES)
8307 { 9085 {
8308 for (face = 0; face < GetNumberOfSides(part); face++) 9086 for (face = 0; face < GetNumberOfSides(part); face++)
8309 { 9087 {
8310 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9088 primglow = tex.GetFace((uint)face).Glow;
8311 res.Add(new LSL_Float(texface.Glow)); 9089 res.Add(new LSL_Float(primglow));
8312 } 9090 }
8313 } 9091 }
8314 else 9092 else
8315 { 9093 {
8316 if (face >= 0 && face < GetNumberOfSides(part)) 9094 primglow = tex.GetFace((uint)face).Glow;
8317 { 9095 res.Add(new LSL_Float(primglow));
8318 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8319 res.Add(new LSL_Float(texface.Glow));
8320 }
8321 } 9096 }
8322 break; 9097 break;
8323 9098
@@ -8329,15 +9104,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8329 textColor.B)); 9104 textColor.B));
8330 res.Add(new LSL_Float(textColor.A)); 9105 res.Add(new LSL_Float(textColor.A));
8331 break; 9106 break;
9107
8332 case (int)ScriptBaseClass.PRIM_NAME: 9108 case (int)ScriptBaseClass.PRIM_NAME:
8333 res.Add(new LSL_String(part.Name)); 9109 res.Add(new LSL_String(part.Name));
8334 break; 9110 break;
9111
8335 case (int)ScriptBaseClass.PRIM_DESC: 9112 case (int)ScriptBaseClass.PRIM_DESC:
8336 res.Add(new LSL_String(part.Description)); 9113 res.Add(new LSL_String(part.Description));
8337 break; 9114 break;
9115
8338 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9116 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8339 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9117 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8340 break; 9118 break;
9119
8341 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9120 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8342 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9121 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8343 break; 9122 break;
@@ -8948,8 +9727,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8948 // The function returns an ordered list 9727 // The function returns an ordered list
8949 // representing the tokens found in the supplied 9728 // representing the tokens found in the supplied
8950 // sources string. If two successive tokenizers 9729 // sources string. If two successive tokenizers
8951 // are encountered, then a NULL entry is added 9730 // are encountered, then a null-string entry is
8952 // to the list. 9731 // added to the list.
8953 // 9732 //
8954 // It is a precondition that the source and 9733 // It is a precondition that the source and
8955 // toekizer lisst are non-null. If they are null, 9734 // toekizer lisst are non-null. If they are null,
@@ -8957,7 +9736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8957 // while their lengths are being determined. 9736 // while their lengths are being determined.
8958 // 9737 //
8959 // A small amount of working memoryis required 9738 // A small amount of working memoryis required
8960 // of approximately 8*#tokenizers. 9739 // of approximately 8*#tokenizers + 8*srcstrlen.
8961 // 9740 //
8962 // There are many ways in which this function 9741 // There are many ways in which this function
8963 // can be implemented, this implementation is 9742 // can be implemented, this implementation is
@@ -8973,155 +9752,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8973 // and eliminates redundant tokenizers as soon 9752 // and eliminates redundant tokenizers as soon
8974 // as is possible. 9753 // as is possible.
8975 // 9754 //
8976 // The implementation tries to avoid any copying 9755 // The implementation tries to minimize temporary
8977 // of arrays or other objects. 9756 // garbage generation.
8978 // </remarks> 9757 // </remarks>
8979 9758
8980 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9759 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8981 { 9760 {
8982 int beginning = 0; 9761 return ParseString2List(src, separators, spacers, true);
8983 int srclen = src.Length; 9762 }
8984 int seplen = separators.Length;
8985 object[] separray = separators.Data;
8986 int spclen = spacers.Length;
8987 object[] spcarray = spacers.Data;
8988 int mlen = seplen+spclen;
8989
8990 int[] offset = new int[mlen+1];
8991 bool[] active = new bool[mlen];
8992
8993 int best;
8994 int j;
8995
8996 // Initial capacity reduces resize cost
8997 9763
8998 LSL_List tokens = new LSL_List(); 9764 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9765 {
9766 int srclen = src.Length;
9767 int seplen = separators.Length;
9768 object[] separray = separators.Data;
9769 int spclen = spacers.Length;
9770 object[] spcarray = spacers.Data;
9771 int dellen = 0;
9772 string[] delarray = new string[seplen+spclen];
8999 9773
9000 // All entries are initially valid 9774 int outlen = 0;
9775 string[] outarray = new string[srclen*2+1];
9001 9776
9002 for (int i = 0; i < mlen; i++) 9777 int i, j;
9003 active[i] = true; 9778 string d;
9004 9779
9005 offset[mlen] = srclen; 9780 m_host.AddScriptLPS(1);
9006 9781
9007 while (beginning < srclen) 9782 /*
9783 * Convert separator and spacer lists to C# strings.
9784 * Also filter out null strings so we don't hang.
9785 */
9786 for (i = 0; i < seplen; i ++)
9008 { 9787 {
9788 d = separray[i].ToString();
9789 if (d.Length > 0)
9790 {
9791 delarray[dellen++] = d;
9792 }
9793 }
9794 seplen = dellen;
9009 9795
9010 best = mlen; // as bad as it gets 9796 for (i = 0; i < spclen; i ++)
9797 {
9798 d = spcarray[i].ToString();
9799 if (d.Length > 0)
9800 {
9801 delarray[dellen++] = d;
9802 }
9803 }
9011 9804
9012 // Scan for separators 9805 /*
9806 * Scan through source string from beginning to end.
9807 */
9808 for (i = 0;;)
9809 {
9013 9810
9014 for (j = 0; j < seplen; j++) 9811 /*
9812 * Find earliest delimeter in src starting at i (if any).
9813 */
9814 int earliestDel = -1;
9815 int earliestSrc = srclen;
9816 string earliestStr = null;
9817 for (j = 0; j < dellen; j ++)
9015 { 9818 {
9016 if (separray[j].ToString() == String.Empty) 9819 d = delarray[j];
9017 active[j] = false; 9820 if (d != null)
9018
9019 if (active[j])
9020 { 9821 {
9021 // scan all of the markers 9822 int index = src.IndexOf(d, i);
9022 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9823 if (index < 0)
9023 { 9824 {
9024 // not present at all 9825 delarray[j] = null; // delim nowhere in src, don't check it anymore
9025 active[j] = false;
9026 } 9826 }
9027 else 9827 else if (index < earliestSrc)
9028 { 9828 {
9029 // present and correct 9829 earliestSrc = index; // where delimeter starts in source string
9030 if (offset[j] < offset[best]) 9830 earliestDel = j; // where delimeter is in delarray[]
9031 { 9831 earliestStr = d; // the delimeter string from delarray[]
9032 // closest so far 9832 if (index == i) break; // can't do any better than found at beg of string
9033 best = j;
9034 if (offset[best] == beginning)
9035 break;
9036 }
9037 } 9833 }
9038 } 9834 }
9039 } 9835 }
9040 9836
9041 // Scan for spacers 9837 /*
9042 9838 * Output source string starting at i through start of earliest delimeter.
9043 if (offset[best] != beginning) 9839 */
9840 if (keepNulls || (earliestSrc > i))
9044 { 9841 {
9045 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9842 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9046 {
9047 if (spcarray[j-seplen].ToString() == String.Empty)
9048 active[j] = false;
9049
9050 if (active[j])
9051 {
9052 // scan all of the markers
9053 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9054 {
9055 // not present at all
9056 active[j] = false;
9057 }
9058 else
9059 {
9060 // present and correct
9061 if (offset[j] < offset[best])
9062 {
9063 // closest so far
9064 best = j;
9065 }
9066 }
9067 }
9068 }
9069 } 9843 }
9070 9844
9071 // This is the normal exit from the scanning loop 9845 /*
9846 * If no delimeter found at or after i, we're done scanning.
9847 */
9848 if (earliestDel < 0) break;
9072 9849
9073 if (best == mlen) 9850 /*
9851 * If delimeter was a spacer, output the spacer.
9852 */
9853 if (earliestDel >= seplen)
9074 { 9854 {
9075 // no markers were found on this pass 9855 outarray[outlen++] = earliestStr;
9076 // so we're pretty much done
9077 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9078 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9079 break;
9080 } 9856 }
9081 9857
9082 // Otherwise we just add the newly delimited token 9858 /*
9083 // and recalculate where the search should continue. 9859 * Look at rest of src string following delimeter.
9084 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9860 */
9085 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9861 i = earliestSrc + earliestStr.Length;
9086
9087 if (best < seplen)
9088 {
9089 beginning = offset[best] + (separray[best].ToString()).Length;
9090 }
9091 else
9092 {
9093 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9094 string str = spcarray[best - seplen].ToString();
9095 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9096 tokens.Add(new LSL_String(str));
9097 }
9098 } 9862 }
9099 9863
9100 // This an awkward an not very intuitive boundary case. If the 9864 /*
9101 // last substring is a tokenizer, then there is an implied trailing 9865 * Make up an exact-sized output array suitable for an LSL_List object.
9102 // null list entry. Hopefully the single comparison will not be too 9866 */
9103 // arduous. Alternatively the 'break' could be replced with a return 9867 object[] outlist = new object[outlen];
9104 // but that's shabby programming. 9868 for (i = 0; i < outlen; i ++)
9105
9106 if ((beginning == srclen) && (keepNulls))
9107 { 9869 {
9108 if (srclen != 0) 9870 outlist[i] = new LSL_String(outarray[i]);
9109 tokens.Add(new LSL_String(""));
9110 } 9871 }
9111 9872 return new LSL_List(outlist);
9112 return tokens;
9113 }
9114
9115 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9116 {
9117 m_host.AddScriptLPS(1);
9118 return this.ParseString(src, separators, spacers, false);
9119 }
9120
9121 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9122 {
9123 m_host.AddScriptLPS(1);
9124 return this.ParseString(src, separators, spacers, true);
9125 } 9873 }
9126 9874
9127 public LSL_Integer llGetObjectPermMask(int mask) 9875 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9216,6 +9964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9216 case 4: 9964 case 4:
9217 return (int)item.NextPermissions; 9965 return (int)item.NextPermissions;
9218 } 9966 }
9967 m_host.TaskInventory.LockItemsForRead(false);
9219 9968
9220 return -1; 9969 return -1;
9221 } 9970 }
@@ -9418,31 +10167,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9418 UUID key = new UUID(); 10167 UUID key = new UUID();
9419 if (UUID.TryParse(id, out key)) 10168 if (UUID.TryParse(id, out key))
9420 { 10169 {
9421 try 10170 // return total object mass
9422 { 10171 SceneObjectPart part = World.GetSceneObjectPart(key);
9423 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10172 if (part != null)
9424 if (obj != null) 10173 return part.ParentGroup.GetMass();
9425 return (double)obj.GetMass(); 10174
9426 // the object is null so the key is for an avatar 10175 // the object is null so the key is for an avatar
9427 ScenePresence avatar = World.GetScenePresence(key); 10176 ScenePresence avatar = World.GetScenePresence(key);
9428 if (avatar != null) 10177 if (avatar != null)
9429 if (avatar.IsChildAgent)
9430 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9431 // child agents have a mass of 1.0
9432 return 1;
9433 else
9434 return (double)avatar.GetMass();
9435 }
9436 catch (KeyNotFoundException)
9437 { 10178 {
9438 return 0; // The Object/Agent not in the region so just return zero 10179 if (avatar.IsChildAgent)
10180 {
10181 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10182 // child agents have a mass of 1.0
10183 return 1;
10184 }
10185 else
10186 {
10187 return (double)avatar.GetMass();
10188 }
9439 } 10189 }
9440 } 10190 }
9441 return 0; 10191 return 0;
9442 } 10192 }
9443 10193
9444 /// <summary> 10194 /// <summary>
9445 /// illListReplaceList removes the sub-list defined by the inclusive indices 10195 /// llListReplaceList removes the sub-list defined by the inclusive indices
9446 /// start and end and inserts the src list in its place. The inclusive 10196 /// start and end and inserts the src list in its place. The inclusive
9447 /// nature of the indices means that at least one element must be deleted 10197 /// nature of the indices means that at least one element must be deleted
9448 /// if the indices are within the bounds of the existing list. I.e. 2,2 10198 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9499,16 +10249,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9499 // based upon end. Note that if end exceeds the upper 10249 // based upon end. Note that if end exceeds the upper
9500 // bound in this case, the entire destination list 10250 // bound in this case, the entire destination list
9501 // is removed. 10251 // is removed.
9502 else 10252 else if (start == 0)
9503 { 10253 {
9504 if (end + 1 < dest.Length) 10254 if (end + 1 < dest.Length)
9505 {
9506 return src + dest.GetSublist(end + 1, -1); 10255 return src + dest.GetSublist(end + 1, -1);
9507 }
9508 else 10256 else
9509 {
9510 return src; 10257 return src;
9511 } 10258 }
10259 else // Start < 0
10260 {
10261 if (end + 1 < dest.Length)
10262 return dest.GetSublist(end + 1, -1);
10263 else
10264 return new LSL_List();
9512 } 10265 }
9513 } 10266 }
9514 // Finally, if start > end, we strip away a prefix and 10267 // Finally, if start > end, we strip away a prefix and
@@ -9559,17 +10312,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9559 int width = 0; 10312 int width = 0;
9560 int height = 0; 10313 int height = 0;
9561 10314
9562 ParcelMediaCommandEnum? commandToSend = null; 10315 uint commandToSend = 0;
9563 float time = 0.0f; // default is from start 10316 float time = 0.0f; // default is from start
9564 10317
9565 ScenePresence presence = null; 10318 ScenePresence presence = null;
9566 10319
9567 for (int i = 0; i < commandList.Data.Length; i++) 10320 for (int i = 0; i < commandList.Data.Length; i++)
9568 { 10321 {
9569 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10322 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9570 switch (command) 10323 switch (command)
9571 { 10324 {
9572 case ParcelMediaCommandEnum.Agent: 10325 case (uint)ParcelMediaCommandEnum.Agent:
9573 // we send only to one agent 10326 // we send only to one agent
9574 if ((i + 1) < commandList.Length) 10327 if ((i + 1) < commandList.Length)
9575 { 10328 {
@@ -9586,25 +10339,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9586 } 10339 }
9587 break; 10340 break;
9588 10341
9589 case ParcelMediaCommandEnum.Loop: 10342 case (uint)ParcelMediaCommandEnum.Loop:
9590 loop = 1; 10343 loop = 1;
9591 commandToSend = command; 10344 commandToSend = command;
9592 update = true; //need to send the media update packet to set looping 10345 update = true; //need to send the media update packet to set looping
9593 break; 10346 break;
9594 10347
9595 case ParcelMediaCommandEnum.Play: 10348 case (uint)ParcelMediaCommandEnum.Play:
9596 loop = 0; 10349 loop = 0;
9597 commandToSend = command; 10350 commandToSend = command;
9598 update = true; //need to send the media update packet to make sure it doesn't loop 10351 update = true; //need to send the media update packet to make sure it doesn't loop
9599 break; 10352 break;
9600 10353
9601 case ParcelMediaCommandEnum.Pause: 10354 case (uint)ParcelMediaCommandEnum.Pause:
9602 case ParcelMediaCommandEnum.Stop: 10355 case (uint)ParcelMediaCommandEnum.Stop:
9603 case ParcelMediaCommandEnum.Unload: 10356 case (uint)ParcelMediaCommandEnum.Unload:
9604 commandToSend = command; 10357 commandToSend = command;
9605 break; 10358 break;
9606 10359
9607 case ParcelMediaCommandEnum.Url: 10360 case (uint)ParcelMediaCommandEnum.Url:
9608 if ((i + 1) < commandList.Length) 10361 if ((i + 1) < commandList.Length)
9609 { 10362 {
9610 if (commandList.Data[i + 1] is LSL_String) 10363 if (commandList.Data[i + 1] is LSL_String)
@@ -9617,7 +10370,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9617 } 10370 }
9618 break; 10371 break;
9619 10372
9620 case ParcelMediaCommandEnum.Texture: 10373 case (uint)ParcelMediaCommandEnum.Texture:
9621 if ((i + 1) < commandList.Length) 10374 if ((i + 1) < commandList.Length)
9622 { 10375 {
9623 if (commandList.Data[i + 1] is LSL_String) 10376 if (commandList.Data[i + 1] is LSL_String)
@@ -9630,7 +10383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 } 10383 }
9631 break; 10384 break;
9632 10385
9633 case ParcelMediaCommandEnum.Time: 10386 case (uint)ParcelMediaCommandEnum.Time:
9634 if ((i + 1) < commandList.Length) 10387 if ((i + 1) < commandList.Length)
9635 { 10388 {
9636 if (commandList.Data[i + 1] is LSL_Float) 10389 if (commandList.Data[i + 1] is LSL_Float)
@@ -9642,7 +10395,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9642 } 10395 }
9643 break; 10396 break;
9644 10397
9645 case ParcelMediaCommandEnum.AutoAlign: 10398 case (uint)ParcelMediaCommandEnum.AutoAlign:
9646 if ((i + 1) < commandList.Length) 10399 if ((i + 1) < commandList.Length)
9647 { 10400 {
9648 if (commandList.Data[i + 1] is LSL_Integer) 10401 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9656,7 +10409,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 } 10409 }
9657 break; 10410 break;
9658 10411
9659 case ParcelMediaCommandEnum.Type: 10412 case (uint)ParcelMediaCommandEnum.Type:
9660 if ((i + 1) < commandList.Length) 10413 if ((i + 1) < commandList.Length)
9661 { 10414 {
9662 if (commandList.Data[i + 1] is LSL_String) 10415 if (commandList.Data[i + 1] is LSL_String)
@@ -9669,7 +10422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9669 } 10422 }
9670 break; 10423 break;
9671 10424
9672 case ParcelMediaCommandEnum.Desc: 10425 case (uint)ParcelMediaCommandEnum.Desc:
9673 if ((i + 1) < commandList.Length) 10426 if ((i + 1) < commandList.Length)
9674 { 10427 {
9675 if (commandList.Data[i + 1] is LSL_String) 10428 if (commandList.Data[i + 1] is LSL_String)
@@ -9682,7 +10435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 } 10435 }
9683 break; 10436 break;
9684 10437
9685 case ParcelMediaCommandEnum.Size: 10438 case (uint)ParcelMediaCommandEnum.Size:
9686 if ((i + 2) < commandList.Length) 10439 if ((i + 2) < commandList.Length)
9687 { 10440 {
9688 if (commandList.Data[i + 1] is LSL_Integer) 10441 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9752,7 +10505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9752 } 10505 }
9753 } 10506 }
9754 10507
9755 if (commandToSend != null) 10508 if (commandToSend != 0)
9756 { 10509 {
9757 // the commandList contained a start/stop/... command, too 10510 // the commandList contained a start/stop/... command, too
9758 if (presence == null) 10511 if (presence == null)
@@ -9789,7 +10542,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9789 10542
9790 if (aList.Data[i] != null) 10543 if (aList.Data[i] != null)
9791 { 10544 {
9792 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10545 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9793 { 10546 {
9794 case ParcelMediaCommandEnum.Url: 10547 case ParcelMediaCommandEnum.Url:
9795 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10548 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9846,15 +10599,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9846 10599
9847 if (quick_pay_buttons.Data.Length < 4) 10600 if (quick_pay_buttons.Data.Length < 4)
9848 { 10601 {
9849 LSLError("List must have at least 4 elements"); 10602 int x;
9850 return; 10603 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10604 {
10605 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10606 }
9851 } 10607 }
9852 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10608 int[] nPrice = new int[5];
9853 10609 nPrice[0] = price;
9854 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10610 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9855 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10611 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9856 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10612 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9857 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10613 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10614 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9858 m_host.ParentGroup.HasGroupChanged = true; 10615 m_host.ParentGroup.HasGroupChanged = true;
9859 } 10616 }
9860 10617
@@ -9871,7 +10628,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9871 return new LSL_Vector(); 10628 return new LSL_Vector();
9872 } 10629 }
9873 10630
9874 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10631// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10632 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9875 if (presence != null) 10633 if (presence != null)
9876 { 10634 {
9877 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10635 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9893,7 +10651,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9893 return new LSL_Rotation(); 10651 return new LSL_Rotation();
9894 } 10652 }
9895 10653
9896 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10654// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10655 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9897 if (presence != null) 10656 if (presence != null)
9898 { 10657 {
9899 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10658 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9953,14 +10712,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9953 { 10712 {
9954 m_host.AddScriptLPS(1); 10713 m_host.AddScriptLPS(1);
9955 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10714 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9956 if (detectedParams == null) return; // only works on the first detected avatar 10715 if (detectedParams == null)
9957 10716 {
10717 if (m_host.ParentGroup.IsAttachment == true)
10718 {
10719 detectedParams = new DetectParams();
10720 detectedParams.Key = m_host.OwnerID;
10721 }
10722 else
10723 {
10724 return;
10725 }
10726 }
10727
9958 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10728 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9959 if (avatar != null) 10729 if (avatar != null)
9960 { 10730 {
9961 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10731 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9962 simname, pos, lookAt); 10732 simname, pos, lookAt);
9963 } 10733 }
10734
9964 ScriptSleep(1000); 10735 ScriptSleep(1000);
9965 } 10736 }
9966 10737
@@ -10084,12 +10855,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10084 10855
10085 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10856 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10086 object[] data = rules.Data; 10857 object[] data = rules.Data;
10087 for (int i = 0; i < data.Length; ++i) { 10858 for (int i = 0; i < data.Length; ++i)
10859 {
10088 int type = Convert.ToInt32(data[i++].ToString()); 10860 int type = Convert.ToInt32(data[i++].ToString());
10089 if (i >= data.Length) break; // odd number of entries => ignore the last 10861 if (i >= data.Length) break; // odd number of entries => ignore the last
10090 10862
10091 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10863 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10092 switch (type) { 10864 switch (type)
10865 {
10093 case ScriptBaseClass.CAMERA_FOCUS: 10866 case ScriptBaseClass.CAMERA_FOCUS:
10094 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10867 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10095 case ScriptBaseClass.CAMERA_POSITION: 10868 case ScriptBaseClass.CAMERA_POSITION:
@@ -10194,19 +10967,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10194 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10967 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10195 { 10968 {
10196 m_host.AddScriptLPS(1); 10969 m_host.AddScriptLPS(1);
10197 string ret = String.Empty; 10970
10198 string src1 = llBase64ToString(str1); 10971 if (str1 == String.Empty)
10199 string src2 = llBase64ToString(str2); 10972 return String.Empty;
10200 int c = 0; 10973 if (str2 == String.Empty)
10201 for (int i = 0; i < src1.Length; i++) 10974 return str1;
10975
10976 int len = str2.Length;
10977 if ((len % 4) != 0) // LL is EVIL!!!!
10202 { 10978 {
10203 ret += (char) (src1[i] ^ src2[c]); 10979 while (str2.EndsWith("="))
10980 str2 = str2.Substring(0, str2.Length - 1);
10981
10982 len = str2.Length;
10983 int mod = len % 4;
10204 10984
10205 c++; 10985 if (mod == 1)
10206 if (c >= src2.Length) 10986 str2 = str2.Substring(0, str2.Length - 1);
10207 c = 0; 10987 else if (mod == 2)
10988 str2 += "==";
10989 else if (mod == 3)
10990 str2 += "=";
10991 }
10992
10993 byte[] data1;
10994 byte[] data2;
10995 try
10996 {
10997 data1 = Convert.FromBase64String(str1);
10998 data2 = Convert.FromBase64String(str2);
10999 }
11000 catch (Exception)
11001 {
11002 return new LSL_String(String.Empty);
11003 }
11004
11005 byte[] d2 = new Byte[data1.Length];
11006 int pos = 0;
11007
11008 if (data1.Length <= data2.Length)
11009 {
11010 Array.Copy(data2, 0, d2, 0, data1.Length);
11011 }
11012 else
11013 {
11014 while (pos < data1.Length)
11015 {
11016 len = data1.Length - pos;
11017 if (len > data2.Length)
11018 len = data2.Length;
11019
11020 Array.Copy(data2, 0, d2, pos, len);
11021 pos += len;
11022 }
10208 } 11023 }
10209 return llStringToBase64(ret); 11024
11025 for (pos = 0 ; pos < data1.Length ; pos++ )
11026 data1[pos] ^= d2[pos];
11027
11028 return Convert.ToBase64String(data1);
10210 } 11029 }
10211 11030
10212 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11031 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10259,16 +11078,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10259 if (userAgent != null) 11078 if (userAgent != null)
10260 httpHeaders["User-Agent"] = userAgent; 11079 httpHeaders["User-Agent"] = userAgent;
10261 11080
11081 // See if the URL contains any header hacks
11082 string[] urlParts = url.Split(new char[] {'\n'});
11083 if (urlParts.Length > 1)
11084 {
11085 // Iterate the passed headers and parse them
11086 for (int i = 1 ; i < urlParts.Length ; i++ )
11087 {
11088 // The rest of those would be added to the body in SL.
11089 // Let's not do that.
11090 if (urlParts[i] == String.Empty)
11091 break;
11092
11093 // See if this could be a valid header
11094 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11095 if (headerParts.Length != 2)
11096 continue;
11097
11098 string headerName = headerParts[0].Trim();
11099 string headerValue = headerParts[1].Trim();
11100
11101 // Filter out headers that could be used to abuse
11102 // another system or cloak the request
11103 if (headerName.ToLower() == "x-secondlife-shard" ||
11104 headerName.ToLower() == "x-secondlife-object-name" ||
11105 headerName.ToLower() == "x-secondlife-object-key" ||
11106 headerName.ToLower() == "x-secondlife-region" ||
11107 headerName.ToLower() == "x-secondlife-local-position" ||
11108 headerName.ToLower() == "x-secondlife-local-velocity" ||
11109 headerName.ToLower() == "x-secondlife-local-rotation" ||
11110 headerName.ToLower() == "x-secondlife-owner-name" ||
11111 headerName.ToLower() == "x-secondlife-owner-key" ||
11112 headerName.ToLower() == "connection" ||
11113 headerName.ToLower() == "content-length" ||
11114 headerName.ToLower() == "from" ||
11115 headerName.ToLower() == "host" ||
11116 headerName.ToLower() == "proxy-authorization" ||
11117 headerName.ToLower() == "referer" ||
11118 headerName.ToLower() == "trailer" ||
11119 headerName.ToLower() == "transfer-encoding" ||
11120 headerName.ToLower() == "via" ||
11121 headerName.ToLower() == "authorization")
11122 continue;
11123
11124 httpHeaders[headerName] = headerValue;
11125 }
11126
11127 // Finally, strip any protocol specifier from the URL
11128 url = urlParts[0].Trim();
11129 int idx = url.IndexOf(" HTTP/");
11130 if (idx != -1)
11131 url = url.Substring(0, idx);
11132 }
11133
10262 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11134 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10263 Regex r = new Regex(authregex); 11135 Regex r = new Regex(authregex);
10264 int[] gnums = r.GetGroupNumbers(); 11136 int[] gnums = r.GetGroupNumbers();
10265 Match m = r.Match(url); 11137 Match m = r.Match(url);
10266 if (m.Success) { 11138 if (m.Success)
10267 for (int i = 1; i < gnums.Length; i++) { 11139 {
11140 for (int i = 1; i < gnums.Length; i++)
11141 {
10268 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11142 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10269 //CaptureCollection cc = g.Captures; 11143 //CaptureCollection cc = g.Captures;
10270 } 11144 }
10271 if (m.Groups.Count == 5) { 11145 if (m.Groups.Count == 5)
11146 {
10272 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11147 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10273 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11148 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10274 } 11149 }
@@ -10471,6 +11346,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10471 11346
10472 LSL_List ret = new LSL_List(); 11347 LSL_List ret = new LSL_List();
10473 UUID key = new UUID(); 11348 UUID key = new UUID();
11349
11350
10474 if (UUID.TryParse(id, out key)) 11351 if (UUID.TryParse(id, out key))
10475 { 11352 {
10476 ScenePresence av = World.GetScenePresence(key); 11353 ScenePresence av = World.GetScenePresence(key);
@@ -10488,13 +11365,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10488 ret.Add(new LSL_String("")); 11365 ret.Add(new LSL_String(""));
10489 break; 11366 break;
10490 case ScriptBaseClass.OBJECT_POS: 11367 case ScriptBaseClass.OBJECT_POS:
10491 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11368 Vector3 avpos;
11369
11370 if (av.ParentID != 0 && av.ParentPart != null)
11371 {
11372 avpos = av.OffsetPosition;
11373
11374 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11375 avpos -= sitOffset;
11376
11377 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11378 }
11379 else
11380 avpos = av.AbsolutePosition;
11381
11382 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10492 break; 11383 break;
10493 case ScriptBaseClass.OBJECT_ROT: 11384 case ScriptBaseClass.OBJECT_ROT:
10494 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11385 Quaternion avrot = av.Rotation;
11386 if (av.ParentID != 0 && av.ParentPart != null)
11387 {
11388 avrot = av.ParentPart.GetWorldRotation() * avrot;
11389 }
11390 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10495 break; 11391 break;
10496 case ScriptBaseClass.OBJECT_VELOCITY: 11392 case ScriptBaseClass.OBJECT_VELOCITY:
10497 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11393 Vector3 avvel = av.Velocity;
11394 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10498 break; 11395 break;
10499 case ScriptBaseClass.OBJECT_OWNER: 11396 case ScriptBaseClass.OBJECT_OWNER:
10500 ret.Add(new LSL_String(id)); 11397 ret.Add(new LSL_String(id));
@@ -10550,11 +11447,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10550 case ScriptBaseClass.OBJECT_NAME: 11447 case ScriptBaseClass.OBJECT_NAME:
10551 ret.Add(new LSL_String(obj.Name)); 11448 ret.Add(new LSL_String(obj.Name));
10552 break; 11449 break;
10553 case ScriptBaseClass.OBJECT_DESC: 11450 case ScriptBaseClass.OBJECT_DESC:
10554 ret.Add(new LSL_String(obj.Description)); 11451 ret.Add(new LSL_String(obj.Description));
10555 break; 11452 break;
10556 case ScriptBaseClass.OBJECT_POS: 11453 case ScriptBaseClass.OBJECT_POS:
10557 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11454 Vector3 opos = obj.AbsolutePosition;
11455 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10558 break; 11456 break;
10559 case ScriptBaseClass.OBJECT_ROT: 11457 case ScriptBaseClass.OBJECT_ROT:
10560 { 11458 {
@@ -10604,9 +11502,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10604 // The value returned in SL for normal prims is prim count 11502 // The value returned in SL for normal prims is prim count
10605 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11503 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10606 break; 11504 break;
10607 // The following 3 costs I have intentionaly coded to return zero. They are part of 11505
10608 // "Land Impact" calculations. These calculations are probably not applicable 11506 // costs below may need to be diferent for root parts, need to check
10609 // to OpenSim and are not yet complete in SL
10610 case ScriptBaseClass.OBJECT_SERVER_COST: 11507 case ScriptBaseClass.OBJECT_SERVER_COST:
10611 // The linden calculation is here 11508 // The linden calculation is here
10612 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11509 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10614,16 +11511,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10614 ret.Add(new LSL_Float(0)); 11511 ret.Add(new LSL_Float(0));
10615 break; 11512 break;
10616 case ScriptBaseClass.OBJECT_STREAMING_COST: 11513 case ScriptBaseClass.OBJECT_STREAMING_COST:
10617 // The linden calculation is here 11514 // The value returned in SL for normal prims is prim count * 0.06
10618 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11515 ret.Add(new LSL_Float(obj.StreamingCost));
10619 // The value returned in SL for normal prims looks like the prim count * 0.06
10620 ret.Add(new LSL_Float(0));
10621 break; 11516 break;
10622 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11517 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10623 // The linden calculation is here 11518 // The value returned in SL for normal prims is prim count
10624 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11519 ret.Add(new LSL_Float(obj.PhysicsCost));
10625 // The value returned in SL for normal prims looks like the prim count
10626 ret.Add(new LSL_Float(0));
10627 break; 11520 break;
10628 default: 11521 default:
10629 // Invalid or unhandled constant. 11522 // Invalid or unhandled constant.
@@ -10834,15 +11727,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10834 return result; 11727 return result;
10835 } 11728 }
10836 11729
10837 public void print(string str) 11730 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10838 { 11731 {
10839 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11732 List<SceneObjectPart> parts = GetLinkParts(link);
10840 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11733 if (parts.Count < 1)
10841 if (ossl != null) 11734 return 0;
10842 { 11735
10843 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11736 return GetNumberOfSides(parts[0]);
10844 m_log.Info("LSL print():" + str);
10845 }
10846 } 11737 }
10847 11738
10848 private string Name2Username(string name) 11739 private string Name2Username(string name)
@@ -10887,7 +11778,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10887 11778
10888 return rq.ToString(); 11779 return rq.ToString();
10889 } 11780 }
10890 11781/*
11782 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11783 {
11784 m_SayShoutCount = 0;
11785 }
11786*/
10891 private struct Tri 11787 private struct Tri
10892 { 11788 {
10893 public Vector3 p1; 11789 public Vector3 p1;
@@ -11027,9 +11923,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11027 11923
11028 ContactResult result = new ContactResult (); 11924 ContactResult result = new ContactResult ();
11029 result.ConsumerID = group.LocalId; 11925 result.ConsumerID = group.LocalId;
11030 result.Depth = intersection.distance; 11926// result.Depth = intersection.distance;
11031 result.Normal = intersection.normal; 11927 result.Normal = intersection.normal;
11032 result.Pos = intersection.ipoint; 11928 result.Pos = intersection.ipoint;
11929 result.Depth = Vector3.Mag(rayStart - result.Pos);
11033 11930
11034 contacts.Add(result); 11931 contacts.Add(result);
11035 }); 11932 });
@@ -11162,6 +12059,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11162 12059
11163 return contacts[0]; 12060 return contacts[0];
11164 } 12061 }
12062/*
12063 // not done:
12064 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12065 {
12066 ContactResult[] contacts = null;
12067 World.ForEachSOG(delegate(SceneObjectGroup group)
12068 {
12069 if (m_host.ParentGroup == group)
12070 return;
12071
12072 if (group.IsAttachment)
12073 return;
12074
12075 if(group.RootPart.PhysActor != null)
12076 return;
12077
12078 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12079 });
12080 return contacts;
12081 }
12082*/
11165 12083
11166 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12084 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11167 { 12085 {
@@ -11203,32 +12121,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11203 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12121 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11204 12122
11205 12123
11206 if (checkTerrain) 12124 if (World.SuportsRayCastFiltered())
11207 { 12125 {
11208 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12126 if (dist == 0)
11209 if (groundContact != null) 12127 return list;
11210 results.Add((ContactResult)groundContact);
11211 }
11212 12128
11213 if (checkAgents) 12129 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11214 { 12130 if (checkTerrain)
11215 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12131 rayfilter |= RayFilterFlags.land;
11216 foreach (ContactResult r in agentHits) 12132// if (checkAgents)
11217 results.Add(r); 12133// rayfilter |= RayFilterFlags.agent;
11218 } 12134 if (checkPhysical)
12135 rayfilter |= RayFilterFlags.physical;
12136 if (checkNonPhysical)
12137 rayfilter |= RayFilterFlags.nonphysical;
12138 if (detectPhantom)
12139 rayfilter |= RayFilterFlags.LSLPhanton;
12140
12141 Vector3 direction = dir * ( 1/dist);
12142
12143 if(rayfilter == 0)
12144 {
12145 list.Add(new LSL_Integer(0));
12146 return list;
12147 }
12148
12149 // get some more contacts to sort ???
12150 int physcount = 4 * count;
12151 if (physcount > 20)
12152 physcount = 20;
12153
12154 object physresults;
12155 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12156
12157 if (physresults == null)
12158 {
12159 list.Add(new LSL_Integer(-3)); // timeout error
12160 return list;
12161 }
11219 12162
11220 if (checkPhysical || checkNonPhysical || detectPhantom) 12163 results = (List<ContactResult>)physresults;
12164
12165 // for now physics doesn't detect sitted avatars so do it outside physics
12166 if (checkAgents)
12167 {
12168 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12169 foreach (ContactResult r in agentHits)
12170 results.Add(r);
12171 }
12172
12173 // TODO: Replace this with a better solution. ObjectIntersection can only
12174 // detect nonphysical phantoms. They are detected by virtue of being
12175 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12176 // physicsl phantoms as done by the physics scene
12177 // We don't want anything else but phantoms here.
12178 if (detectPhantom)
12179 {
12180 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12181 foreach (ContactResult r in objectHits)
12182 results.Add(r);
12183 }
12184 }
12185 else
11221 { 12186 {
11222 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12187 if (checkTerrain)
11223 foreach (ContactResult r in objectHits) 12188 {
11224 results.Add(r); 12189 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12190 if (groundContact != null)
12191 results.Add((ContactResult)groundContact);
12192 }
12193
12194 if (checkAgents)
12195 {
12196 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12197 foreach (ContactResult r in agentHits)
12198 results.Add(r);
12199 }
12200
12201 if (checkPhysical || checkNonPhysical || detectPhantom)
12202 {
12203 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12204 foreach (ContactResult r in objectHits)
12205 results.Add(r);
12206 }
11225 } 12207 }
11226 12208
11227 results.Sort(delegate(ContactResult a, ContactResult b) 12209 results.Sort(delegate(ContactResult a, ContactResult b)
11228 { 12210 {
11229 return a.Depth.CompareTo(b.Depth); 12211 return a.Depth.CompareTo(b.Depth);
11230 }); 12212 });
11231 12213
11232 int values = 0; 12214 int values = 0;
11233 SceneObjectGroup thisgrp = m_host.ParentGroup; 12215 SceneObjectGroup thisgrp = m_host.ParentGroup;
11234 12216
@@ -11321,7 +12303,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11321 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12303 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11322 if (!isAccount) return 0; 12304 if (!isAccount) return 0;
11323 if (estate.HasAccess(id)) return 1; 12305 if (estate.HasAccess(id)) return 1;
11324 if (estate.IsBanned(id)) 12306 if (estate.IsBanned(id, World.GetUserFlags(id)))
11325 estate.RemoveBan(id); 12307 estate.RemoveBan(id);
11326 estate.AddEstateUser(id); 12308 estate.AddEstateUser(id);
11327 break; 12309 break;
@@ -11340,14 +12322,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11340 break; 12322 break;
11341 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12323 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11342 if (!isAccount) return 0; 12324 if (!isAccount) return 0;
11343 if (estate.IsBanned(id)) return 1; 12325 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11344 EstateBan ban = new EstateBan(); 12326 EstateBan ban = new EstateBan();
11345 ban.EstateID = estate.EstateID; 12327 ban.EstateID = estate.EstateID;
11346 ban.BannedUserID = id; 12328 ban.BannedUserID = id;
11347 estate.AddBan(ban); 12329 estate.AddBan(ban);
11348 break; 12330 break;
11349 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12331 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11350 if (!isAccount || !estate.IsBanned(id)) return 0; 12332 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11351 estate.RemoveBan(id); 12333 estate.RemoveBan(id);
11352 break; 12334 break;
11353 default: return 0; 12335 default: return 0;
@@ -11376,7 +12358,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11376 return 16384; 12358 return 16384;
11377 } 12359 }
11378 12360
11379 public LSL_Integer llGetUsedMemory() 12361 public virtual LSL_Integer llGetUsedMemory()
11380 { 12362 {
11381 m_host.AddScriptLPS(1); 12363 m_host.AddScriptLPS(1);
11382 // The value returned for LSO scripts in SL 12364 // The value returned for LSO scripts in SL
@@ -11404,22 +12386,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11404 public void llSetSoundQueueing(int queue) 12386 public void llSetSoundQueueing(int queue)
11405 { 12387 {
11406 m_host.AddScriptLPS(1); 12388 m_host.AddScriptLPS(1);
11407 NotImplemented("llSetSoundQueueing");
11408 } 12389 }
11409 12390
11410 public void llCollisionSprite(string impact_sprite) 12391 public void llCollisionSprite(string impact_sprite)
11411 { 12392 {
11412 m_host.AddScriptLPS(1); 12393 m_host.AddScriptLPS(1);
11413 NotImplemented("llCollisionSprite"); 12394 // Viewer 2.0 broke this and it's likely LL has no intention
12395 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11414 } 12396 }
11415 12397
11416 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12398 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11417 { 12399 {
11418 m_host.AddScriptLPS(1); 12400 m_host.AddScriptLPS(1);
11419 NotImplemented("llGodLikeRezObject"); 12401
12402 if (!World.Permissions.IsGod(m_host.OwnerID))
12403 NotImplemented("llGodLikeRezObject");
12404
12405 AssetBase rezAsset = World.AssetService.Get(inventory);
12406 if (rezAsset == null)
12407 {
12408 llSay(0, "Asset not found");
12409 return;
12410 }
12411
12412 SceneObjectGroup group = null;
12413
12414 try
12415 {
12416 string xmlData = Utils.BytesToString(rezAsset.Data);
12417 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12418 }
12419 catch
12420 {
12421 llSay(0, "Asset not found");
12422 return;
12423 }
12424
12425 if (group == null)
12426 {
12427 llSay(0, "Asset not found");
12428 return;
12429 }
12430
12431 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12432 group.RootPart.AttachOffset = group.AbsolutePosition;
12433
12434 group.ResetIDs();
12435
12436 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12437 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12438 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12439 group.ScheduleGroupForFullUpdate();
12440
12441 // objects rezzed with this method are die_at_edge by default.
12442 group.RootPart.SetDieAtEdge(true);
12443
12444 group.ResumeScripts();
12445
12446 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12447 "object_rez", new Object[] {
12448 new LSL_String(
12449 group.RootPart.UUID.ToString()) },
12450 new DetectParams[0]));
12451 }
12452
12453 public LSL_String llTransferLindenDollars(string destination, int amount)
12454 {
12455 UUID txn = UUID.Random();
12456
12457 Util.FireAndForget(delegate(object x)
12458 {
12459 int replycode = 0;
12460 string replydata = destination + "," + amount.ToString();
12461
12462 try
12463 {
12464 TaskInventoryItem item = m_item;
12465 if (item == null)
12466 {
12467 replydata = "SERVICE_ERROR";
12468 return;
12469 }
12470
12471 m_host.AddScriptLPS(1);
12472
12473 if (item.PermsGranter == UUID.Zero)
12474 {
12475 replydata = "MISSING_PERMISSION_DEBIT";
12476 return;
12477 }
12478
12479 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12480 {
12481 replydata = "MISSING_PERMISSION_DEBIT";
12482 return;
12483 }
12484
12485 UUID toID = new UUID();
12486
12487 if (!UUID.TryParse(destination, out toID))
12488 {
12489 replydata = "INVALID_AGENT";
12490 return;
12491 }
12492
12493 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12494
12495 if (money == null)
12496 {
12497 replydata = "TRANSFERS_DISABLED";
12498 return;
12499 }
12500
12501 bool result = money.ObjectGiveMoney(
12502 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12503
12504 if (result)
12505 {
12506 replycode = 1;
12507 return;
12508 }
12509
12510 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12511 }
12512 finally
12513 {
12514 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12515 "transaction_result", new Object[] {
12516 new LSL_String(txn.ToString()),
12517 new LSL_Integer(replycode),
12518 new LSL_String(replydata) },
12519 new DetectParams[0]));
12520 }
12521 });
12522
12523 return txn.ToString();
11420 } 12524 }
11421 12525
11422 #endregion 12526 #endregion
12527
12528 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12529 {
12530 SceneObjectGroup group = m_host.ParentGroup;
12531
12532 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12533 return;
12534 if (group.IsAttachment)
12535 return;
12536
12537 if (frames.Data.Length > 0) // We are getting a new motion
12538 {
12539 if (group.RootPart.KeyframeMotion != null)
12540 group.RootPart.KeyframeMotion.Delete();
12541 group.RootPart.KeyframeMotion = null;
12542
12543 int idx = 0;
12544
12545 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12546 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12547
12548 while (idx < options.Data.Length)
12549 {
12550 int option = (int)options.GetLSLIntegerItem(idx++);
12551 int remain = options.Data.Length - idx;
12552
12553 switch (option)
12554 {
12555 case ScriptBaseClass.KFM_MODE:
12556 if (remain < 1)
12557 break;
12558 int modeval = (int)options.GetLSLIntegerItem(idx++);
12559 switch(modeval)
12560 {
12561 case ScriptBaseClass.KFM_FORWARD:
12562 mode = KeyframeMotion.PlayMode.Forward;
12563 break;
12564 case ScriptBaseClass.KFM_REVERSE:
12565 mode = KeyframeMotion.PlayMode.Reverse;
12566 break;
12567 case ScriptBaseClass.KFM_LOOP:
12568 mode = KeyframeMotion.PlayMode.Loop;
12569 break;
12570 case ScriptBaseClass.KFM_PING_PONG:
12571 mode = KeyframeMotion.PlayMode.PingPong;
12572 break;
12573 }
12574 break;
12575 case ScriptBaseClass.KFM_DATA:
12576 if (remain < 1)
12577 break;
12578 int dataval = (int)options.GetLSLIntegerItem(idx++);
12579 data = (KeyframeMotion.DataFormat)dataval;
12580 break;
12581 }
12582 }
12583
12584 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12585
12586 idx = 0;
12587
12588 int elemLength = 2;
12589 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12590 elemLength = 3;
12591
12592 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12593 while (idx < frames.Data.Length)
12594 {
12595 int remain = frames.Data.Length - idx;
12596
12597 if (remain < elemLength)
12598 break;
12599
12600 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12601 frame.Position = null;
12602 frame.Rotation = null;
12603
12604 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12605 {
12606 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12607 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12608 }
12609 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12610 {
12611 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12612 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12613 }
12614
12615 float tempf = (float)frames.GetLSLFloatItem(idx++);
12616 frame.TimeMS = (int)(tempf * 1000.0f);
12617
12618 keyframes.Add(frame);
12619 }
12620
12621 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12622 group.RootPart.KeyframeMotion.Start();
12623 }
12624 else
12625 {
12626 if (group.RootPart.KeyframeMotion == null)
12627 return;
12628
12629 if (options.Data.Length == 0)
12630 {
12631 group.RootPart.KeyframeMotion.Stop();
12632 return;
12633 }
12634
12635 int code = (int)options.GetLSLIntegerItem(0);
12636
12637 int idx = 0;
12638
12639 while (idx < options.Data.Length)
12640 {
12641 int option = (int)options.GetLSLIntegerItem(idx++);
12642 int remain = options.Data.Length - idx;
12643
12644 switch (option)
12645 {
12646 case ScriptBaseClass.KFM_COMMAND:
12647 int cmd = (int)options.GetLSLIntegerItem(idx++);
12648 switch (cmd)
12649 {
12650 case ScriptBaseClass.KFM_CMD_PLAY:
12651 group.RootPart.KeyframeMotion.Start();
12652 break;
12653 case ScriptBaseClass.KFM_CMD_STOP:
12654 group.RootPart.KeyframeMotion.Stop();
12655 break;
12656 case ScriptBaseClass.KFM_CMD_PAUSE:
12657 group.RootPart.KeyframeMotion.Pause();
12658 break;
12659 }
12660 break;
12661 }
12662 }
12663 }
12664 }
12665
12666 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12667 {
12668 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12669
12670 int idx = 0;
12671 int idxStart = 0;
12672
12673 bool positionChanged = false;
12674 Vector3 finalPos = Vector3.Zero;
12675
12676 try
12677 {
12678 while (idx < rules.Length)
12679 {
12680 ++rulesParsed;
12681 int code = rules.GetLSLIntegerItem(idx++);
12682
12683 int remain = rules.Length - idx;
12684 idxStart = idx;
12685
12686 switch (code)
12687 {
12688 case (int)ScriptBaseClass.PRIM_POSITION:
12689 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12690 {
12691 if (remain < 1)
12692 return null;
12693
12694 LSL_Vector v;
12695 v = rules.GetVector3Item(idx++);
12696
12697 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12698 if (part == null)
12699 break;
12700
12701 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12702 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12703 if (part.LinkNum > 1)
12704 {
12705 localRot = GetPartLocalRot(part);
12706 localPos = GetPartLocalPos(part);
12707 }
12708
12709 v -= localPos;
12710 v /= localRot;
12711
12712 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12713
12714 v = v + 2 * sitOffset;
12715
12716 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12717 av.SendAvatarDataToAllAgents();
12718
12719 }
12720 break;
12721
12722 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12723 case (int)ScriptBaseClass.PRIM_ROTATION:
12724 {
12725 if (remain < 1)
12726 return null;
12727
12728 LSL_Rotation r;
12729 r = rules.GetQuaternionItem(idx++);
12730
12731 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12732 if (part == null)
12733 break;
12734
12735 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12736 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12737
12738 if (part.LinkNum > 1)
12739 localRot = GetPartLocalRot(part);
12740
12741 r = r * llGetRootRotation() / localRot;
12742 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12743 av.SendAvatarDataToAllAgents();
12744 }
12745 break;
12746
12747 // parse rest doing nothing but number of parameters error check
12748 case (int)ScriptBaseClass.PRIM_SIZE:
12749 case (int)ScriptBaseClass.PRIM_MATERIAL:
12750 case (int)ScriptBaseClass.PRIM_PHANTOM:
12751 case (int)ScriptBaseClass.PRIM_PHYSICS:
12752 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12753 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12754 case (int)ScriptBaseClass.PRIM_NAME:
12755 case (int)ScriptBaseClass.PRIM_DESC:
12756 if (remain < 1)
12757 return null;
12758 idx++;
12759 break;
12760
12761 case (int)ScriptBaseClass.PRIM_GLOW:
12762 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12763 case (int)ScriptBaseClass.PRIM_TEXGEN:
12764 if (remain < 2)
12765 return null;
12766 idx += 2;
12767 break;
12768
12769 case (int)ScriptBaseClass.PRIM_TYPE:
12770 if (remain < 3)
12771 return null;
12772 code = (int)rules.GetLSLIntegerItem(idx++);
12773 remain = rules.Length - idx;
12774 switch (code)
12775 {
12776 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12777 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12778 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12779 if (remain < 6)
12780 return null;
12781 idx += 6;
12782 break;
12783
12784 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12785 if (remain < 5)
12786 return null;
12787 idx += 5;
12788 break;
12789
12790 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12791 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12792 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12793 if (remain < 11)
12794 return null;
12795 idx += 11;
12796 break;
12797
12798 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12799 if (remain < 2)
12800 return null;
12801 idx += 2;
12802 break;
12803 }
12804 break;
12805
12806 case (int)ScriptBaseClass.PRIM_COLOR:
12807 case (int)ScriptBaseClass.PRIM_TEXT:
12808 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12809 case (int)ScriptBaseClass.PRIM_OMEGA:
12810 if (remain < 3)
12811 return null;
12812 idx += 3;
12813 break;
12814
12815 case (int)ScriptBaseClass.PRIM_TEXTURE:
12816 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12817 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12818 if (remain < 5)
12819 return null;
12820 idx += 5;
12821 break;
12822
12823 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12824 if (remain < 7)
12825 return null;
12826
12827 idx += 7;
12828 break;
12829
12830 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12831 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12832 return null;
12833
12834 return rules.GetSublist(idx, -1);
12835 }
12836 }
12837 }
12838 catch (InvalidCastException e)
12839 {
12840 ShoutError(string.Format(
12841 "{0} error running rule #{1}: arg #{2} ",
12842 originFunc, rulesParsed, idx - idxStart) + e.Message);
12843 }
12844 finally
12845 {
12846 if (positionChanged)
12847 {
12848 av.OffsetPosition = finalPos;
12849// av.SendAvatarDataToAllAgents();
12850 av.SendTerseUpdateToAllClients();
12851 positionChanged = false;
12852 }
12853 }
12854 return null;
12855 }
12856
12857 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12858 {
12859 // avatars case
12860 // replies as SL wiki
12861
12862// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12863 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12864
12865 int idx = 0;
12866 while (idx < rules.Length)
12867 {
12868 int code = (int)rules.GetLSLIntegerItem(idx++);
12869 int remain = rules.Length - idx;
12870
12871 switch (code)
12872 {
12873 case (int)ScriptBaseClass.PRIM_MATERIAL:
12874 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12875 break;
12876
12877 case (int)ScriptBaseClass.PRIM_PHYSICS:
12878 res.Add(new LSL_Integer(0));
12879 break;
12880
12881 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12882 res.Add(new LSL_Integer(0));
12883 break;
12884
12885 case (int)ScriptBaseClass.PRIM_PHANTOM:
12886 res.Add(new LSL_Integer(0));
12887 break;
12888
12889 case (int)ScriptBaseClass.PRIM_POSITION:
12890
12891 Vector3 pos = avatar.OffsetPosition;
12892
12893 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12894 pos -= sitOffset;
12895
12896 if( sitPart != null)
12897 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12898
12899 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12900 break;
12901
12902 case (int)ScriptBaseClass.PRIM_SIZE:
12903 // as in llGetAgentSize above
12904 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_ROTATION:
12908 Quaternion rot = avatar.Rotation;
12909 if (sitPart != null)
12910 {
12911 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12912 }
12913
12914 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12915 break;
12916
12917 case (int)ScriptBaseClass.PRIM_TYPE:
12918 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12919 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12920 res.Add(new LSL_Vector(0f,1.0f,0f));
12921 res.Add(new LSL_Float(0.0f));
12922 res.Add(new LSL_Vector(0, 0, 0));
12923 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12924 res.Add(new LSL_Vector(0, 0, 0));
12925 break;
12926
12927 case (int)ScriptBaseClass.PRIM_TEXTURE:
12928 if (remain < 1)
12929 return null;
12930
12931 int face = (int)rules.GetLSLIntegerItem(idx++);
12932 if (face == ScriptBaseClass.ALL_SIDES)
12933 {
12934 for (face = 0; face < 21; face++)
12935 {
12936 res.Add(new LSL_String(""));
12937 res.Add(new LSL_Vector(0,0,0));
12938 res.Add(new LSL_Vector(0,0,0));
12939 res.Add(new LSL_Float(0.0));
12940 }
12941 }
12942 else
12943 {
12944 if (face >= 0 && face < 21)
12945 {
12946 res.Add(new LSL_String(""));
12947 res.Add(new LSL_Vector(0,0,0));
12948 res.Add(new LSL_Vector(0,0,0));
12949 res.Add(new LSL_Float(0.0));
12950 }
12951 }
12952 break;
12953
12954 case (int)ScriptBaseClass.PRIM_COLOR:
12955 if (remain < 1)
12956 return null;
12957
12958 face = (int)rules.GetLSLIntegerItem(idx++);
12959
12960 if (face == ScriptBaseClass.ALL_SIDES)
12961 {
12962 for (face = 0; face < 21; face++)
12963 {
12964 res.Add(new LSL_Vector(0,0,0));
12965 res.Add(new LSL_Float(0));
12966 }
12967 }
12968 else
12969 {
12970 res.Add(new LSL_Vector(0,0,0));
12971 res.Add(new LSL_Float(0));
12972 }
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12976 if (remain < 1)
12977 return null;
12978 face = (int)rules.GetLSLIntegerItem(idx++);
12979
12980 if (face == ScriptBaseClass.ALL_SIDES)
12981 {
12982 for (face = 0; face < 21; face++)
12983 {
12984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12986 }
12987 }
12988 else
12989 {
12990 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12991 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12992 }
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12996 if (remain < 1)
12997 return null;
12998 face = (int)rules.GetLSLIntegerItem(idx++);
12999
13000 if (face == ScriptBaseClass.ALL_SIDES)
13001 {
13002 for (face = 0; face < 21; face++)
13003 {
13004 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13005 }
13006 }
13007 else
13008 {
13009 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13010 }
13011 break;
13012
13013 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13014 res.Add(new LSL_Integer(0));
13015 res.Add(new LSL_Integer(0));// softness
13016 res.Add(new LSL_Float(0.0f)); // gravity
13017 res.Add(new LSL_Float(0.0f)); // friction
13018 res.Add(new LSL_Float(0.0f)); // wind
13019 res.Add(new LSL_Float(0.0f)); // tension
13020 res.Add(new LSL_Vector(0f,0f,0f));
13021 break;
13022
13023 case (int)ScriptBaseClass.PRIM_TEXGEN:
13024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13025 if (remain < 1)
13026 return null;
13027 face = (int)rules.GetLSLIntegerItem(idx++);
13028
13029 if (face == ScriptBaseClass.ALL_SIDES)
13030 {
13031 for (face = 0; face < 21; face++)
13032 {
13033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13034 }
13035 }
13036 else
13037 {
13038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13039 }
13040 break;
13041
13042 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13043 res.Add(new LSL_Integer(0));
13044 res.Add(new LSL_Vector(0f,0f,0f));
13045 res.Add(new LSL_Float(0f)); // intensity
13046 res.Add(new LSL_Float(0f)); // radius
13047 res.Add(new LSL_Float(0f)); // falloff
13048 break;
13049
13050 case (int)ScriptBaseClass.PRIM_GLOW:
13051 if (remain < 1)
13052 return null;
13053 face = (int)rules.GetLSLIntegerItem(idx++);
13054
13055 if (face == ScriptBaseClass.ALL_SIDES)
13056 {
13057 for (face = 0; face < 21; face++)
13058 {
13059 res.Add(new LSL_Float(0f));
13060 }
13061 }
13062 else
13063 {
13064 res.Add(new LSL_Float(0f));
13065 }
13066 break;
13067
13068 case (int)ScriptBaseClass.PRIM_TEXT:
13069 res.Add(new LSL_String(""));
13070 res.Add(new LSL_Vector(0f,0f,0f));
13071 res.Add(new LSL_Float(1.0f));
13072 break;
13073
13074 case (int)ScriptBaseClass.PRIM_NAME:
13075 res.Add(new LSL_String(avatar.Name));
13076 break;
13077
13078 case (int)ScriptBaseClass.PRIM_DESC:
13079 res.Add(new LSL_String(""));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13083 Quaternion lrot = avatar.Rotation;
13084
13085 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13086 {
13087 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13088 }
13089 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13090 break;
13091
13092 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13093 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13094 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13095 lpos -= lsitOffset;
13096
13097 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13098 {
13099 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13100 }
13101 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13102 break;
13103
13104 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13105 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13106 return null;
13107
13108 return rules.GetSublist(idx, -1);
13109 }
13110 }
13111
13112 return null;
13113 }
11423 } 13114 }
11424 13115
11425 public class NotecardCache 13116 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 828288d..51c8c7e 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;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new ScriptException("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new ScriptException("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1814,6 +1823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 1823
1815 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1824 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1816 { 1825 {
1826 m_host.TaskInventory.LockItemsForRead(true);
1817 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1827 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1818 { 1828 {
1819 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1829 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1821,6 +1831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 assetID = item.AssetID; 1831 assetID = item.AssetID;
1822 } 1832 }
1823 } 1833 }
1834 m_host.TaskInventory.LockItemsForRead(false);
1824 } 1835 }
1825 1836
1826 if (assetID == UUID.Zero) 1837 if (assetID == UUID.Zero)
@@ -2306,7 +2317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2306 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2317 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2307 m_host.AddScriptLPS(1); 2318 m_host.AddScriptLPS(1);
2308 2319
2309 return NpcCreate(firstname, lastname, position, notecard, false, false); 2320 return NpcCreate(firstname, lastname, position, notecard, true, false);
2310 } 2321 }
2311 2322
2312 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2323 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2317,24 +2328,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2317 return NpcCreate( 2328 return NpcCreate(
2318 firstname, lastname, position, notecard, 2329 firstname, lastname, position, notecard,
2319 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2330 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2320 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2331 false);
2332// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2321 } 2333 }
2322 2334
2323 private LSL_Key NpcCreate( 2335 private LSL_Key NpcCreate(
2324 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2336 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2325 { 2337 {
2338 if (!owned)
2339 OSSLError("Unowned NPCs are unsupported");
2340
2341 string groupTitle = String.Empty;
2342
2343 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2344 return new LSL_Key(UUID.Zero.ToString());
2345
2346 if (firstname != String.Empty || lastname != String.Empty)
2347 {
2348 if (firstname != "Shown outfit:")
2349 groupTitle = "- NPC -";
2350 }
2351
2326 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2352 INPCModule module = World.RequestModuleInterface<INPCModule>();
2327 if (module != null) 2353 if (module != null)
2328 { 2354 {
2329 AvatarAppearance appearance = null; 2355 AvatarAppearance appearance = null;
2330 2356
2331 UUID id; 2357// UUID id;
2332 if (UUID.TryParse(notecard, out id)) 2358// if (UUID.TryParse(notecard, out id))
2333 { 2359// {
2334 ScenePresence clonePresence = World.GetScenePresence(id); 2360// ScenePresence clonePresence = World.GetScenePresence(id);
2335 if (clonePresence != null) 2361// if (clonePresence != null)
2336 appearance = clonePresence.Appearance; 2362// appearance = clonePresence.Appearance;
2337 } 2363// }
2338 2364
2339 if (appearance == null) 2365 if (appearance == null)
2340 { 2366 {
@@ -2342,9 +2368,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 2368
2343 if (appearanceSerialized != null) 2369 if (appearanceSerialized != null)
2344 { 2370 {
2345 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2371 try
2346 appearance = new AvatarAppearance(); 2372 {
2347 appearance.Unpack(appearanceOsd); 2373 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2374 appearance = new AvatarAppearance();
2375 appearance.Unpack(appearanceOsd);
2376 }
2377 catch
2378 {
2379 return UUID.Zero.ToString();
2380 }
2348 } 2381 }
2349 else 2382 else
2350 { 2383 {
@@ -2363,6 +2396,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 World, 2396 World,
2364 appearance); 2397 appearance);
2365 2398
2399 ScenePresence sp;
2400 if (World.TryGetScenePresence(x, out sp))
2401 {
2402 sp.Grouptitle = groupTitle;
2403 sp.SendAvatarDataToAllAgents();
2404 }
2366 return new LSL_Key(x.ToString()); 2405 return new LSL_Key(x.ToString());
2367 } 2406 }
2368 2407
@@ -2666,16 +2705,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2666 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2667 m_host.AddScriptLPS(1); 2706 m_host.AddScriptLPS(1);
2668 2707
2669 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2708 ManualResetEvent ev = new ManualResetEvent(false);
2670 if (module != null)
2671 {
2672 UUID npcId = new UUID(npc.m_string);
2673 2709
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2710 Util.FireAndForget(delegate(object x) {
2675 return; 2711 try
2712 {
2713 INPCModule module = World.RequestModuleInterface<INPCModule>();
2714 if (module != null)
2715 {
2716 UUID npcId = new UUID(npc.m_string);
2676 2717
2677 module.DeleteNPC(npcId, World); 2718 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2678 } 2719 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2720 {
2721 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2722 return;
2723 }
2724
2725 module.DeleteNPC(npcId, World);
2726 }
2727 }
2728 finally
2729 {
2730 ev.Set();
2731 }
2732 });
2733 ev.WaitOne();
2679 } 2734 }
2680 2735
2681 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2736 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 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 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 bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
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 e97ff9d..05c20f9 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,12 @@ 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 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 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);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index cdd9ea8..c447d1f 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 880841b..0dd5a57 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;
@@ -643,6 +644,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
643 public const int PRIM_MEDIA_PERM_OWNER = 1; 644 public const int PRIM_MEDIA_PERM_OWNER = 1;
644 public const int PRIM_MEDIA_PERM_GROUP = 2; 645 public const int PRIM_MEDIA_PERM_GROUP = 2;
645 public const int PRIM_MEDIA_PERM_ANYONE = 4; 646 public const int PRIM_MEDIA_PERM_ANYONE = 4;
647
648 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
649 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
650 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
651 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
652
653 public const int PRIM_PHYSICS_MATERIAL = 31;
654 public const int DENSITY = 1;
655 public const int FRICTION = 2;
656 public const int RESTITUTION = 4;
657 public const int GRAVITY_MULTIPLIER = 8;
646 658
647 // extra constants for llSetPrimMediaParams 659 // extra constants for llSetPrimMediaParams
648 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 660 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -715,7 +727,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
715 727
716 public static readonly LSLInteger RCERR_UNKNOWN = -1; 728 public static readonly LSLInteger RCERR_UNKNOWN = -1;
717 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 729 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
718 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 730 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
731
732 public const int KFM_MODE = 1;
733 public const int KFM_LOOP = 1;
734 public const int KFM_REVERSE = 3;
735 public const int KFM_FORWARD = 0;
736 public const int KFM_PING_PONG = 2;
737 public const int KFM_DATA = 2;
738 public const int KFM_TRANSLATION = 2;
739 public const int KFM_ROTATION = 1;
740 public const int KFM_COMMAND = 0;
741 public const int KFM_CMD_PLAY = 0;
742 public const int KFM_CMD_STOP = 1;
743 public const int KFM_CMD_PAUSE = 2;
719 744
720 /// <summary> 745 /// <summary>
721 /// process name parameter as regex 746 /// 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 c457880..89b6eff 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();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
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 5a58f73..22804f5 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
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
185 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
@@ -189,22 +197,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Rotation.W); 197 presence.Rotation.W);
190 Velocity = new LSL_Types.Vector3(presence.Velocity); 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
191 199
192 if (presence.PresenceType != PresenceType.Npc) 200 Type = 0x01; // Avatar
193 { 201 if (presence.PresenceType == PresenceType.Npc)
194 Type = AGENT; 202 Type = 0x20;
195 } 203
196 else 204 // Cope Impl. We don't use OS_NPC.
197 { 205 //if (presence.PresenceType != PresenceType.Npc)
198 Type = OS_NPC; 206 //{
199 207 // Type = AGENT;
200 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 208 //}
201 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 209 //else
202 210 //{
203 if (npcData.SenseAsAgent) 211 // Type = OS_NPC;
204 { 212
205 Type |= AGENT; 213 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
206 } 214 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
207 } 215
216 // if (npcData.SenseAsAgent)
217 // {
218 // Type |= AGENT;
219 // }
220 //}
208 221
209 if (presence.Velocity != Vector3.Zero) 222 if (presence.Velocity != Vector3.Zero)
210 Type |= ACTIVE; 223 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 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;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 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 fcb98a5..c9c4753 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)
@@ -686,24 +688,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
686 688
687 public static bool operator ==(list a, list b) 689 public static bool operator ==(list a, list b)
688 { 690 {
689 int la = -1; 691 int la = a.Length;
690 int lb = -1; 692 int lb = b.Length;
691 try { la = a.Length; }
692 catch (NullReferenceException) { }
693 try { lb = b.Length; }
694 catch (NullReferenceException) { }
695 693
696 return la == lb; 694 return la == lb;
697 } 695 }
698 696
699 public static bool operator !=(list a, list b) 697 public static bool operator !=(list a, list b)
700 { 698 {
701 int la = -1; 699 int la = a.Length;
702 int lb = -1; 700 int lb = b.Length;
703 try { la = a.Length; }
704 catch (NullReferenceException) { }
705 try {lb = b.Length;}
706 catch (NullReferenceException) { }
707 701
708 return la != lb; 702 return la != lb;
709 } 703 }
@@ -937,7 +931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
937 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 931 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
938 } 932 }
939 933
940 if (ascending == 0) 934 if (ascending != 1)
941 { 935 {
942 ret = 0 - ret; 936 ret = 0 - ret;
943 } 937 }
@@ -970,6 +964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
970 stride = 1; 964 stride = 1;
971 } 965 }
972 966
967 if ((Data.Length % stride) != 0)
968 return new list(ret);
969
973 // we can optimize here in the case where stride == 1 and the list 970 // we can optimize here in the case where stride == 1 and the list
974 // consists of homogeneous types 971 // consists of homogeneous types
975 972
@@ -989,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
989 if (homogeneous) 986 if (homogeneous)
990 { 987 {
991 Array.Sort(ret, new HomogeneousComparer()); 988 Array.Sort(ret, new HomogeneousComparer());
992 if (ascending == 0) 989 if (ascending != 1)
993 { 990 {
994 Array.Reverse(ret); 991 Array.Reverse(ret);
995 } 992 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0460f22..9f05666 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.Reflection; 34using System.Reflection;
@@ -128,6 +129,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
128 private Dictionary<UUID, IScriptInstance> m_Scripts = 129 private Dictionary<UUID, IScriptInstance> m_Scripts =
129 new Dictionary<UUID, IScriptInstance>(); 130 new Dictionary<UUID, IScriptInstance>();
130 131
132 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
133
131 // Maps the asset ID to the assembly 134 // Maps the asset ID to the assembly
132 135
133 private Dictionary<UUID, string> m_Assemblies = 136 private Dictionary<UUID, string> m_Assemblies =
@@ -150,6 +153,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
150 IWorkItemResult m_CurrentCompile = null; 153 IWorkItemResult m_CurrentCompile = null;
151 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 154 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
152 155
156 private void lockScriptsForRead(bool locked)
157 {
158 if (locked)
159 {
160 if (m_scriptsLock.RecursiveReadCount > 0)
161 {
162 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.");
163 m_scriptsLock.ExitReadLock();
164 }
165 if (m_scriptsLock.RecursiveWriteCount > 0)
166 {
167 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
168 m_scriptsLock.ExitWriteLock();
169 }
170
171 while (!m_scriptsLock.TryEnterReadLock(60000))
172 {
173 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.");
174 if (m_scriptsLock.IsWriteLockHeld)
175 {
176 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
177 }
178 }
179 }
180 else
181 {
182 if (m_scriptsLock.RecursiveReadCount > 0)
183 {
184 m_scriptsLock.ExitReadLock();
185 }
186 }
187 }
188 private void lockScriptsForWrite(bool locked)
189 {
190 if (locked)
191 {
192 if (m_scriptsLock.RecursiveReadCount > 0)
193 {
194 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.");
195 m_scriptsLock.ExitReadLock();
196 }
197 if (m_scriptsLock.RecursiveWriteCount > 0)
198 {
199 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
200 m_scriptsLock.ExitWriteLock();
201 }
202
203 while (!m_scriptsLock.TryEnterWriteLock(60000))
204 {
205 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.");
206 if (m_scriptsLock.IsWriteLockHeld)
207 {
208 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
209 }
210 }
211 }
212 else
213 {
214 if (m_scriptsLock.RecursiveWriteCount > 0)
215 {
216 m_scriptsLock.ExitWriteLock();
217 }
218 }
219 }
220
153 public string ScriptEngineName 221 public string ScriptEngineName
154 { 222 {
155 get { return "XEngine"; } 223 get { return "XEngine"; }
@@ -576,64 +644,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
576 { 644 {
577 if (!m_Enabled) 645 if (!m_Enabled)
578 return; 646 return;
647 lockScriptsForRead(true);
579 648
580 lock (m_Scripts) 649 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
581 {
582 m_log.InfoFormat(
583 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
584 650
585 foreach (IScriptInstance instance in m_Scripts.Values) 651// foreach (IScriptInstance instance in m_Scripts.Values)
652 foreach (IScriptInstance instance in instancesToDel)
653 {
654 // Force a final state save
655 //
656 if (m_Assemblies.ContainsKey(instance.AssetID))
586 { 657 {
587 // Force a final state save 658 string assembly = m_Assemblies[instance.AssetID];
588 //
589 if (m_Assemblies.ContainsKey(instance.AssetID))
590 {
591 string assembly = m_Assemblies[instance.AssetID];
592 659
593 try 660 try
594 { 661 {
595 instance.SaveState(assembly); 662 instance.SaveState(assembly);
596 }
597 catch (Exception e)
598 {
599 m_log.Error(
600 string.Format(
601 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
602 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
603 , e);
604 }
605 } 663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
672 }
606 673
607 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
608 // 675 //
609 instance.ClearQueue(); 676 instance.ClearQueue();
610 instance.Stop(0); 677 instance.Stop(0);
611 678
612 // Release events, timer, etc 679 // Release events, timer, etc
613 // 680 //
614 instance.DestroyScriptInstance(); 681 instance.DestroyScriptInstance();
615 682
616 // Unload scripts and app domains. 683 // Unload scripts and app domains
617 // Must be done explicitly because they have infinite 684 // Must be done explicitly because they have infinite
618 // lifetime. 685 // lifetime
619 // However, don't bother to do this if the simulator is shutting 686 //
620 // down since it takes a long time with many scripts. 687// if (!m_SimulatorShuttingDown)
621 if (!m_SimulatorShuttingDown) 688 {
689 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
690 if (m_DomainScripts[instance.AppDomain].Count == 0)
622 { 691 {
623 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 692 m_DomainScripts.Remove(instance.AppDomain);
624 if (m_DomainScripts[instance.AppDomain].Count == 0) 693 UnloadAppDomain(instance.AppDomain);
625 {
626 m_DomainScripts.Remove(instance.AppDomain);
627 UnloadAppDomain(instance.AppDomain);
628 }
629 } 694 }
630 } 695 }
631 696
632 m_Scripts.Clear(); 697// m_Scripts.Clear();
633 m_PrimObjects.Clear(); 698// m_PrimObjects.Clear();
634 m_Assemblies.Clear(); 699// m_Assemblies.Clear();
635 m_DomainScripts.Clear(); 700// m_DomainScripts.Clear();
636 } 701 }
702 lockScriptsForRead(false);
703 lockScriptsForWrite(true);
704 m_Scripts.Clear();
705 lockScriptsForWrite(false);
706 m_PrimObjects.Clear();
707 m_Assemblies.Clear();
708 m_DomainScripts.Clear();
709
637 lock (m_ScriptEngines) 710 lock (m_ScriptEngines)
638 { 711 {
639 m_ScriptEngines.Remove(this); 712 m_ScriptEngines.Remove(this);
@@ -702,22 +775,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 775
703 List<IScriptInstance> instances = new List<IScriptInstance>(); 776 List<IScriptInstance> instances = new List<IScriptInstance>();
704 777
705 lock (m_Scripts) 778 lockScriptsForRead(true);
706 { 779 foreach (IScriptInstance instance in m_Scripts.Values)
707 foreach (IScriptInstance instance in m_Scripts.Values)
708 instances.Add(instance); 780 instances.Add(instance);
709 } 781 lockScriptsForRead(false);
710 782
711 foreach (IScriptInstance i in instances) 783 foreach (IScriptInstance i in instances)
712 { 784 {
713 string assembly = String.Empty; 785 string assembly = String.Empty;
714 786
715 lock (m_Scripts) 787
716 {
717 if (!m_Assemblies.ContainsKey(i.AssetID)) 788 if (!m_Assemblies.ContainsKey(i.AssetID))
718 continue; 789 continue;
719 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
720 } 791
721 792
722 try 793 try
723 { 794 {
@@ -1119,96 +1190,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 } 1190 }
1120 1191
1121 ScriptInstance instance = null; 1192 ScriptInstance instance = null;
1122 lock (m_Scripts) 1193 // Create the object record
1194 lockScriptsForRead(true);
1195 if ((!m_Scripts.ContainsKey(itemID)) ||
1196 (m_Scripts[itemID].AssetID != assetID))
1123 { 1197 {
1124 // Create the object record 1198 lockScriptsForRead(false);
1125 if ((!m_Scripts.ContainsKey(itemID)) ||
1126 (m_Scripts[itemID].AssetID != assetID))
1127 {
1128 UUID appDomain = assetID;
1129 1199
1130 if (part.ParentGroup.IsAttachment) 1200 UUID appDomain = assetID;
1131 appDomain = part.ParentGroup.RootPart.UUID;
1132 1201
1133 if (!m_AppDomains.ContainsKey(appDomain)) 1202 if (part.ParentGroup.IsAttachment)
1134 { 1203 appDomain = part.ParentGroup.RootPart.UUID;
1135 try
1136 {
1137 AppDomainSetup appSetup = new AppDomainSetup();
1138 appSetup.PrivateBinPath = Path.Combine(
1139 m_ScriptEnginesPath,
1140 m_Scene.RegionInfo.RegionID.ToString());
1141 1204
1142 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1205 if (!m_AppDomains.ContainsKey(appDomain))
1143 Evidence evidence = new Evidence(baseEvidence); 1206 {
1207 try
1208 {
1209 AppDomainSetup appSetup = new AppDomainSetup();
1210 appSetup.PrivateBinPath = Path.Combine(
1211 m_ScriptEnginesPath,
1212 m_Scene.RegionInfo.RegionID.ToString());
1144 1213
1145 AppDomain sandbox; 1214 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1146 if (m_AppDomainLoading) 1215 Evidence evidence = new Evidence(baseEvidence);
1147 {
1148 sandbox = AppDomain.CreateDomain(
1149 m_Scene.RegionInfo.RegionID.ToString(),
1150 evidence, appSetup);
1151 sandbox.AssemblyResolve +=
1152 new ResolveEventHandler(
1153 AssemblyResolver.OnAssemblyResolve);
1154 }
1155 else
1156 {
1157 sandbox = AppDomain.CurrentDomain;
1158 }
1159
1160 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1161 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1162 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1163 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1164 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1165 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1166 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1167
1168 m_AppDomains[appDomain] = sandbox;
1169 1216
1170 m_DomainScripts[appDomain] = new List<UUID>(); 1217 AppDomain sandbox;
1218 if (m_AppDomainLoading)
1219 {
1220 sandbox = AppDomain.CreateDomain(
1221 m_Scene.RegionInfo.RegionID.ToString(),
1222 evidence, appSetup);
1223 m_AppDomains[appDomain].AssemblyResolve +=
1224 new ResolveEventHandler(
1225 AssemblyResolver.OnAssemblyResolve);
1171 } 1226 }
1172 catch (Exception e) 1227 else
1173 { 1228 {
1174 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1229 sandbox = AppDomain.CurrentDomain;
1175 m_ScriptErrorMessage += "Exception creating app domain:\n";
1176 m_ScriptFailCount++;
1177 lock (m_AddingAssemblies)
1178 {
1179 m_AddingAssemblies[assembly]--;
1180 }
1181 return false;
1182 } 1230 }
1183 }
1184 m_DomainScripts[appDomain].Add(itemID);
1185
1186 instance = new ScriptInstance(this, part,
1187 itemID, assetID, assembly,
1188 m_AppDomains[appDomain],
1189 part.ParentGroup.RootPart.Name,
1190 item.Name, startParam, postOnRez,
1191 stateSource, m_MaxScriptQueue);
1192
1193// if (DebugLevel >= 1)
1194// m_log.DebugFormat(
1195// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1196// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1197// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1198 1231
1199 if (presence != null) 1232 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1233 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1234 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1235 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1236 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1237 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1238 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1239
1240 m_AppDomains[appDomain] = sandbox;
1241
1242 m_DomainScripts[appDomain] = new List<UUID>();
1243 }
1244 catch (Exception e)
1200 { 1245 {
1201 ShowScriptSaveResponse(item.OwnerID, 1246 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1202 assetID, "Compile successful", true); 1247 m_ScriptErrorMessage += "Exception creating app domain:\n";
1248 m_ScriptFailCount++;
1249 lock (m_AddingAssemblies)
1250 {
1251 m_AddingAssemblies[assembly]--;
1252 }
1253 return false;
1203 } 1254 }
1255 }
1256 m_DomainScripts[appDomain].Add(itemID);
1257
1258 instance = new ScriptInstance(this, part,
1259 itemID, assetID, assembly,
1260 m_AppDomains[appDomain],
1261 part.ParentGroup.RootPart.Name,
1262 item.Name, startParam, postOnRez,
1263 stateSource, m_MaxScriptQueue);
1264
1265// m_log.DebugFormat(
1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1204 1269
1205 instance.AppDomain = appDomain; 1270 if (presence != null)
1206 instance.LineMap = linemap; 1271 {
1207 1272 ShowScriptSaveResponse(item.OwnerID,
1208 m_Scripts[itemID] = instance; 1273 assetID, "Compile successful", true);
1209 } 1274 }
1210 }
1211 1275
1276 instance.AppDomain = appDomain;
1277 instance.LineMap = linemap;
1278 lockScriptsForWrite(true);
1279 m_Scripts[itemID] = instance;
1280 lockScriptsForWrite(false);
1281 }
1282 else
1283 {
1284 lockScriptsForRead(false);
1285 }
1212 lock (m_PrimObjects) 1286 lock (m_PrimObjects)
1213 { 1287 {
1214 if (!m_PrimObjects.ContainsKey(localID)) 1288 if (!m_PrimObjects.ContainsKey(localID))
@@ -1226,7 +1300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1226 m_AddingAssemblies[assembly]--; 1300 m_AddingAssemblies[assembly]--;
1227 } 1301 }
1228 1302
1229 if (instance != null) 1303 if (instance!=null)
1230 instance.Init(); 1304 instance.Init();
1231 1305
1232 bool runIt; 1306 bool runIt;
@@ -1249,18 +1323,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1249 m_CompileDict.Remove(itemID); 1323 m_CompileDict.Remove(itemID);
1250 } 1324 }
1251 1325
1252 IScriptInstance instance = null; 1326 lockScriptsForRead(true);
1253 1327 // Do we even have it?
1254 lock (m_Scripts) 1328 if (!m_Scripts.ContainsKey(itemID))
1255 { 1329 {
1256 // Do we even have it? 1330 // Do we even have it?
1257 if (!m_Scripts.ContainsKey(itemID)) 1331 if (!m_Scripts.ContainsKey(itemID))
1258 return; 1332 return;
1259 1333
1260 instance = m_Scripts[itemID]; 1334 lockScriptsForRead(false);
1335 lockScriptsForWrite(true);
1261 m_Scripts.Remove(itemID); 1336 m_Scripts.Remove(itemID);
1337 lockScriptsForWrite(false);
1338
1339 return;
1262 } 1340 }
1341
1263 1342
1343 IScriptInstance instance=m_Scripts[itemID];
1344 lockScriptsForRead(false);
1345 lockScriptsForWrite(true);
1346 m_Scripts.Remove(itemID);
1347 lockScriptsForWrite(false);
1264 instance.ClearQueue(); 1348 instance.ClearQueue();
1265 1349
1266 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1350 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1299,8 +1383,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1299 1383
1300 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1384 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1301 if (handlerObjectRemoved != null) 1385 if (handlerObjectRemoved != null)
1302 handlerObjectRemoved(instance.ObjectID); 1386 {
1387 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1388 handlerObjectRemoved(part.UUID);
1389 }
1303 1390
1391 CleanAssemblies();
1392
1304 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1393 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1305 if (handlerScriptRemoved != null) 1394 if (handlerScriptRemoved != null)
1306 handlerScriptRemoved(itemID); 1395 handlerScriptRemoved(itemID);
@@ -1561,12 +1650,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1561 private IScriptInstance GetInstance(UUID itemID) 1650 private IScriptInstance GetInstance(UUID itemID)
1562 { 1651 {
1563 IScriptInstance instance; 1652 IScriptInstance instance;
1564 lock (m_Scripts) 1653 lockScriptsForRead(true);
1654 if (!m_Scripts.ContainsKey(itemID))
1565 { 1655 {
1566 if (!m_Scripts.ContainsKey(itemID)) 1656 lockScriptsForRead(false);
1567 return null; 1657 return null;
1568 instance = m_Scripts[itemID];
1569 } 1658 }
1659 instance = m_Scripts[itemID];
1660 lockScriptsForRead(false);
1570 return instance; 1661 return instance;
1571 } 1662 }
1572 1663
@@ -1590,6 +1681,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1590 return false; 1681 return false;
1591 } 1682 }
1592 1683
1684 [DebuggerNonUserCode]
1593 public void ApiResetScript(UUID itemID) 1685 public void ApiResetScript(UUID itemID)
1594 { 1686 {
1595 IScriptInstance instance = GetInstance(itemID); 1687 IScriptInstance instance = GetInstance(itemID);
@@ -1651,6 +1743,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1651 return UUID.Zero; 1743 return UUID.Zero;
1652 } 1744 }
1653 1745
1746 [DebuggerNonUserCode]
1654 public void SetState(UUID itemID, string newState) 1747 public void SetState(UUID itemID, string newState)
1655 { 1748 {
1656 IScriptInstance instance = GetInstance(itemID); 1749 IScriptInstance instance = GetInstance(itemID);
@@ -1673,11 +1766,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1673 1766
1674 List<IScriptInstance> instances = new List<IScriptInstance>(); 1767 List<IScriptInstance> instances = new List<IScriptInstance>();
1675 1768
1676 lock (m_Scripts) 1769 lockScriptsForRead(true);
1677 { 1770 foreach (IScriptInstance instance in m_Scripts.Values)
1678 foreach (IScriptInstance instance in m_Scripts.Values)
1679 instances.Add(instance); 1771 instances.Add(instance);
1680 } 1772 lockScriptsForRead(false);
1681 1773
1682 foreach (IScriptInstance i in instances) 1774 foreach (IScriptInstance i in instances)
1683 { 1775 {