aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3216
-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.cs87
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs378
19 files changed, 3263 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..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..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 f9b90c5..253d193 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{
@@ -105,16 +109,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
105 protected int m_notecardLineReadCharsMax = 255; 109 protected int m_notecardLineReadCharsMax = 255;
106 protected int m_scriptConsoleChannel = 0; 110 protected int m_scriptConsoleChannel = 0;
107 protected bool m_scriptConsoleChannelEnabled = false; 111 protected bool m_scriptConsoleChannelEnabled = false;
112 protected bool m_debuggerSafe = false;
108 protected IUrlModule m_UrlModule = null; 113 protected IUrlModule m_UrlModule = null;
109 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 114 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
110 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 115 new Dictionary<UUID, UserInfoCacheEntry>();
116 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
111 protected ISoundModule m_SoundModule = null; 117 protected ISoundModule m_SoundModule = null;
112 118
119// protected Timer m_ShoutSayTimer;
120 protected int m_SayShoutCount = 0;
121 DateTime m_lastSayShoutCheck;
122
123 private Dictionary<string, string> MovementAnimationsForLSL =
124 new Dictionary<string, string> {
125 {"FLY", "Flying"},
126 {"FLYSLOW", "FlyingSlow"},
127 {"HOVER_UP", "Hovering Up"},
128 {"HOVER_DOWN", "Hovering Down"},
129 {"HOVER", "Hovering"},
130 {"LAND", "Landing"},
131 {"FALLDOWN", "Falling Down"},
132 {"PREJUMP", "PreJumping"},
133 {"JUMP", "Jumping"},
134 {"STANDUP", "Standing Up"},
135 {"SOFT_LAND", "Soft Landing"},
136 {"STAND", "Standing"},
137 {"CROUCHWALK", "CrouchWalking"},
138 {"RUN", "Running"},
139 {"WALK", "Walking"},
140 {"CROUCH", "Crouching"},
141 {"TURNLEFT", "Turning Left"},
142 {"TURNRIGHT", "Turning Right"}
143 };
144
113 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 145 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
114 { 146 {
147/*
148 m_ShoutSayTimer = new Timer(1000);
149 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
150 m_ShoutSayTimer.AutoReset = true;
151 m_ShoutSayTimer.Start();
152*/
153 m_lastSayShoutCheck = DateTime.UtcNow;
154
115 m_ScriptEngine = ScriptEngine; 155 m_ScriptEngine = ScriptEngine;
116 m_host = host; 156 m_host = host;
117 m_item = item; 157 m_item = item;
158 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
118 159
119 LoadLimits(); // read script limits from config. 160 LoadLimits(); // read script limits from config.
120 161
@@ -179,6 +220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
179 get { return m_ScriptEngine.World; } 220 get { return m_ScriptEngine.World; }
180 } 221 }
181 222
223 [DebuggerNonUserCode]
182 public void state(string newState) 224 public void state(string newState)
183 { 225 {
184 m_ScriptEngine.SetState(m_item.ItemID, newState); 226 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -188,6 +230,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
188 /// Reset the named script. The script must be present 230 /// Reset the named script. The script must be present
189 /// in the same prim. 231 /// in the same prim.
190 /// </summary> 232 /// </summary>
233 [DebuggerNonUserCode]
191 public void llResetScript() 234 public void llResetScript()
192 { 235 {
193 m_host.AddScriptLPS(1); 236 m_host.AddScriptLPS(1);
@@ -250,6 +293,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 } 293 }
251 } 294 }
252 295
296 public List<ScenePresence> GetLinkAvatars(int linkType)
297 {
298 List<ScenePresence> ret = new List<ScenePresence>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
301
302 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
303
304 switch (linkType)
305 {
306 case ScriptBaseClass.LINK_SET:
307 return avs;
308
309 case ScriptBaseClass.LINK_ROOT:
310 return ret;
311
312 case ScriptBaseClass.LINK_ALL_OTHERS:
313 return avs;
314
315 case ScriptBaseClass.LINK_ALL_CHILDREN:
316 return avs;
317
318 case ScriptBaseClass.LINK_THIS:
319 return ret;
320
321 default:
322 if (linkType < 0)
323 return ret;
324
325 int partCount = m_host.ParentGroup.GetPartCount();
326
327 if (linkType <= partCount)
328 {
329 return ret;
330 }
331 else
332 {
333 linkType = linkType - partCount;
334 if (linkType > avs.Count)
335 {
336 return ret;
337 }
338 else
339 {
340 ret.Add(avs[linkType-1]);
341 return ret;
342 }
343 }
344 }
345 }
346
253 public List<SceneObjectPart> GetLinkParts(int linkType) 347 public List<SceneObjectPart> GetLinkParts(int linkType)
254 { 348 {
255 return GetLinkParts(m_host, linkType); 349 return GetLinkParts(m_host, linkType);
@@ -258,6 +352,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
258 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 352 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
259 { 353 {
260 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 354 List<SceneObjectPart> ret = new List<SceneObjectPart>();
355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
356 return ret;
261 ret.Add(part); 357 ret.Add(part);
262 358
263 switch (linkType) 359 switch (linkType)
@@ -484,31 +580,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
484 580
485 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 581 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
486 582
487 /// <summary> 583 // Utility function for llRot2Euler
488 /// Convert an LSL rotation to a Euler vector. 584
489 /// </summary> 585 // normalize an angle between -PI and PI (-180 to +180 degrees)
490 /// <remarks> 586 protected double NormalizeAngle(double angle)
491 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
492 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
493 /// </remarks>
494 /// <param name="r"></param>
495 /// <returns></returns>
496 public LSL_Vector llRot2Euler(LSL_Rotation r)
497 { 587 {
498 m_host.AddScriptLPS(1); 588 if (angle > -Math.PI && angle < Math.PI)
589 return angle;
499 590
500 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 591 int numPis = (int)(Math.PI / angle);
501 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 592 double remainder = angle - Math.PI * numPis;
502 if (m == 0.0) return new LSL_Vector(); 593 if (numPis % 2 == 1)
503 double x = Math.Atan2(-v.y, v.z); 594 return Math.PI - angle;
504 double sin = v.x / m; 595 return remainder;
505 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 596 }
506 double y = Math.Asin(sin);
507 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
508 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)));
509 double z = Math.Atan2(v.y, v.x);
510 597
511 return new LSL_Vector(x, y, z); 598 public LSL_Vector llRot2Euler(LSL_Rotation q1)
599 {
600 m_host.AddScriptLPS(1);
601 LSL_Vector eul = new LSL_Vector();
602
603 double sqw = q1.s*q1.s;
604 double sqx = q1.x*q1.x;
605 double sqy = q1.z*q1.z;
606 double sqz = q1.y*q1.y;
607 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
608 double test = q1.x*q1.z + q1.y*q1.s;
609 if (test > 0.4999*unit) { // singularity at north pole
610 eul.z = 2 * Math.Atan2(q1.x,q1.s);
611 eul.y = Math.PI/2;
612 eul.x = 0;
613 return eul;
614 }
615 if (test < -0.4999*unit) { // singularity at south pole
616 eul.z = -2 * Math.Atan2(q1.x,q1.s);
617 eul.y = -Math.PI/2;
618 eul.x = 0;
619 return eul;
620 }
621 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
622 eul.y = Math.Asin(2*test/unit);
623 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
624 return eul;
512 } 625 }
513 626
514 /* From wiki: 627 /* From wiki:
@@ -561,18 +674,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
561 m_host.AddScriptLPS(1); 674 m_host.AddScriptLPS(1);
562 675
563 double x,y,z,s; 676 double x,y,z,s;
564 677 v.x *= 0.5;
565 double c1 = Math.Cos(v.x * 0.5); 678 v.y *= 0.5;
566 double c2 = Math.Cos(v.y * 0.5); 679 v.z *= 0.5;
567 double c3 = Math.Cos(v.z * 0.5); 680 double c1 = Math.Cos(v.x);
568 double s1 = Math.Sin(v.x * 0.5); 681 double c2 = Math.Cos(v.y);
569 double s2 = Math.Sin(v.y * 0.5); 682 double c1c2 = c1 * c2;
570 double s3 = Math.Sin(v.z * 0.5); 683 double s1 = Math.Sin(v.x);
571 684 double s2 = Math.Sin(v.y);
572 x = s1 * c2 * c3 + c1 * s2 * s3; 685 double s1s2 = s1 * s2;
573 y = c1 * s2 * c3 - s1 * c2 * s3; 686 double c1s2 = c1 * s2;
574 z = s1 * s2 * c3 + c1 * c2 * s3; 687 double s1c2 = s1 * c2;
575 s = c1 * c2 * c3 - s1 * s2 * s3; 688 double c3 = Math.Cos(v.z);
689 double s3 = Math.Sin(v.z);
690
691 x = s1c2 * c3 + c1s2 * s3;
692 y = c1s2 * c3 - s1c2 * s3;
693 z = s1s2 * c3 + c1c2 * s3;
694 s = c1c2 * c3 - s1s2 * s3;
576 695
577 return new LSL_Rotation(x, y, z, s); 696 return new LSL_Rotation(x, y, z, s);
578 } 697 }
@@ -710,77 +829,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
710 { 829 {
711 //A and B should both be normalized 830 //A and B should both be normalized
712 m_host.AddScriptLPS(1); 831 m_host.AddScriptLPS(1);
713 LSL_Rotation rotBetween; 832 /* This method is more accurate than the SL one, and thus causes problems
714 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 833 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
715 // continue calculation. 834
716 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 835 double dotProduct = LSL_Vector.Dot(a, b);
836 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
837 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
838 double angle = Math.Acos(dotProduct / magProduct);
839 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
840 double s = Math.Sin(angle / 2);
841
842 double x = axis.x * s;
843 double y = axis.y * s;
844 double z = axis.z * s;
845 double w = Math.Cos(angle / 2);
846
847 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
848 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
849
850 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
851 */
852
853 // This method mimics the 180 errors found in SL
854 // See www.euclideanspace.com... angleBetween
855 LSL_Vector vec_a = a;
856 LSL_Vector vec_b = b;
857
858 // Eliminate zero length
859 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
860 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
861 if (vec_a_mag < 0.00001 ||
862 vec_b_mag < 0.00001)
717 { 863 {
718 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 864 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
719 } 865 }
720 else 866
867 // Normalize
868 vec_a = llVecNorm(vec_a);
869 vec_b = llVecNorm(vec_b);
870
871 // Calculate axis and rotation angle
872 LSL_Vector axis = vec_a % vec_b;
873 LSL_Float cos_theta = vec_a * vec_b;
874
875 // Check if parallel
876 if (cos_theta > 0.99999)
721 { 877 {
722 a = LSL_Vector.Norm(a); 878 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
723 b = LSL_Vector.Norm(b); 879 }
724 double dotProduct = LSL_Vector.Dot(a, b); 880
725 // There are two degenerate cases possible. These are for vectors 180 or 881 // Check if anti-parallel
726 // 0 degrees apart. These have to be detected and handled individually. 882 else if (cos_theta < -0.99999)
727 // 883 {
728 // Check for vectors 180 degrees apart. 884 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
729 // A dot product of -1 would mean the angle between vectors is 180 degrees. 885 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
730 if (dotProduct < -0.9999999f) 886 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
731 { 887 }
732 // First assume X axis is orthogonal to the vectors. 888 else // other rotation
733 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 889 {
734 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 890 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
735 // Check for near zero vector. A very small non-zero number here will create 891 axis = llVecNorm(axis);
736 // a rotation in an undesired direction. 892 double x, y, z, s, t;
737 if (LSL_Vector.Mag(orthoVector) > 0.0001) 893 s = Math.Cos(theta);
738 { 894 t = Math.Sin(theta);
739 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 895 x = axis.x * t;
740 } 896 y = axis.y * t;
741 // If the magnitude of the vector was near zero, then assume the X axis is not 897 z = axis.z * t;
742 // orthogonal and use the Z axis instead. 898 return new LSL_Rotation(x,y,z,s);
743 else
744 {
745 // Set 180 z rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
747 }
748 }
749 // Check for parallel vectors.
750 // A dot product of 1 would mean the angle between vectors is 0 degrees.
751 else if (dotProduct > 0.9999999f)
752 {
753 // Set zero rotation.
754 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
755 }
756 else
757 {
758 // All special checks have been performed so get the axis of rotation.
759 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
760 // Quarternion s value is the length of the unit vector + dot product.
761 double qs = 1.0 + dotProduct;
762 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
763 // Normalize the rotation.
764 double mag = LSL_Rotation.Mag(rotBetween);
765 // We shouldn't have to worry about a divide by zero here. The qs value will be
766 // non-zero because we already know if we're here, then the dotProduct is not -1 so
767 // qs will not be zero. Also, we've already handled the input vectors being zero so the
768 // crossProduct vector should also not be zero.
769 rotBetween.x = rotBetween.x / mag;
770 rotBetween.y = rotBetween.y / mag;
771 rotBetween.z = rotBetween.z / mag;
772 rotBetween.s = rotBetween.s / mag;
773 // Check for undefined values and set zero rotation if any found. This code might not actually be required
774 // any longer since zero vectors are checked for at the top.
775 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
776 {
777 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
778 }
779 }
780 } 899 }
781 return rotBetween;
782 } 900 }
783 901
784 public void llWhisper(int channelID, string text) 902 public void llWhisper(int channelID, string text)
785 { 903 {
786 m_host.AddScriptLPS(1); 904 m_host.AddScriptLPS(1);
@@ -796,10 +914,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
796 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 914 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
797 } 915 }
798 916
917 private void CheckSayShoutTime()
918 {
919 DateTime now = DateTime.UtcNow;
920 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
921 {
922 m_lastSayShoutCheck = now;
923 m_SayShoutCount = 0;
924 }
925 else
926 m_SayShoutCount++;
927 }
928
799 public void llSay(int channelID, string text) 929 public void llSay(int channelID, string text)
800 { 930 {
801 m_host.AddScriptLPS(1); 931 m_host.AddScriptLPS(1);
802 932
933 if (channelID == 0)
934// m_SayShoutCount++;
935 CheckSayShoutTime();
936
937 if (m_SayShoutCount >= 11)
938 ScriptSleep(2000);
939
803 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 940 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
804 { 941 {
805 Console.WriteLine(text); 942 Console.WriteLine(text);
@@ -822,6 +959,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
822 { 959 {
823 m_host.AddScriptLPS(1); 960 m_host.AddScriptLPS(1);
824 961
962 if (channelID == 0)
963// m_SayShoutCount++;
964 CheckSayShoutTime();
965
966 if (m_SayShoutCount >= 11)
967 ScriptSleep(2000);
968
825 if (text.Length > 1023) 969 if (text.Length > 1023)
826 text = text.Substring(0, 1023); 970 text = text.Substring(0, 1023);
827 971
@@ -853,22 +997,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
853 997
854 public void llRegionSayTo(string target, int channel, string msg) 998 public void llRegionSayTo(string target, int channel, string msg)
855 { 999 {
1000 string error = String.Empty;
1001
856 if (msg.Length > 1023) 1002 if (msg.Length > 1023)
857 msg = msg.Substring(0, 1023); 1003 msg = msg.Substring(0, 1023);
858 1004
859 m_host.AddScriptLPS(1); 1005 m_host.AddScriptLPS(1);
860 1006
861 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
862 {
863 return;
864 }
865
866 UUID TargetID; 1007 UUID TargetID;
867 UUID.TryParse(target, out TargetID); 1008 UUID.TryParse(target, out TargetID);
868 1009
869 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1010 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
870 if (wComm != null) 1011 if (wComm != null)
871 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1012 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1013 LSLError(error);
872 } 1014 }
873 1015
874 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1016 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1124,10 +1266,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1124 return detectedParams.TouchUV; 1266 return detectedParams.TouchUV;
1125 } 1267 }
1126 1268
1269 [DebuggerNonUserCode]
1127 public virtual void llDie() 1270 public virtual void llDie()
1128 { 1271 {
1129 m_host.AddScriptLPS(1); 1272 m_host.AddScriptLPS(1);
1130 throw new SelfDeleteException(); 1273 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1131 } 1274 }
1132 1275
1133 public LSL_Float llGround(LSL_Vector offset) 1276 public LSL_Float llGround(LSL_Vector offset)
@@ -1198,6 +1341,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1198 1341
1199 public void llSetStatus(int status, int value) 1342 public void llSetStatus(int status, int value)
1200 { 1343 {
1344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1345 return;
1201 m_host.AddScriptLPS(1); 1346 m_host.AddScriptLPS(1);
1202 1347
1203 int statusrotationaxis = 0; 1348 int statusrotationaxis = 0;
@@ -1221,6 +1366,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1221 if (!allow) 1366 if (!allow)
1222 return; 1367 return;
1223 1368
1369 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1370 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1371 return;
1372
1224 m_host.ScriptSetPhysicsStatus(true); 1373 m_host.ScriptSetPhysicsStatus(true);
1225 } 1374 }
1226 else 1375 else
@@ -1421,6 +1570,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1421 { 1570 {
1422 m_host.AddScriptLPS(1); 1571 m_host.AddScriptLPS(1);
1423 1572
1573 SetColor(m_host, color, face);
1574 }
1575
1576 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1581 Primitive.TextureEntry tex = part.Shape.Textures;
1582 Color4 texcolor;
1583 if (face >= 0 && face < GetNumberOfSides(part))
1584 {
1585 texcolor = tex.CreateFace((uint)face).RGBA;
1586 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1587 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1588 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1589 tex.FaceTextures[face].RGBA = texcolor;
1590 part.UpdateTextureEntry(tex.GetBytes());
1591 return;
1592 }
1593 else if (face == ScriptBaseClass.ALL_SIDES)
1594 {
1595 for (uint i = 0; i < GetNumberOfSides(part); i++)
1596 {
1597 if (tex.FaceTextures[i] != null)
1598 {
1599 texcolor = tex.FaceTextures[i].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.FaceTextures[i].RGBA = texcolor;
1604 }
1605 texcolor = tex.DefaultTexture.RGBA;
1606 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1607 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1608 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1609 tex.DefaultTexture.RGBA = texcolor;
1610 }
1611 part.UpdateTextureEntry(tex.GetBytes());
1612 return;
1613 }
1614
1424 if (face == ScriptBaseClass.ALL_SIDES) 1615 if (face == ScriptBaseClass.ALL_SIDES)
1425 face = SceneObjectPart.ALL_SIDES; 1616 face = SceneObjectPart.ALL_SIDES;
1426 1617
@@ -1429,6 +1620,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1429 1620
1430 public void SetTexGen(SceneObjectPart part, int face,int style) 1621 public void SetTexGen(SceneObjectPart part, int face,int style)
1431 { 1622 {
1623 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1624 return;
1625
1432 Primitive.TextureEntry tex = part.Shape.Textures; 1626 Primitive.TextureEntry tex = part.Shape.Textures;
1433 MappingType textype; 1627 MappingType textype;
1434 textype = MappingType.Default; 1628 textype = MappingType.Default;
@@ -1459,6 +1653,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1459 1653
1460 public void SetGlow(SceneObjectPart part, int face, float glow) 1654 public void SetGlow(SceneObjectPart part, int face, float glow)
1461 { 1655 {
1656 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return;
1658
1462 Primitive.TextureEntry tex = part.Shape.Textures; 1659 Primitive.TextureEntry tex = part.Shape.Textures;
1463 if (face >= 0 && face < GetNumberOfSides(part)) 1660 if (face >= 0 && face < GetNumberOfSides(part))
1464 { 1661 {
@@ -1484,6 +1681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1484 1681
1485 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1682 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1486 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1487 1686
1488 Shininess sval = new Shininess(); 1687 Shininess sval = new Shininess();
1489 1688
@@ -1534,6 +1733,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1534 1733
1535 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1734 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1536 { 1735 {
1736 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1737 return;
1738
1537 Primitive.TextureEntry tex = part.Shape.Textures; 1739 Primitive.TextureEntry tex = part.Shape.Textures;
1538 if (face >= 0 && face < GetNumberOfSides(part)) 1740 if (face >= 0 && face < GetNumberOfSides(part))
1539 { 1741 {
@@ -1594,13 +1796,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1594 m_host.AddScriptLPS(1); 1796 m_host.AddScriptLPS(1);
1595 1797
1596 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1798 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1597 1799 if (parts.Count > 0)
1598 foreach (SceneObjectPart part in parts) 1800 {
1599 SetAlpha(part, alpha, face); 1801 try
1802 {
1803 foreach (SceneObjectPart part in parts)
1804 SetAlpha(part, alpha, face);
1805 }
1806 finally
1807 {
1808 }
1809 }
1600 } 1810 }
1601 1811
1602 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1812 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1603 { 1813 {
1814 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1815 return;
1816
1604 Primitive.TextureEntry tex = part.Shape.Textures; 1817 Primitive.TextureEntry tex = part.Shape.Textures;
1605 Color4 texcolor; 1818 Color4 texcolor;
1606 if (face >= 0 && face < GetNumberOfSides(part)) 1819 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1653,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1653 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1866 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1654 float wind, float tension, LSL_Vector Force) 1867 float wind, float tension, LSL_Vector Force)
1655 { 1868 {
1656 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return; 1870 return;
1658 1871
1659 if (flexi) 1872 if (flexi)
@@ -1687,7 +1900,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 /// <param name="falloff"></param> 1900 /// <param name="falloff"></param>
1688 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1901 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1689 { 1902 {
1690 if (part == null) 1903 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return; 1904 return;
1692 1905
1693 if (light) 1906 if (light)
@@ -1720,11 +1933,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1720 Primitive.TextureEntry tex = part.Shape.Textures; 1933 Primitive.TextureEntry tex = part.Shape.Textures;
1721 Color4 texcolor; 1934 Color4 texcolor;
1722 LSL_Vector rgb = new LSL_Vector(); 1935 LSL_Vector rgb = new LSL_Vector();
1936 int nsides = GetNumberOfSides(part);
1937
1723 if (face == ScriptBaseClass.ALL_SIDES) 1938 if (face == ScriptBaseClass.ALL_SIDES)
1724 { 1939 {
1725 int i; 1940 int i;
1726 1941 for (i = 0; i < nsides; i++)
1727 for (i = 0 ; i < GetNumberOfSides(part); i++)
1728 { 1942 {
1729 texcolor = tex.GetFace((uint)i).RGBA; 1943 texcolor = tex.GetFace((uint)i).RGBA;
1730 rgb.x += texcolor.R; 1944 rgb.x += texcolor.R;
@@ -1732,14 +1946,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1732 rgb.z += texcolor.B; 1946 rgb.z += texcolor.B;
1733 } 1947 }
1734 1948
1735 rgb.x /= (float)GetNumberOfSides(part); 1949 float invnsides = 1.0f / (float)nsides;
1736 rgb.y /= (float)GetNumberOfSides(part); 1950
1737 rgb.z /= (float)GetNumberOfSides(part); 1951 rgb.x *= invnsides;
1952 rgb.y *= invnsides;
1953 rgb.z *= invnsides;
1738 1954
1739 return rgb; 1955 return rgb;
1740 } 1956 }
1741 1957 if (face >= 0 && face < nsides)
1742 if (face >= 0 && face < GetNumberOfSides(part))
1743 { 1958 {
1744 texcolor = tex.GetFace((uint)face).RGBA; 1959 texcolor = tex.GetFace((uint)face).RGBA;
1745 rgb.x = texcolor.R; 1960 rgb.x = texcolor.R;
@@ -1766,15 +1981,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1766 m_host.AddScriptLPS(1); 1981 m_host.AddScriptLPS(1);
1767 1982
1768 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1983 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1769 1984 if (parts.Count > 0)
1770 foreach (SceneObjectPart part in parts) 1985 {
1771 SetTexture(part, texture, face); 1986 try
1772 1987 {
1988 foreach (SceneObjectPart part in parts)
1989 SetTexture(part, texture, face);
1990 }
1991 finally
1992 {
1993 }
1994 }
1773 ScriptSleep(200); 1995 ScriptSleep(200);
1774 } 1996 }
1775 1997
1776 protected void SetTexture(SceneObjectPart part, string texture, int face) 1998 protected void SetTexture(SceneObjectPart part, string texture, int face)
1777 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1778 UUID textureID = new UUID(); 2003 UUID textureID = new UUID();
1779 2004
1780 textureID = InventoryKey(texture, (int)AssetType.Texture); 2005 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1819,6 +2044,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2044
1820 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2045 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2046 {
2047 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2048 return;
2049
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2050 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2051 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2052 {
@@ -1855,6 +2083,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2083
1856 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2084 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1857 { 2085 {
2086 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2087 return;
2088
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2089 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2090 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2091 {
@@ -1891,6 +2122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1891 2122
1892 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2123 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1893 { 2124 {
2125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2126 return;
2127
1894 Primitive.TextureEntry tex = part.Shape.Textures; 2128 Primitive.TextureEntry tex = part.Shape.Textures;
1895 if (face >= 0 && face < GetNumberOfSides(part)) 2129 if (face >= 0 && face < GetNumberOfSides(part))
1896 { 2130 {
@@ -2061,24 +2295,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2061 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2295 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2062 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2296 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2063 { 2297 {
2064 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2298 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2299 return;
2300
2065 LSL_Vector currentPos = GetPartLocalPos(part); 2301 LSL_Vector currentPos = GetPartLocalPos(part);
2302 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2066 2303
2067 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2068 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2069 2304
2070 if (part.ParentGroup.RootPart == part) 2305 if (part.ParentGroup.RootPart == part)
2071 { 2306 {
2072 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2073 targetPos.z = ground;
2074 SceneObjectGroup parent = part.ParentGroup; 2307 SceneObjectGroup parent = part.ParentGroup;
2075 parent.UpdateGroupPosition(!adjust ? targetPos : 2308 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2076 SetPosAdjust(currentPos, targetPos)); 2309 return;
2310 Util.FireAndForget(delegate(object x) {
2311 parent.UpdateGroupPosition((Vector3)toPos);
2312 });
2077 } 2313 }
2078 else 2314 else
2079 { 2315 {
2080 part.OffsetPosition = !adjust ? targetPos : 2316 part.OffsetPosition = (Vector3)toPos;
2081 SetPosAdjust(currentPos, targetPos);
2082 SceneObjectGroup parent = part.ParentGroup; 2317 SceneObjectGroup parent = part.ParentGroup;
2083 parent.HasGroupChanged = true; 2318 parent.HasGroupChanged = true;
2084 parent.ScheduleGroupForTerseUpdate(); 2319 parent.ScheduleGroupForTerseUpdate();
@@ -2110,13 +2345,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2110 else 2345 else
2111 { 2346 {
2112 if (part.ParentGroup.IsAttachment) 2347 if (part.ParentGroup.IsAttachment)
2113 {
2114 pos = part.AttachedPos; 2348 pos = part.AttachedPos;
2115 }
2116 else 2349 else
2117 {
2118 pos = part.AbsolutePosition; 2350 pos = part.AbsolutePosition;
2119 }
2120 } 2351 }
2121 2352
2122// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2353// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2156,25 +2387,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2156 2387
2157 protected void SetRot(SceneObjectPart part, Quaternion rot) 2388 protected void SetRot(SceneObjectPart part, Quaternion rot)
2158 { 2389 {
2159 part.UpdateRotation(rot); 2390 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2160 // Update rotation does not move the object in the physics scene if it's a linkset. 2391 return;
2161 2392
2162//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2393 bool isroot = (part == part.ParentGroup.RootPart);
2163// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2394 bool isphys;
2164 2395
2165 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2166 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2167 // It's perfectly okay when the object is not an active physical body though.
2168 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2169 // but only if the object is not physial and active. This is important for rotating doors.
2170 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2171 // scene
2172 PhysicsActor pa = part.PhysActor; 2396 PhysicsActor pa = part.PhysActor;
2173 2397
2174 if (pa != null && !pa.IsPhysical) 2398 // keep using physactor ideia of isphysical
2399 // it should be SOP ideia of that
2400 // not much of a issue with ubitODE
2401 if (pa != null && pa.IsPhysical)
2402 isphys = true;
2403 else
2404 isphys = false;
2405
2406 // SL doesn't let scripts rotate root of physical linksets
2407 if (isroot && isphys)
2408 return;
2409
2410 part.UpdateRotation(rot);
2411
2412 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2413 // so do a nasty update of parts positions if is a root part rotation
2414 if (isroot && pa != null) // with if above implies non physical root part
2175 { 2415 {
2176 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2416 part.ParentGroup.ResetChildPrimPhysicsPositions();
2177 } 2417 }
2418 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2419 {
2420 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2421 if (sittingavas.Count > 0)
2422 {
2423 foreach (ScenePresence av in sittingavas)
2424 {
2425 if (isroot || part.LocalId == av.ParentID)
2426 av.SendTerseUpdateToAllClients();
2427 }
2428 }
2429 }
2178 } 2430 }
2179 2431
2180 /// <summary> 2432 /// <summary>
@@ -2222,8 +2474,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2222 2474
2223 public LSL_Rotation llGetLocalRot() 2475 public LSL_Rotation llGetLocalRot()
2224 { 2476 {
2477 return GetPartLocalRot(m_host);
2478 }
2479
2480 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2481 {
2225 m_host.AddScriptLPS(1); 2482 m_host.AddScriptLPS(1);
2226 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2483 Quaternion rot = part.RotationOffset;
2484 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2227 } 2485 }
2228 2486
2229 public void llSetForce(LSL_Vector force, int local) 2487 public void llSetForce(LSL_Vector force, int local)
@@ -2303,16 +2561,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2303 m_host.ApplyImpulse(v, local != 0); 2561 m_host.ApplyImpulse(v, local != 0);
2304 } 2562 }
2305 2563
2564
2306 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2565 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.ApplyAngularImpulse(force, local != 0); 2568 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2310 } 2569 }
2311 2570
2312 public void llSetTorque(LSL_Vector torque, int local) 2571 public void llSetTorque(LSL_Vector torque, int local)
2313 { 2572 {
2314 m_host.AddScriptLPS(1); 2573 m_host.AddScriptLPS(1);
2315 m_host.SetAngularImpulse(torque, local != 0); 2574 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2316 } 2575 }
2317 2576
2318 public LSL_Vector llGetTorque() 2577 public LSL_Vector llGetTorque()
@@ -2329,20 +2588,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2329 llSetTorque(torque, local); 2588 llSetTorque(torque, local);
2330 } 2589 }
2331 2590
2591 public void llSetVelocity(LSL_Vector vel, int local)
2592 {
2593 m_host.AddScriptLPS(1);
2594 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2595 }
2596
2332 public LSL_Vector llGetVel() 2597 public LSL_Vector llGetVel()
2333 { 2598 {
2334 m_host.AddScriptLPS(1); 2599 m_host.AddScriptLPS(1);
2335 2600
2336 Vector3 vel; 2601 Vector3 vel = Vector3.Zero;
2337 2602
2338 if (m_host.ParentGroup.IsAttachment) 2603 if (m_host.ParentGroup.IsAttachment)
2339 { 2604 {
2340 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2605 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2341 vel = avatar.Velocity; 2606 if (avatar != null)
2607 vel = avatar.Velocity;
2342 } 2608 }
2343 else 2609 else
2344 { 2610 {
2345 vel = m_host.Velocity; 2611 vel = m_host.ParentGroup.RootPart.Velocity;
2346 } 2612 }
2347 2613
2348 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2614 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2354,10 +2620,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2354 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2620 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2355 } 2621 }
2356 2622
2623 public void llSetAngularVelocity(LSL_Vector avel, int local)
2624 {
2625 m_host.AddScriptLPS(1);
2626 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2627 }
2628
2357 public LSL_Vector llGetOmega() 2629 public LSL_Vector llGetOmega()
2358 { 2630 {
2359 m_host.AddScriptLPS(1); 2631 m_host.AddScriptLPS(1);
2360 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2632 Vector3 avel = m_host.AngularVelocity;
2633 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2361 } 2634 }
2362 2635
2363 public LSL_Float llGetTimeOfDay() 2636 public LSL_Float llGetTimeOfDay()
@@ -2746,7 +3019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2746 } 3019 }
2747 3020
2748 bool result = money.ObjectGiveMoney( 3021 bool result = money.ObjectGiveMoney(
2749 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3022 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2750 3023
2751 if (result) 3024 if (result)
2752 return 1; 3025 return 1;
@@ -2830,13 +3103,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2830 new_group.RootPart.UUID.ToString()) }, 3103 new_group.RootPart.UUID.ToString()) },
2831 new DetectParams[0])); 3104 new DetectParams[0]));
2832 3105
2833 float groupmass = new_group.GetMass(); 3106 // do recoil
3107 SceneObjectGroup hostgrp = m_host.ParentGroup;
3108 if (hostgrp == null)
3109 return;
3110
3111 if (hostgrp.IsAttachment) // don't recoil avatars
3112 return;
2834 3113
2835 PhysicsActor pa = new_group.RootPart.PhysActor; 3114 PhysicsActor pa = new_group.RootPart.PhysActor;
2836 3115
2837 //Recoil. 3116 //Recoil.
2838 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3117 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2839 { 3118 {
3119 float groupmass = new_group.GetMass();
2840 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3120 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2841 if (recoil != Vector3.Zero) 3121 if (recoil != Vector3.Zero)
2842 { 3122 {
@@ -2844,6 +3124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 } 3124 }
2845 } 3125 }
2846 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3126 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3127 return;
3128
2847 }); 3129 });
2848 3130
2849 //ScriptSleep((int)((groupmass * velmag) / 10)); 3131 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2858,35 +3140,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 public void llLookAt(LSL_Vector target, double strength, double damping) 3140 public void llLookAt(LSL_Vector target, double strength, double damping)
2859 { 3141 {
2860 m_host.AddScriptLPS(1); 3142 m_host.AddScriptLPS(1);
2861 // Determine where we are looking from
2862 LSL_Vector from = llGetPos();
2863 3143
2864 // Work out the normalised vector from the source to the target 3144 // Get the normalized vector to the target
2865 LSL_Vector delta = llVecNorm(target - from); 3145 LSL_Vector d1 = llVecNorm(target - llGetPos());
2866 LSL_Vector angle = new LSL_Vector(0,0,0);
2867 3146
2868 // Calculate the yaw 3147 // Get the bearing (yaw)
2869 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3148 LSL_Vector a1 = new LSL_Vector(0,0,0);
2870 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3149 a1.z = llAtan2(d1.y, d1.x);
2871 3150
2872 // Calculate pitch 3151 // Get the elevation (pitch)
2873 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3152 LSL_Vector a2 = new LSL_Vector(0,0,0);
3153 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2874 3154
2875 // we need to convert from a vector describing 3155 LSL_Rotation r1 = llEuler2Rot(a1);
2876 // the angles of rotation in radians into rotation value 3156 LSL_Rotation r2 = llEuler2Rot(a2);
2877 LSL_Rotation rot = llEuler2Rot(angle); 3157 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2878
2879 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2880 // set the rotation of the object, copy that behavior
2881 PhysicsActor pa = m_host.PhysActor;
2882 3158
2883 if (strength == 0 || pa == null || !pa.IsPhysical) 3159 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2884 { 3160 {
2885 llSetRot(rot); 3161 // Do nothing if either value is 0 (this has been checked in SL)
3162 if (strength <= 0.0 || damping <= 0.0)
3163 return;
3164
3165 llSetRot(r3 * r2 * r1);
2886 } 3166 }
2887 else 3167 else
2888 { 3168 {
2889 m_host.StartLookAt(rot, (float)strength, (float)damping); 3169 if (strength == 0)
3170 {
3171 llSetRot(r3 * r2 * r1);
3172 return;
3173 }
3174
3175 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2890 } 3176 }
2891 } 3177 }
2892 3178
@@ -2932,17 +3218,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 } 3218 }
2933 else 3219 else
2934 { 3220 {
2935 if (m_host.IsRoot) 3221 // new SL always returns object mass
2936 { 3222// if (m_host.IsRoot)
3223// {
2937 return m_host.ParentGroup.GetMass(); 3224 return m_host.ParentGroup.GetMass();
2938 } 3225// }
2939 else 3226// else
2940 { 3227// {
2941 return m_host.GetMass(); 3228// return m_host.GetMass();
2942 } 3229// }
2943 } 3230 }
2944 } 3231 }
2945 3232
3233
3234 public LSL_Float llGetMassMKS()
3235 {
3236 return 100f * llGetMass();
3237 }
3238
2946 public void llCollisionFilter(string name, string id, int accept) 3239 public void llCollisionFilter(string name, string id, int accept)
2947 { 3240 {
2948 m_host.AddScriptLPS(1); 3241 m_host.AddScriptLPS(1);
@@ -2990,8 +3283,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2990 { 3283 {
2991 // Unregister controls from Presence 3284 // Unregister controls from Presence
2992 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3285 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2993 // Remove Take Control permission.
2994 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2995 } 3286 }
2996 } 3287 }
2997 } 3288 }
@@ -3017,7 +3308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3017 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3308 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3018 3309
3019 if (attachmentsModule != null) 3310 if (attachmentsModule != null)
3020 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3311 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3021 else 3312 else
3022 return false; 3313 return false;
3023 } 3314 }
@@ -3047,9 +3338,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 { 3338 {
3048 m_host.AddScriptLPS(1); 3339 m_host.AddScriptLPS(1);
3049 3340
3050// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3051// return;
3052
3053 if (m_item.PermsGranter != m_host.OwnerID) 3341 if (m_item.PermsGranter != m_host.OwnerID)
3054 return; 3342 return;
3055 3343
@@ -3092,6 +3380,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3092 3380
3093 public void llInstantMessage(string user, string message) 3381 public void llInstantMessage(string user, string message)
3094 { 3382 {
3383 UUID result;
3384 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3385 {
3386 ShoutError("An invalid key was passed to llInstantMessage");
3387 ScriptSleep(2000);
3388 return;
3389 }
3390
3391
3095 m_host.AddScriptLPS(1); 3392 m_host.AddScriptLPS(1);
3096 3393
3097 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3394 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3106,14 +3403,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3106 UUID friendTransactionID = UUID.Random(); 3403 UUID friendTransactionID = UUID.Random();
3107 3404
3108 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3405 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3109 3406
3110 GridInstantMessage msg = new GridInstantMessage(); 3407 GridInstantMessage msg = new GridInstantMessage();
3111 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3408 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3112 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3409 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3113 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3410 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3114// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3411// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3115// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3412// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3116 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3413// DateTime dt = DateTime.UtcNow;
3414//
3415// // Ticks from UtcNow, but make it look like local. Evil, huh?
3416// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3417//
3418// try
3419// {
3420// // Convert that to the PST timezone
3421// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3422// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3423// }
3424// catch
3425// {
3426// // No logging here, as it could be VERY spammy
3427// }
3428//
3429// // And make it look local again to fool the unix time util
3430// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3431
3432 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3433
3117 //if (client != null) 3434 //if (client != null)
3118 //{ 3435 //{
3119 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3436 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3127,12 +3444,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3127 msg.message = message.Substring(0, 1024); 3444 msg.message = message.Substring(0, 1024);
3128 else 3445 else
3129 msg.message = message; 3446 msg.message = message;
3130 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3447 msg.dialog = (byte)19; // MessageFromObject
3131 msg.fromGroup = false;// fromGroup; 3448 msg.fromGroup = false;// fromGroup;
3132 msg.offline = (byte)0; //offline; 3449 msg.offline = (byte)0; //offline;
3133 msg.ParentEstateID = 0; //ParentEstateID; 3450 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3134 msg.Position = new Vector3(m_host.AbsolutePosition); 3451 msg.Position = new Vector3(m_host.AbsolutePosition);
3135 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3452 msg.RegionID = World.RegionInfo.RegionID.Guid;
3136 msg.binaryBucket 3453 msg.binaryBucket
3137 = Util.StringToBytes256( 3454 = Util.StringToBytes256(
3138 "{0}/{1}/{2}/{3}", 3455 "{0}/{1}/{2}/{3}",
@@ -3160,7 +3477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3160 } 3477 }
3161 3478
3162 emailModule.SendEmail(m_host.UUID, address, subject, message); 3479 emailModule.SendEmail(m_host.UUID, address, subject, message);
3163 llSleep(EMAIL_PAUSE_TIME); 3480 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3164 } 3481 }
3165 3482
3166 public void llGetNextEmail(string address, string subject) 3483 public void llGetNextEmail(string address, string subject)
@@ -3406,7 +3723,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3723 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3407 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3724 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3408 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3725 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3726 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3409 ScriptBaseClass.PERMISSION_ATTACH; 3727 ScriptBaseClass.PERMISSION_ATTACH;
3728
3410 } 3729 }
3411 else 3730 else
3412 { 3731 {
@@ -3437,15 +3756,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3437 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3756 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3438 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3757 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3439 } 3758 }
3759 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3760 {
3761 implicitPerms = perm;
3762 }
3440 } 3763 }
3441 3764
3442 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3765 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3443 { 3766 {
3444 lock (m_host.TaskInventory) 3767 m_host.TaskInventory.LockItemsForWrite(true);
3445 { 3768 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3446 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3769 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3447 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3770 m_host.TaskInventory.LockItemsForWrite(false);
3448 }
3449 3771
3450 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3772 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3451 "run_time_permissions", new Object[] { 3773 "run_time_permissions", new Object[] {
@@ -3488,11 +3810,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3488 3810
3489 if (!m_waitingForScriptAnswer) 3811 if (!m_waitingForScriptAnswer)
3490 { 3812 {
3491 lock (m_host.TaskInventory) 3813 m_host.TaskInventory.LockItemsForWrite(true);
3492 { 3814 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3493 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3815 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3494 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3816 m_host.TaskInventory.LockItemsForWrite(false);
3495 }
3496 3817
3497 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3818 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3498 m_waitingForScriptAnswer=true; 3819 m_waitingForScriptAnswer=true;
@@ -3521,14 +3842,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3521 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3842 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3522 llReleaseControls(); 3843 llReleaseControls();
3523 3844
3524 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForWrite(true);
3525 { 3846 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3526 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3847 m_host.TaskInventory.LockItemsForWrite(false);
3527 } 3848
3528 3849 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3529 m_ScriptEngine.PostScriptEvent( 3850 "run_time_permissions", new Object[] {
3530 m_item.ItemID, 3851 new LSL_Integer(answer) },
3531 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3852 new DetectParams[0]));
3532 } 3853 }
3533 3854
3534 public LSL_String llGetPermissionsKey() 3855 public LSL_String llGetPermissionsKey()
@@ -3567,14 +3888,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3888 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3568 { 3889 {
3569 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3890 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3570 3891 if (parts.Count > 0)
3571 foreach (SceneObjectPart part in parts) 3892 {
3572 part.SetFaceColorAlpha(face, color, null); 3893 try
3894 {
3895 foreach (SceneObjectPart part in parts)
3896 part.SetFaceColorAlpha(face, color, null);
3897 }
3898 finally
3899 {
3900 }
3901 }
3573 } 3902 }
3574 3903
3575 public void llCreateLink(string target, int parent) 3904 public void llCreateLink(string target, int parent)
3576 { 3905 {
3577 m_host.AddScriptLPS(1); 3906 m_host.AddScriptLPS(1);
3907
3578 UUID targetID; 3908 UUID targetID;
3579 3909
3580 if (!UUID.TryParse(target, out targetID)) 3910 if (!UUID.TryParse(target, out targetID))
@@ -3680,10 +4010,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3680 // Restructuring Multiple Prims. 4010 // Restructuring Multiple Prims.
3681 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4011 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3682 parts.Remove(parentPrim.RootPart); 4012 parts.Remove(parentPrim.RootPart);
3683 foreach (SceneObjectPart part in parts) 4013 if (parts.Count > 0)
3684 { 4014 {
3685 parentPrim.DelinkFromGroup(part.LocalId, true); 4015 try
4016 {
4017 foreach (SceneObjectPart part in parts)
4018 {
4019 parentPrim.DelinkFromGroup(part.LocalId, true);
4020 }
4021 }
4022 finally
4023 {
4024 }
3686 } 4025 }
4026
3687 parentPrim.HasGroupChanged = true; 4027 parentPrim.HasGroupChanged = true;
3688 parentPrim.ScheduleGroupForFullUpdate(); 4028 parentPrim.ScheduleGroupForFullUpdate();
3689 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4029 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3692,12 +4032,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 { 4032 {
3693 SceneObjectPart newRoot = parts[0]; 4033 SceneObjectPart newRoot = parts[0];
3694 parts.Remove(newRoot); 4034 parts.Remove(newRoot);
3695 foreach (SceneObjectPart part in parts) 4035
4036 try
3696 { 4037 {
3697 // Required for linking 4038 foreach (SceneObjectPart part in parts)
3698 part.ClearUpdateSchedule(); 4039 {
3699 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4040 part.ClearUpdateSchedule();
4041 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4042 }
3700 } 4043 }
4044 finally
4045 {
4046 }
4047
4048
3701 newRoot.ParentGroup.HasGroupChanged = true; 4049 newRoot.ParentGroup.HasGroupChanged = true;
3702 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4050 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3703 } 4051 }
@@ -3717,6 +4065,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3717 public void llBreakAllLinks() 4065 public void llBreakAllLinks()
3718 { 4066 {
3719 m_host.AddScriptLPS(1); 4067 m_host.AddScriptLPS(1);
4068
4069 TaskInventoryItem item = m_item;
4070
4071 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4072 && !m_automaticLinkPermission)
4073 {
4074 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4075 return;
4076 }
4077
3720 SceneObjectGroup parentPrim = m_host.ParentGroup; 4078 SceneObjectGroup parentPrim = m_host.ParentGroup;
3721 if (parentPrim.AttachmentPoint != 0) 4079 if (parentPrim.AttachmentPoint != 0)
3722 return; // Fail silently if attached 4080 return; // Fail silently if attached
@@ -3736,25 +4094,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3736 public LSL_String llGetLinkKey(int linknum) 4094 public LSL_String llGetLinkKey(int linknum)
3737 { 4095 {
3738 m_host.AddScriptLPS(1); 4096 m_host.AddScriptLPS(1);
3739 List<UUID> keytable = new List<UUID>();
3740 // parse for sitting avatare-uuids
3741 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3742 {
3743 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3744 keytable.Add(presence.UUID);
3745 });
3746
3747 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3748 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3749 {
3750 return keytable[totalprims - linknum].ToString();
3751 }
3752
3753 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3754 {
3755 return m_host.UUID.ToString();
3756 }
3757
3758 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4097 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3759 if (part != null) 4098 if (part != null)
3760 { 4099 {
@@ -3762,6 +4101,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3762 } 4101 }
3763 else 4102 else
3764 { 4103 {
4104 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4105 {
4106 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4107
4108 if (linknum < 0)
4109 return UUID.Zero.ToString();
4110
4111 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4112 if (avatars.Count > linknum)
4113 {
4114 return avatars[linknum].UUID.ToString();
4115 }
4116 }
3765 return UUID.Zero.ToString(); 4117 return UUID.Zero.ToString();
3766 } 4118 }
3767 } 4119 }
@@ -3871,17 +4223,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 m_host.AddScriptLPS(1); 4223 m_host.AddScriptLPS(1);
3872 int count = 0; 4224 int count = 0;
3873 4225
3874 lock (m_host.TaskInventory) 4226 m_host.TaskInventory.LockItemsForRead(true);
4227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3875 { 4228 {
3876 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4229 if (inv.Value.Type == type || type == -1)
3877 { 4230 {
3878 if (inv.Value.Type == type || type == -1) 4231 count = count + 1;
3879 {
3880 count = count + 1;
3881 }
3882 } 4232 }
3883 } 4233 }
3884 4234
4235 m_host.TaskInventory.LockItemsForRead(false);
3885 return count; 4236 return count;
3886 } 4237 }
3887 4238
@@ -3890,16 +4241,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 m_host.AddScriptLPS(1); 4241 m_host.AddScriptLPS(1);
3891 ArrayList keys = new ArrayList(); 4242 ArrayList keys = new ArrayList();
3892 4243
3893 lock (m_host.TaskInventory) 4244 m_host.TaskInventory.LockItemsForRead(true);
4245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3894 { 4246 {
3895 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4247 if (inv.Value.Type == type || type == -1)
3896 { 4248 {
3897 if (inv.Value.Type == type || type == -1) 4249 keys.Add(inv.Value.Name);
3898 {
3899 keys.Add(inv.Value.Name);
3900 }
3901 } 4250 }
3902 } 4251 }
4252 m_host.TaskInventory.LockItemsForRead(false);
3903 4253
3904 if (keys.Count == 0) 4254 if (keys.Count == 0)
3905 { 4255 {
@@ -3937,7 +4287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3937 if (item == null) 4287 if (item == null)
3938 { 4288 {
3939 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4289 llSay(0, String.Format("Could not find object '{0}'", inventory));
3940 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4290 return;
4291// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3941 } 4292 }
3942 4293
3943 UUID objId = item.ItemID; 4294 UUID objId = item.ItemID;
@@ -3965,33 +4316,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3965 return; 4316 return;
3966 } 4317 }
3967 } 4318 }
4319
3968 // destination is an avatar 4320 // destination is an avatar
3969 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4321 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3970 4322
3971 if (agentItem == null) 4323 if (agentItem == null)
3972 return; 4324 return;
3973 4325
3974 if (m_TransferModule != null) 4326 byte[] bucket = new byte[1];
3975 { 4327 bucket[0] = (byte)item.Type;
3976 byte[] bucket = new byte[1]; 4328 //byte[] objBytes = agentItem.ID.GetBytes();
3977 bucket[0] = (byte)item.Type; 4329 //Array.Copy(objBytes, 0, bucket, 1, 16);
3978 4330
3979 GridInstantMessage msg = new GridInstantMessage(World, 4331 GridInstantMessage msg = new GridInstantMessage(World,
3980 m_host.OwnerID, m_host.Name, destId, 4332 m_host.OwnerID, m_host.Name, destId,
3981 (byte)InstantMessageDialog.TaskInventoryOffered, 4333 (byte)InstantMessageDialog.TaskInventoryOffered,
3982 false, item.Name+". "+m_host.Name+" is located at "+ 4334 false, item.Name+". "+m_host.Name+" is located at "+
3983 World.RegionInfo.RegionName+" "+ 4335 World.RegionInfo.RegionName+" "+
3984 m_host.AbsolutePosition.ToString(), 4336 m_host.AbsolutePosition.ToString(),
3985 agentItem.ID, true, m_host.AbsolutePosition, 4337 agentItem.ID, true, m_host.AbsolutePosition,
3986 bucket, true); 4338 bucket, true);
3987 4339
3988 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4340 ScenePresence sp;
3989 }
3990 4341
4342 if (World.TryGetScenePresence(destId, out sp))
4343 {
4344 sp.ControllingClient.SendInstantMessage(msg);
4345 }
4346 else
4347 {
4348 if (m_TransferModule != null)
4349 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4350 }
4351
4352 //This delay should only occur when giving inventory to avatars.
3991 ScriptSleep(3000); 4353 ScriptSleep(3000);
3992 } 4354 }
3993 } 4355 }
3994 4356
4357 [DebuggerNonUserCode]
3995 public void llRemoveInventory(string name) 4358 public void llRemoveInventory(string name)
3996 { 4359 {
3997 m_host.AddScriptLPS(1); 4360 m_host.AddScriptLPS(1);
@@ -4046,109 +4409,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 { 4409 {
4047 m_host.AddScriptLPS(1); 4410 m_host.AddScriptLPS(1);
4048 4411
4049 UUID uuid = (UUID)id; 4412 UUID uuid;
4050 PresenceInfo pinfo = null; 4413 if (UUID.TryParse(id, out uuid))
4051 UserAccount account;
4052
4053 UserInfoCacheEntry ce;
4054 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4055 { 4414 {
4056 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4415 PresenceInfo pinfo = null;
4057 if (account == null) 4416 UserAccount account;
4417
4418 UserInfoCacheEntry ce;
4419 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4058 { 4420 {
4059 m_userInfoCache[uuid] = null; // Cache negative 4421 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4060 return UUID.Zero.ToString(); 4422 if (account == null)
4061 } 4423 {
4424 m_userInfoCache[uuid] = null; // Cache negative
4425 return UUID.Zero.ToString();
4426 }
4062 4427
4063 4428
4064 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4429 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4065 if (pinfos != null && pinfos.Length > 0) 4430 if (pinfos != null && pinfos.Length > 0)
4066 {
4067 foreach (PresenceInfo p in pinfos)
4068 { 4431 {
4069 if (p.RegionID != UUID.Zero) 4432 foreach (PresenceInfo p in pinfos)
4070 { 4433 {
4071 pinfo = p; 4434 if (p.RegionID != UUID.Zero)
4435 {
4436 pinfo = p;
4437 }
4072 } 4438 }
4073 } 4439 }
4074 }
4075 4440
4076 ce = new UserInfoCacheEntry(); 4441 ce = new UserInfoCacheEntry();
4077 ce.time = Util.EnvironmentTickCount(); 4442 ce.time = Util.EnvironmentTickCount();
4078 ce.account = account; 4443 ce.account = account;
4079 ce.pinfo = pinfo; 4444 ce.pinfo = pinfo;
4080 } 4445 m_userInfoCache[uuid] = ce;
4081 else 4446 }
4082 { 4447 else
4083 if (ce == null) 4448 {
4084 return UUID.Zero.ToString(); 4449 if (ce == null)
4450 return UUID.Zero.ToString();
4085 4451
4086 account = ce.account; 4452 account = ce.account;
4087 pinfo = ce.pinfo; 4453 pinfo = ce.pinfo;
4088 } 4454 }
4089 4455
4090 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4456 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4091 {
4092 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4093 if (pinfos != null && pinfos.Length > 0)
4094 { 4457 {
4095 foreach (PresenceInfo p in pinfos) 4458 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4459 if (pinfos != null && pinfos.Length > 0)
4096 { 4460 {
4097 if (p.RegionID != UUID.Zero) 4461 foreach (PresenceInfo p in pinfos)
4098 { 4462 {
4099 pinfo = p; 4463 if (p.RegionID != UUID.Zero)
4464 {
4465 pinfo = p;
4466 }
4100 } 4467 }
4101 } 4468 }
4102 } 4469 else
4103 else 4470 pinfo = null;
4104 pinfo = null;
4105 4471
4106 ce.time = Util.EnvironmentTickCount(); 4472 ce.time = Util.EnvironmentTickCount();
4107 ce.pinfo = pinfo; 4473 ce.pinfo = pinfo;
4108 } 4474 }
4109 4475
4110 string reply = String.Empty; 4476 string reply = String.Empty;
4111 4477
4112 switch (data) 4478 switch (data)
4113 { 4479 {
4114 case 1: // DATA_ONLINE (0|1) 4480 case 1: // DATA_ONLINE (0|1)
4115 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4481 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4116 reply = "1"; 4482 reply = "1";
4117 else 4483 else
4118 reply = "0"; 4484 reply = "0";
4119 break; 4485 break;
4120 case 2: // DATA_NAME (First Last) 4486 case 2: // DATA_NAME (First Last)
4121 reply = account.FirstName + " " + account.LastName; 4487 reply = account.FirstName + " " + account.LastName;
4122 break; 4488 break;
4123 case 3: // DATA_BORN (YYYY-MM-DD) 4489 case 3: // DATA_BORN (YYYY-MM-DD)
4124 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4490 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4125 born = born.AddSeconds(account.Created); 4491 born = born.AddSeconds(account.Created);
4126 reply = born.ToString("yyyy-MM-dd"); 4492 reply = born.ToString("yyyy-MM-dd");
4127 break; 4493 break;
4128 case 4: // DATA_RATING (0,0,0,0,0,0) 4494 case 4: // DATA_RATING (0,0,0,0,0,0)
4129 reply = "0,0,0,0,0,0"; 4495 reply = "0,0,0,0,0,0";
4130 break; 4496 break;
4131 case 7: // DATA_USERLEVEL (integer) 4497 case 8: // DATA_PAYINFO (0|1|2|3)
4132 reply = account.UserLevel.ToString(); 4498 reply = "0";
4133 break; 4499 break;
4134 case 8: // DATA_PAYINFO (0|1|2|3) 4500 default:
4135 reply = "0"; 4501 return UUID.Zero.ToString(); // Raise no event
4136 break; 4502 }
4137 default:
4138 return UUID.Zero.ToString(); // Raise no event
4139 }
4140 4503
4141 UUID rq = UUID.Random(); 4504 UUID rq = UUID.Random();
4142 4505
4143 UUID tid = AsyncCommands. 4506 UUID tid = AsyncCommands.
4144 DataserverPlugin.RegisterRequest(m_host.LocalId, 4507 DataserverPlugin.RegisterRequest(m_host.LocalId,
4145 m_item.ItemID, rq.ToString()); 4508 m_item.ItemID, rq.ToString());
4146 4509
4147 AsyncCommands. 4510 AsyncCommands.
4148 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4511 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4149 4512
4150 ScriptSleep(100); 4513 ScriptSleep(100);
4151 return tid.ToString(); 4514 return tid.ToString();
4515 }
4516 else
4517 {
4518 ShoutError("Invalid UUID passed to llRequestAgentData.");
4519 }
4520 return "";
4152 } 4521 }
4153 4522
4154 public LSL_String llRequestInventoryData(string name) 4523 public LSL_String llRequestInventoryData(string name)
@@ -4205,13 +4574,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4205 if (UUID.TryParse(agent, out agentId)) 4574 if (UUID.TryParse(agent, out agentId))
4206 { 4575 {
4207 ScenePresence presence = World.GetScenePresence(agentId); 4576 ScenePresence presence = World.GetScenePresence(agentId);
4208 if (presence != null) 4577 if (presence != null && presence.PresenceType != PresenceType.Npc)
4209 { 4578 {
4579 // agent must not be a god
4580 if (presence.UserLevel >= 200) return;
4581
4210 // agent must be over the owners land 4582 // agent must be over the owners land
4211 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4583 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4212 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4584 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4213 { 4585 {
4214 World.TeleportClientHome(agentId, presence.ControllingClient); 4586 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4587 {
4588 // They can't be teleported home for some reason
4589 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4590 if (regionInfo != null)
4591 {
4592 World.RequestTeleportLocation(
4593 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4594 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4595 }
4596 }
4215 } 4597 }
4216 } 4598 }
4217 } 4599 }
@@ -4318,7 +4700,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4318 UUID av = new UUID(); 4700 UUID av = new UUID();
4319 if (!UUID.TryParse(agent,out av)) 4701 if (!UUID.TryParse(agent,out av))
4320 { 4702 {
4321 LSLError("First parameter to llDialog needs to be a key"); 4703 //LSLError("First parameter to llDialog needs to be a key");
4322 return; 4704 return;
4323 } 4705 }
4324 4706
@@ -4350,10 +4732,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4350 public void llCollisionSound(string impact_sound, double impact_volume) 4732 public void llCollisionSound(string impact_sound, double impact_volume)
4351 { 4733 {
4352 m_host.AddScriptLPS(1); 4734 m_host.AddScriptLPS(1);
4353 4735
4736 if(impact_sound == "")
4737 {
4738 m_host.CollisionSoundVolume = (float)impact_volume;
4739 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4740 m_host.CollisionSoundType = 0;
4741 return;
4742 }
4354 // TODO: Parameter check logic required. 4743 // TODO: Parameter check logic required.
4355 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4744 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4356 m_host.CollisionSoundVolume = (float)impact_volume; 4745 m_host.CollisionSoundVolume = (float)impact_volume;
4746 m_host.CollisionSoundType = 1;
4357 } 4747 }
4358 4748
4359 public LSL_String llGetAnimation(string id) 4749 public LSL_String llGetAnimation(string id)
@@ -4367,14 +4757,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 4757
4368 if (m_host.RegionHandle == presence.RegionHandle) 4758 if (m_host.RegionHandle == presence.RegionHandle)
4369 { 4759 {
4370 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4371
4372 if (presence != null) 4760 if (presence != null)
4373 { 4761 {
4374 AnimationSet currentAnims = presence.Animator.Animations; 4762 if (presence.SitGround)
4375 string currentAnimationState = String.Empty; 4763 return "Sitting on Ground";
4376 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4764 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4377 return currentAnimationState; 4765 return "Sitting";
4766
4767 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4768 string lslMovementAnimation;
4769
4770 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4771 return lslMovementAnimation;
4378 } 4772 }
4379 } 4773 }
4380 4774
@@ -4521,7 +4915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4521 { 4915 {
4522 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4916 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4523 float distance_term = distance * distance * distance; // Script Energy 4917 float distance_term = distance * distance * distance; // Script Energy
4524 float pusher_mass = m_host.GetMass(); 4918 // use total object mass and not part
4919 float pusher_mass = m_host.ParentGroup.GetMass();
4525 4920
4526 float PUSH_ATTENUATION_DISTANCE = 17f; 4921 float PUSH_ATTENUATION_DISTANCE = 17f;
4527 float PUSH_ATTENUATION_SCALE = 5f; 4922 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4771,6 +5166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4771 { 5166 {
4772 return item.AssetID.ToString(); 5167 return item.AssetID.ToString();
4773 } 5168 }
5169 m_host.TaskInventory.LockItemsForRead(false);
4774 5170
4775 return UUID.Zero.ToString(); 5171 return UUID.Zero.ToString();
4776 } 5172 }
@@ -4904,7 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4904 public LSL_Vector llGetCenterOfMass() 5300 public LSL_Vector llGetCenterOfMass()
4905 { 5301 {
4906 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4907 Vector3 center = m_host.GetGeometricCenter(); 5303 Vector3 center = m_host.GetCenterOfMass();
4908 return new LSL_Vector(center.X,center.Y,center.Z); 5304 return new LSL_Vector(center.X,center.Y,center.Z);
4909 } 5305 }
4910 5306
@@ -4923,14 +5319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4923 { 5319 {
4924 m_host.AddScriptLPS(1); 5320 m_host.AddScriptLPS(1);
4925 5321
4926 if (src == null) 5322 return src.Length;
4927 {
4928 return 0;
4929 }
4930 else
4931 {
4932 return src.Length;
4933 }
4934 } 5323 }
4935 5324
4936 public LSL_Integer llList2Integer(LSL_List src, int index) 5325 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5001,7 +5390,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5001 else if (src.Data[index] is LSL_Float) 5390 else if (src.Data[index] is LSL_Float)
5002 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5391 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5003 else if (src.Data[index] is LSL_String) 5392 else if (src.Data[index] is LSL_String)
5004 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5393 {
5394 string str = ((LSL_String) src.Data[index]).m_string;
5395 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5396 if (m != Match.Empty)
5397 {
5398 str = m.Value;
5399 double d = 0.0;
5400 if (!Double.TryParse(str, out d))
5401 return 0.0;
5402
5403 return d;
5404 }
5405 return 0.0;
5406 }
5005 return Convert.ToDouble(src.Data[index]); 5407 return Convert.ToDouble(src.Data[index]);
5006 } 5408 }
5007 catch (FormatException) 5409 catch (FormatException)
@@ -5043,7 +5445,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5043 // for completion and should LSL_Key ever be implemented 5445 // for completion and should LSL_Key ever be implemented
5044 // as it's own struct 5446 // as it's own struct
5045 else if (!(src.Data[index] is LSL_String || 5447 else if (!(src.Data[index] is LSL_String ||
5046 src.Data[index] is LSL_Key)) 5448 src.Data[index] is LSL_Key ||
5449 src.Data[index] is String))
5047 { 5450 {
5048 return ""; 5451 return "";
5049 } 5452 }
@@ -5301,7 +5704,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5301 } 5704 }
5302 } 5705 }
5303 } 5706 }
5304 else { 5707 else
5708 {
5305 object[] array = new object[src.Length]; 5709 object[] array = new object[src.Length];
5306 Array.Copy(src.Data, 0, array, 0, src.Length); 5710 Array.Copy(src.Data, 0, array, 0, src.Length);
5307 result = new LSL_List(array); 5711 result = new LSL_List(array);
@@ -5408,7 +5812,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5408 public LSL_Integer llGetRegionAgentCount() 5812 public LSL_Integer llGetRegionAgentCount()
5409 { 5813 {
5410 m_host.AddScriptLPS(1); 5814 m_host.AddScriptLPS(1);
5411 return new LSL_Integer(World.GetRootAgentCount()); 5815
5816 int count = 0;
5817 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5818 count++;
5819 });
5820
5821 return new LSL_Integer(count);
5412 } 5822 }
5413 5823
5414 public LSL_Vector llGetRegionCorner() 5824 public LSL_Vector llGetRegionCorner()
@@ -5649,6 +6059,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5649 flags |= ScriptBaseClass.AGENT_AWAY; 6059 flags |= ScriptBaseClass.AGENT_AWAY;
5650 } 6060 }
5651 6061
6062 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6063 UUID[] anims = agent.Animator.GetAnimationArray();
6064 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6065 {
6066 flags |= ScriptBaseClass.AGENT_BUSY;
6067 }
6068
5652 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6069 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5653 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6070 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5654 { 6071 {
@@ -5696,6 +6113,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5696 flags |= ScriptBaseClass.AGENT_SITTING; 6113 flags |= ScriptBaseClass.AGENT_SITTING;
5697 } 6114 }
5698 6115
6116 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6117 {
6118 flags |= ScriptBaseClass.AGENT_MALE;
6119 }
6120
5699 return flags; 6121 return flags;
5700 } 6122 }
5701 6123
@@ -5843,9 +6265,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5843 6265
5844 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6266 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5845 6267
5846 foreach (SceneObjectPart part in parts) 6268 try
6269 {
6270 foreach (SceneObjectPart part in parts)
6271 {
6272 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6273 }
6274 }
6275 finally
5847 { 6276 {
5848 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5849 } 6277 }
5850 } 6278 }
5851 6279
@@ -5899,13 +6327,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5899 6327
5900 if (m_host.OwnerID == land.LandData.OwnerID) 6328 if (m_host.OwnerID == land.LandData.OwnerID)
5901 { 6329 {
5902 World.TeleportClientHome(agentID, presence.ControllingClient); 6330 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6331 presence.TeleportWithMomentum(pos, null);
6332 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5903 } 6333 }
5904 } 6334 }
5905 } 6335 }
5906 ScriptSleep(5000); 6336 ScriptSleep(5000);
5907 } 6337 }
5908 6338
6339 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6340 {
6341 return ParseString2List(str, separators, in_spacers, false);
6342 }
6343
5909 public LSL_Integer llOverMyLand(string id) 6344 public LSL_Integer llOverMyLand(string id)
5910 { 6345 {
5911 m_host.AddScriptLPS(1); 6346 m_host.AddScriptLPS(1);
@@ -5959,25 +6394,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5959 } 6394 }
5960 else 6395 else
5961 { 6396 {
5962 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6397// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6398 Vector3 s = avatar.Appearance.AvatarSize;
6399 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5963 } 6400 }
5964 return agentSize; 6401 return agentSize;
5965 } 6402 }
5966 6403
5967 public LSL_Integer llSameGroup(string agent) 6404 public LSL_Integer llSameGroup(string id)
5968 { 6405 {
5969 m_host.AddScriptLPS(1); 6406 m_host.AddScriptLPS(1);
5970 UUID agentId = new UUID(); 6407 UUID uuid = new UUID();
5971 if (!UUID.TryParse(agent, out agentId)) 6408 if (!UUID.TryParse(id, out uuid))
5972 return new LSL_Integer(0);
5973 ScenePresence presence = World.GetScenePresence(agentId);
5974 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5975 return new LSL_Integer(0); 6409 return new LSL_Integer(0);
5976 IClientAPI client = presence.ControllingClient; 6410
5977 if (m_host.GroupID == client.ActiveGroupId) 6411 // Check if it's a group key
6412 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5978 return new LSL_Integer(1); 6413 return new LSL_Integer(1);
5979 else 6414
6415 // We got passed a UUID.Zero
6416 if (uuid == UUID.Zero)
5980 return new LSL_Integer(0); 6417 return new LSL_Integer(0);
6418
6419 // Handle the case where id names an avatar
6420 ScenePresence presence = World.GetScenePresence(uuid);
6421 if (presence != null)
6422 {
6423 if (presence.IsChildAgent)
6424 return new LSL_Integer(0);
6425
6426 IClientAPI client = presence.ControllingClient;
6427 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6428 return new LSL_Integer(1);
6429
6430 return new LSL_Integer(0);
6431 }
6432
6433 // Handle object case
6434 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6435 if (part != null)
6436 {
6437 // This will handle both deed and non-deed and also the no
6438 // group case
6439 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6440 return new LSL_Integer(1);
6441
6442 return new LSL_Integer(0);
6443 }
6444
6445 return new LSL_Integer(0);
5981 } 6446 }
5982 6447
5983 public void llUnSit(string id) 6448 public void llUnSit(string id)
@@ -6102,7 +6567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6102 return m_host.ParentGroup.AttachmentPoint; 6567 return m_host.ParentGroup.AttachmentPoint;
6103 } 6568 }
6104 6569
6105 public LSL_Integer llGetFreeMemory() 6570 public virtual LSL_Integer llGetFreeMemory()
6106 { 6571 {
6107 m_host.AddScriptLPS(1); 6572 m_host.AddScriptLPS(1);
6108 // Make scripts designed for LSO happy 6573 // Make scripts designed for LSO happy
@@ -6219,7 +6684,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6219 SetParticleSystem(m_host, rules); 6684 SetParticleSystem(m_host, rules);
6220 } 6685 }
6221 6686
6222 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6687 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6688 {
6223 6689
6224 6690
6225 if (rules.Length == 0) 6691 if (rules.Length == 0)
@@ -6534,6 +7000,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6534 7000
6535 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7001 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6536 { 7002 {
7003 // LSL quaternions can normalize to 0, normal Quaternions can't.
7004 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7005 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7006
6537 part.SitTargetPosition = offset; 7007 part.SitTargetPosition = offset;
6538 part.SitTargetOrientation = rot; 7008 part.SitTargetOrientation = rot;
6539 part.ParentGroup.HasGroupChanged = true; 7009 part.ParentGroup.HasGroupChanged = true;
@@ -6719,13 +7189,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6719 UUID av = new UUID(); 7189 UUID av = new UUID();
6720 if (!UUID.TryParse(avatar,out av)) 7190 if (!UUID.TryParse(avatar,out av))
6721 { 7191 {
6722 LSLError("First parameter to llDialog needs to be a key"); 7192 //LSLError("First parameter to llDialog needs to be a key");
6723 return; 7193 return;
6724 } 7194 }
6725 if (buttons.Length < 1) 7195 if (buttons.Length < 1)
6726 { 7196 {
6727 LSLError("No less than 1 button can be shown"); 7197 buttons.Add("OK");
6728 return;
6729 } 7198 }
6730 if (buttons.Length > 12) 7199 if (buttons.Length > 12)
6731 { 7200 {
@@ -6742,7 +7211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6742 } 7211 }
6743 if (buttons.Data[i].ToString().Length > 24) 7212 if (buttons.Data[i].ToString().Length > 24)
6744 { 7213 {
6745 LSLError("button label cannot be longer than 24 characters"); 7214 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6746 return; 7215 return;
6747 } 7216 }
6748 buts[i] = buttons.Data[i].ToString(); 7217 buts[i] = buttons.Data[i].ToString();
@@ -6809,9 +7278,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6809 return; 7278 return;
6810 } 7279 }
6811 7280
6812 // the rest of the permission checks are done in RezScript, so check the pin there as well 7281 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6813 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7282 if (dest != null)
7283 {
7284 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7285 {
7286 // the rest of the permission checks are done in RezScript, so check the pin there as well
7287 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6814 7288
7289 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7290 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7291 }
7292 }
6815 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7293 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6816 ScriptSleep(3000); 7294 ScriptSleep(3000);
6817 } 7295 }
@@ -6881,19 +7359,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6881 public LSL_String llMD5String(string src, int nonce) 7359 public LSL_String llMD5String(string src, int nonce)
6882 { 7360 {
6883 m_host.AddScriptLPS(1); 7361 m_host.AddScriptLPS(1);
6884 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7362 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6885 } 7363 }
6886 7364
6887 public LSL_String llSHA1String(string src) 7365 public LSL_String llSHA1String(string src)
6888 { 7366 {
6889 m_host.AddScriptLPS(1); 7367 m_host.AddScriptLPS(1);
6890 return Util.SHA1Hash(src).ToLower(); 7368 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6891 } 7369 }
6892 7370
6893 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7371 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6894 { 7372 {
6895 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7373 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6896 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7374 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7375 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7376 return shapeBlock;
6897 7377
6898 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7378 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6899 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7379 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6998,6 +7478,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6998 // Prim type box, cylinder and prism. 7478 // Prim type box, cylinder and prism.
6999 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) 7479 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)
7000 { 7480 {
7481 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7482 return;
7483
7001 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7484 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7002 ObjectShapePacket.ObjectDataBlock shapeBlock; 7485 ObjectShapePacket.ObjectDataBlock shapeBlock;
7003 7486
@@ -7051,6 +7534,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7051 // Prim type sphere. 7534 // Prim type sphere.
7052 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7535 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7053 { 7536 {
7537 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7538 return;
7539
7054 ObjectShapePacket.ObjectDataBlock shapeBlock; 7540 ObjectShapePacket.ObjectDataBlock shapeBlock;
7055 7541
7056 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7542 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7092,6 +7578,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7092 // Prim type torus, tube and ring. 7578 // Prim type torus, tube and ring.
7093 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) 7579 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)
7094 { 7580 {
7581 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7582 return;
7583
7095 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7584 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7096 ObjectShapePacket.ObjectDataBlock shapeBlock; 7585 ObjectShapePacket.ObjectDataBlock shapeBlock;
7097 7586
@@ -7227,6 +7716,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7227 // Prim type sculpt. 7716 // Prim type sculpt.
7228 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7717 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7229 { 7718 {
7719 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7720 return;
7721
7230 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7722 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7231 UUID sculptId; 7723 UUID sculptId;
7232 7724
@@ -7251,7 +7743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7251 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7743 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7252 { 7744 {
7253 // default 7745 // default
7254 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7746 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7255 } 7747 }
7256 7748
7257 part.Shape.SetSculptProperties((byte)type, sculptId); 7749 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7268,48 +7760,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7268 ScriptSleep(200); 7760 ScriptSleep(200);
7269 } 7761 }
7270 7762
7271 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7763 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7272 { 7764 {
7273 m_host.AddScriptLPS(1); 7765 m_host.AddScriptLPS(1);
7274 7766
7275 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7767 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7276 7768
7277 ScriptSleep(200); 7769 ScriptSleep(200);
7278 } 7770 }
7279 7771
7280 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7772 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7281 { 7773 {
7282 m_host.AddScriptLPS(1); 7774 List<object> parts = new List<object>();
7775 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7776 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7777 foreach (SceneObjectPart p in prims)
7778 parts.Add(p);
7779 foreach (ScenePresence p in avatars)
7780 parts.Add(p);
7283 7781
7284 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7782 LSL_List remaining = null;
7783 uint rulesParsed = 0;
7784
7785 if (parts.Count > 0)
7786 {
7787 foreach (object part in parts)
7788 {
7789 if (part is SceneObjectPart)
7790 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7791 else
7792 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7793 }
7794
7795 while ((object)remaining != null && remaining.Length > 2)
7796 {
7797 linknumber = remaining.GetLSLIntegerItem(0);
7798 rules = remaining.GetSublist(1, -1);
7799 parts.Clear();
7800 prims = GetLinkParts(linknumber);
7801 avatars = GetLinkAvatars(linknumber);
7802 foreach (SceneObjectPart p in prims)
7803 parts.Add(p);
7804 foreach (ScenePresence p in avatars)
7805 parts.Add(p);
7806
7807 remaining = null;
7808 foreach (object part in parts)
7809 {
7810 if (part is SceneObjectPart)
7811 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7812 else
7813 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7814 }
7815 }
7816 }
7285 } 7817 }
7286 7818
7287 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7819 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7820 float material_density, float material_friction,
7821 float material_restitution, float material_gravity_modifier)
7288 { 7822 {
7289 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7823 ExtraPhysicsData physdata = new ExtraPhysicsData();
7824 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7825 physdata.Density = part.Density;
7826 physdata.Friction = part.Friction;
7827 physdata.Bounce = part.Bounciness;
7828 physdata.GravitationModifier = part.GravityModifier;
7290 7829
7291 LSL_List remaining = null; 7830 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7292 uint rulesParsed = 0; 7831 physdata.Density = material_density;
7832 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7833 physdata.Friction = material_friction;
7834 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7835 physdata.Bounce = material_restitution;
7836 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7837 physdata.GravitationModifier = material_gravity_modifier;
7293 7838
7294 foreach (SceneObjectPart part in parts) 7839 part.UpdateExtraPhysics(physdata);
7295 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7840 }
7296 7841
7297 while (remaining != null && remaining.Length > 2) 7842 public void llSetPhysicsMaterial(int material_bits,
7298 { 7843 float material_gravity_modifier, float material_restitution,
7299 linknumber = remaining.GetLSLIntegerItem(0); 7844 float material_friction, float material_density)
7300 rules = remaining.GetSublist(1, -1); 7845 {
7301 parts = GetLinkParts(linknumber); 7846 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7847 }
7302 7848
7303 foreach (SceneObjectPart part in parts) 7849 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7304 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7850 {
7851 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7852 llSetLinkPrimitiveParamsFast(linknumber, rules);
7853 ScriptSleep(200);
7854 }
7855
7856 // vector up using libomv (c&p from sop )
7857 // vector up rotated by r
7858 private Vector3 Zrot(Quaternion r)
7859 {
7860 double x, y, z, m;
7861
7862 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7863 if (Math.Abs(1.0 - m) > 0.000001)
7864 {
7865 m = 1.0 / Math.Sqrt(m);
7866 r.X *= (float)m;
7867 r.Y *= (float)m;
7868 r.Z *= (float)m;
7869 r.W *= (float)m;
7305 } 7870 }
7871
7872 x = 2 * (r.X * r.Z + r.Y * r.W);
7873 y = 2 * (-r.X * r.W + r.Y * r.Z);
7874 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7875
7876 return new Vector3((float)x, (float)y, (float)z);
7306 } 7877 }
7307 7878
7308 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7879 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7309 { 7880 {
7881 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7882 return null;
7883
7310 int idx = 0; 7884 int idx = 0;
7311 int idxStart = 0; 7885 int idxStart = 0;
7312 7886
7887 SceneObjectGroup parentgrp = part.ParentGroup;
7888
7313 bool positionChanged = false; 7889 bool positionChanged = false;
7314 LSL_Vector currentPosition = GetPartLocalPos(part); 7890 LSL_Vector currentPosition = GetPartLocalPos(part);
7315 7891
@@ -7334,8 +7910,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7334 return null; 7910 return null;
7335 7911
7336 v=rules.GetVector3Item(idx++); 7912 v=rules.GetVector3Item(idx++);
7337 positionChanged = true;
7338 currentPosition = GetSetPosTarget(part, v, currentPosition); 7913 currentPosition = GetSetPosTarget(part, v, currentPosition);
7914 positionChanged = true;
7339 7915
7340 break; 7916 break;
7341 case (int)ScriptBaseClass.PRIM_SIZE: 7917 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7612,7 +8188,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7612 return null; 8188 return null;
7613 8189
7614 string ph = rules.Data[idx++].ToString(); 8190 string ph = rules.Data[idx++].ToString();
7615 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8191 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7616 8192
7617 break; 8193 break;
7618 8194
@@ -7630,12 +8206,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7630 part.ScriptSetPhysicsStatus(physics); 8206 part.ScriptSetPhysicsStatus(physics);
7631 break; 8207 break;
7632 8208
8209 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8210 if (remain < 1)
8211 return null;
8212
8213 int shape_type = rules.GetLSLIntegerItem(idx++);
8214
8215 ExtraPhysicsData physdata = new ExtraPhysicsData();
8216 physdata.Density = part.Density;
8217 physdata.Bounce = part.Bounciness;
8218 physdata.GravitationModifier = part.GravityModifier;
8219 physdata.PhysShapeType = (PhysShapeType)shape_type;
8220
8221 part.UpdateExtraPhysics(physdata);
8222
8223 break;
8224
8225 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8226 if (remain < 5)
8227 return null;
8228
8229 int material_bits = rules.GetLSLIntegerItem(idx++);
8230 float material_density = (float)rules.GetLSLFloatItem(idx++);
8231 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8232 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8233 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8234
8235 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8236
8237 break;
8238
7633 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8239 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7634 if (remain < 1) 8240 if (remain < 1)
7635 return null; 8241 return null;
7636 string temp = rules.Data[idx++].ToString(); 8242 string temp = rules.Data[idx++].ToString();
7637 8243
7638 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8244 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7639 8245
7640 break; 8246 break;
7641 8247
@@ -7709,7 +8315,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7709 if (part.ParentGroup.RootPart == part) 8315 if (part.ParentGroup.RootPart == part)
7710 { 8316 {
7711 SceneObjectGroup parent = part.ParentGroup; 8317 SceneObjectGroup parent = part.ParentGroup;
7712 parent.UpdateGroupPosition(currentPosition); 8318 Util.FireAndForget(delegate(object x) {
8319 parent.UpdateGroupPosition(currentPosition);
8320 });
7713 } 8321 }
7714 else 8322 else
7715 { 8323 {
@@ -7754,10 +8362,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7754 8362
7755 public LSL_String llXorBase64Strings(string str1, string str2) 8363 public LSL_String llXorBase64Strings(string str1, string str2)
7756 { 8364 {
7757 m_host.AddScriptLPS(1); 8365 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7758 Deprecated("llXorBase64Strings"); 8366
7759 ScriptSleep(300); 8367 ScriptSleep(300);
7760 return String.Empty; 8368 m_host.AddScriptLPS(1);
8369
8370 if (str1 == String.Empty)
8371 return String.Empty;
8372 if (str2 == String.Empty)
8373 return str1;
8374
8375 int len = str2.Length;
8376 if ((len % 4) != 0) // LL is EVIL!!!!
8377 {
8378 while (str2.EndsWith("="))
8379 str2 = str2.Substring(0, str2.Length - 1);
8380
8381 len = str2.Length;
8382 int mod = len % 4;
8383
8384 if (mod == 1)
8385 str2 = str2.Substring(0, str2.Length - 1);
8386 else if (mod == 2)
8387 str2 += "==";
8388 else if (mod == 3)
8389 str2 += "=";
8390 }
8391
8392 byte[] data1;
8393 byte[] data2;
8394 try
8395 {
8396 data1 = Convert.FromBase64String(str1);
8397 data2 = Convert.FromBase64String(str2);
8398 }
8399 catch (Exception)
8400 {
8401 return new LSL_String(String.Empty);
8402 }
8403
8404 // For cases where the decoded length of s2 is greater
8405 // than the decoded length of s1, simply perform a normal
8406 // decode and XOR
8407 //
8408 if (data2.Length >= data1.Length)
8409 {
8410 for (int pos = 0 ; pos < data1.Length ; pos++ )
8411 data1[pos] ^= data2[pos];
8412
8413 return Convert.ToBase64String(data1);
8414 }
8415
8416 // Remove padding
8417 while (str1.EndsWith("="))
8418 str1 = str1.Substring(0, str1.Length - 1);
8419 while (str2.EndsWith("="))
8420 str2 = str2.Substring(0, str2.Length - 1);
8421
8422 byte[] d1 = new byte[str1.Length];
8423 byte[] d2 = new byte[str2.Length];
8424
8425 for (int i = 0 ; i < str1.Length ; i++)
8426 {
8427 int idx = b64.IndexOf(str1.Substring(i, 1));
8428 if (idx == -1)
8429 idx = 0;
8430 d1[i] = (byte)idx;
8431 }
8432
8433 for (int i = 0 ; i < str2.Length ; i++)
8434 {
8435 int idx = b64.IndexOf(str2.Substring(i, 1));
8436 if (idx == -1)
8437 idx = 0;
8438 d2[i] = (byte)idx;
8439 }
8440
8441 string output = String.Empty;
8442
8443 for (int pos = 0 ; pos < d1.Length ; pos++)
8444 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8445
8446 while (output.Length % 3 > 0)
8447 output += "=";
8448
8449 return output;
7761 } 8450 }
7762 8451
7763 public void llRemoteDataSetRegion() 8452 public void llRemoteDataSetRegion()
@@ -7881,13 +8570,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7881 public LSL_Integer llGetNumberOfPrims() 8570 public LSL_Integer llGetNumberOfPrims()
7882 { 8571 {
7883 m_host.AddScriptLPS(1); 8572 m_host.AddScriptLPS(1);
7884 int avatarCount = 0; 8573 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7885 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8574
7886 {
7887 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7888 avatarCount++;
7889 });
7890
7891 return m_host.ParentGroup.PrimCount + avatarCount; 8575 return m_host.ParentGroup.PrimCount + avatarCount;
7892 } 8576 }
7893 8577
@@ -7903,55 +8587,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7903 m_host.AddScriptLPS(1); 8587 m_host.AddScriptLPS(1);
7904 UUID objID = UUID.Zero; 8588 UUID objID = UUID.Zero;
7905 LSL_List result = new LSL_List(); 8589 LSL_List result = new LSL_List();
8590
8591 // If the ID is not valid, return null result
7906 if (!UUID.TryParse(obj, out objID)) 8592 if (!UUID.TryParse(obj, out objID))
7907 { 8593 {
7908 result.Add(new LSL_Vector()); 8594 result.Add(new LSL_Vector());
7909 result.Add(new LSL_Vector()); 8595 result.Add(new LSL_Vector());
7910 return result; 8596 return result;
7911 } 8597 }
8598
8599 // Check if this is an attached prim. If so, replace
8600 // the UUID with the avatar UUID and report it's bounding box
8601 SceneObjectPart part = World.GetSceneObjectPart(objID);
8602 if (part != null && part.ParentGroup.IsAttachment)
8603 objID = part.ParentGroup.AttachedAvatar;
8604
8605 // Find out if this is an avatar ID. If so, return it's box
7912 ScenePresence presence = World.GetScenePresence(objID); 8606 ScenePresence presence = World.GetScenePresence(objID);
7913 if (presence != null) 8607 if (presence != null)
7914 { 8608 {
7915 if (presence.ParentID == 0) // not sat on an object 8609 // As per LSL Wiki, there is no difference between sitting
8610 // and standing avatar since server 1.36
8611 LSL_Vector lower;
8612 LSL_Vector upper;
8613
8614 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8615
8616 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8617 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8618/*
7916 { 8619 {
7917 LSL_Vector lower; 8620 // This is for ground sitting avatars
7918 LSL_Vector upper; 8621 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7919 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8622 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7920 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8623 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7921 {
7922 // This is for ground sitting avatars
7923 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7924 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7925 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7926 }
7927 else
7928 {
7929 // This is for standing/flying avatars
7930 float height = presence.Appearance.AvatarHeight / 2.0f;
7931 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7932 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7933 }
7934 result.Add(lower);
7935 result.Add(upper);
7936 return result;
7937 } 8624 }
7938 else 8625 else
7939 { 8626 {
7940 // sitting on an object so we need the bounding box of that 8627 // This is for standing/flying avatars
7941 // which should include the avatar so set the UUID to the 8628 float height = presence.Appearance.AvatarHeight / 2.0f;
7942 // UUID of the object the avatar is sat on and allow it to fall through 8629 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7943 // to processing an object 8630 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7944 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7945 objID = p.UUID;
7946 } 8631 }
8632
8633 // Adjust to the documented error offsets (see LSL Wiki)
8634 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8635 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8636*/
8637 {
8638 // This is for ground sitting avatars TODO!
8639 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8640 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8641 }
8642 else
8643 {
8644 // This is for standing/flying avatars
8645 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8646 upper = new LSL_Vector(box.X, box.Y, box.Z);
8647 }
8648
8649 if (lower.x > upper.x)
8650 lower.x = upper.x;
8651 if (lower.y > upper.y)
8652 lower.y = upper.y;
8653 if (lower.z > upper.z)
8654 lower.z = upper.z;
8655
8656 result.Add(lower);
8657 result.Add(upper);
8658 return result;
7947 } 8659 }
7948 SceneObjectPart part = World.GetSceneObjectPart(objID); 8660
8661 part = World.GetSceneObjectPart(objID);
7949 // Currently only works for single prims without a sitting avatar 8662 // Currently only works for single prims without a sitting avatar
7950 if (part != null) 8663 if (part != null)
7951 { 8664 {
7952 Vector3 halfSize = part.Scale / 2.0f; 8665 float minX;
7953 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8666 float maxX;
7954 LSL_Vector upper = new LSL_Vector(halfSize); 8667 float minY;
8668 float maxY;
8669 float minZ;
8670 float maxZ;
8671
8672 // This BBox is in sim coordinates, with the offset being
8673 // a contained point.
8674 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8675 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8676
8677 minX -= offsets[0].X;
8678 maxX -= offsets[0].X;
8679 minY -= offsets[0].Y;
8680 maxY -= offsets[0].Y;
8681 minZ -= offsets[0].Z;
8682 maxZ -= offsets[0].Z;
8683
8684 LSL_Vector lower;
8685 LSL_Vector upper;
8686
8687 // Adjust to the documented error offsets (see LSL Wiki)
8688 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8689 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8690
8691 if (lower.x > upper.x)
8692 lower.x = upper.x;
8693 if (lower.y > upper.y)
8694 lower.y = upper.y;
8695 if (lower.z > upper.z)
8696 lower.z = upper.z;
8697
7955 result.Add(lower); 8698 result.Add(lower);
7956 result.Add(upper); 8699 result.Add(upper);
7957 return result; 8700 return result;
@@ -7965,7 +8708,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7965 8708
7966 public LSL_Vector llGetGeometricCenter() 8709 public LSL_Vector llGetGeometricCenter()
7967 { 8710 {
7968 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8711 Vector3 tmp = m_host.GetGeometricCenter();
8712 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7969 } 8713 }
7970 8714
7971 public LSL_List llGetPrimitiveParams(LSL_List rules) 8715 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7993,24 +8737,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7993 { 8737 {
7994 m_host.AddScriptLPS(1); 8738 m_host.AddScriptLPS(1);
7995 8739
7996 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8740 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8741 // keep other options as before
7997 8742
8743 List<SceneObjectPart> parts;
8744 List<ScenePresence> avatars;
8745
7998 LSL_List res = new LSL_List(); 8746 LSL_List res = new LSL_List();
7999 LSL_List remaining = null; 8747 LSL_List remaining = null;
8000 8748
8001 foreach (SceneObjectPart part in parts) 8749 while (rules.Length > 0)
8002 {
8003 remaining = GetPrimParams(part, rules, ref res);
8004 }
8005
8006 while (remaining != null && remaining.Length > 2)
8007 { 8750 {
8008 linknumber = remaining.GetLSLIntegerItem(0);
8009 rules = remaining.GetSublist(1, -1);
8010 parts = GetLinkParts(linknumber); 8751 parts = GetLinkParts(linknumber);
8752 avatars = GetLinkAvatars(linknumber);
8011 8753
8754 remaining = null;
8012 foreach (SceneObjectPart part in parts) 8755 foreach (SceneObjectPart part in parts)
8756 {
8013 remaining = GetPrimParams(part, rules, ref res); 8757 remaining = GetPrimParams(part, rules, ref res);
8758 }
8759 foreach (ScenePresence avatar in avatars)
8760 {
8761 remaining = GetPrimParams(avatar, rules, ref res);
8762 }
8763
8764 if (remaining != null && remaining.Length > 0)
8765 {
8766 linknumber = remaining.GetLSLIntegerItem(0);
8767 rules = remaining.GetSublist(1, -1);
8768 }
8014 } 8769 }
8015 8770
8016 return res; 8771 return res;
@@ -8055,13 +8810,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8055 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8810 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8056 part.AbsolutePosition.Y, 8811 part.AbsolutePosition.Y,
8057 part.AbsolutePosition.Z); 8812 part.AbsolutePosition.Z);
8058 // For some reason, the part.AbsolutePosition.* values do not change if the
8059 // linkset is rotated; they always reflect the child prim's world position
8060 // as though the linkset is unrotated. This is incompatible behavior with SL's
8061 // implementation, so will break scripts imported from there (not to mention it
8062 // makes it more difficult to determine a child prim's actual inworld position).
8063 if (part.ParentID != 0)
8064 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8065 res.Add(v); 8813 res.Add(v);
8066 break; 8814 break;
8067 8815
@@ -8233,30 +8981,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8233 if (remain < 1) 8981 if (remain < 1)
8234 return null; 8982 return null;
8235 8983
8236 face=(int)rules.GetLSLIntegerItem(idx++); 8984 face = (int)rules.GetLSLIntegerItem(idx++);
8237 8985
8238 tex = part.Shape.Textures; 8986 tex = part.Shape.Textures;
8987 int shiny;
8239 if (face == ScriptBaseClass.ALL_SIDES) 8988 if (face == ScriptBaseClass.ALL_SIDES)
8240 { 8989 {
8241 for (face = 0; face < GetNumberOfSides(part); face++) 8990 for (face = 0; face < GetNumberOfSides(part); face++)
8242 { 8991 {
8243 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8992 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8244 // Convert Shininess to PRIM_SHINY_* 8993 if (shinyness == Shininess.High)
8245 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8994 {
8246 // PRIM_BUMP_* 8995 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8247 res.Add(new LSL_Integer((int)texface.Bump)); 8996 }
8997 else if (shinyness == Shininess.Medium)
8998 {
8999 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9000 }
9001 else if (shinyness == Shininess.Low)
9002 {
9003 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9004 }
9005 else
9006 {
9007 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9008 }
9009 res.Add(new LSL_Integer(shiny));
9010 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8248 } 9011 }
8249 } 9012 }
8250 else 9013 else
8251 { 9014 {
8252 if (face >= 0 && face < GetNumberOfSides(part)) 9015 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9016 if (shinyness == Shininess.High)
8253 { 9017 {
8254 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9018 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8255 // Convert Shininess to PRIM_SHINY_* 9019 }
8256 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9020 else if (shinyness == Shininess.Medium)
8257 // PRIM_BUMP_* 9021 {
8258 res.Add(new LSL_Integer((int)texface.Bump)); 9022 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9023 }
9024 else if (shinyness == Shininess.Low)
9025 {
9026 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9027 }
9028 else
9029 {
9030 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8259 } 9031 }
9032 res.Add(new LSL_Integer(shiny));
9033 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8260 } 9034 }
8261 break; 9035 break;
8262 9036
@@ -8264,24 +9038,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8264 if (remain < 1) 9038 if (remain < 1)
8265 return null; 9039 return null;
8266 9040
8267 face=(int)rules.GetLSLIntegerItem(idx++); 9041 face = (int)rules.GetLSLIntegerItem(idx++);
8268 9042
8269 tex = part.Shape.Textures; 9043 tex = part.Shape.Textures;
9044 int fullbright;
8270 if (face == ScriptBaseClass.ALL_SIDES) 9045 if (face == ScriptBaseClass.ALL_SIDES)
8271 { 9046 {
8272 for (face = 0; face < GetNumberOfSides(part); face++) 9047 for (face = 0; face < GetNumberOfSides(part); face++)
8273 { 9048 {
8274 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9049 if (tex.GetFace((uint)face).Fullbright == true)
8275 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9050 {
9051 fullbright = ScriptBaseClass.TRUE;
9052 }
9053 else
9054 {
9055 fullbright = ScriptBaseClass.FALSE;
9056 }
9057 res.Add(new LSL_Integer(fullbright));
8276 } 9058 }
8277 } 9059 }
8278 else 9060 else
8279 { 9061 {
8280 if (face >= 0 && face < GetNumberOfSides(part)) 9062 if (tex.GetFace((uint)face).Fullbright == true)
8281 { 9063 {
8282 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9064 fullbright = ScriptBaseClass.TRUE;
8283 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9065 }
9066 else
9067 {
9068 fullbright = ScriptBaseClass.FALSE;
8284 } 9069 }
9070 res.Add(new LSL_Integer(fullbright));
8285 } 9071 }
8286 break; 9072 break;
8287 9073
@@ -8303,27 +9089,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8303 break; 9089 break;
8304 9090
8305 case (int)ScriptBaseClass.PRIM_TEXGEN: 9091 case (int)ScriptBaseClass.PRIM_TEXGEN:
9092 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8306 if (remain < 1) 9093 if (remain < 1)
8307 return null; 9094 return null;
8308 9095
8309 face=(int)rules.GetLSLIntegerItem(idx++); 9096 face = (int)rules.GetLSLIntegerItem(idx++);
8310 9097
8311 tex = part.Shape.Textures; 9098 tex = part.Shape.Textures;
8312 if (face == ScriptBaseClass.ALL_SIDES) 9099 if (face == ScriptBaseClass.ALL_SIDES)
8313 { 9100 {
8314 for (face = 0; face < GetNumberOfSides(part); face++) 9101 for (face = 0; face < GetNumberOfSides(part); face++)
8315 { 9102 {
8316 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9103 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8317 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9104 {
8318 res.Add(new LSL_Integer((uint)texgen >> 1)); 9105 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9106 }
9107 else
9108 {
9109 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9110 }
8319 } 9111 }
8320 } 9112 }
8321 else 9113 else
8322 { 9114 {
8323 if (face >= 0 && face < GetNumberOfSides(part)) 9115 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8324 { 9116 {
8325 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9117 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8326 res.Add(new LSL_Integer((uint)texgen >> 1)); 9118 }
9119 else
9120 {
9121 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8327 } 9122 }
8328 } 9123 }
8329 break; 9124 break;
@@ -8347,24 +9142,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8347 if (remain < 1) 9142 if (remain < 1)
8348 return null; 9143 return null;
8349 9144
8350 face=(int)rules.GetLSLIntegerItem(idx++); 9145 face = (int)rules.GetLSLIntegerItem(idx++);
8351 9146
8352 tex = part.Shape.Textures; 9147 tex = part.Shape.Textures;
9148 float primglow;
8353 if (face == ScriptBaseClass.ALL_SIDES) 9149 if (face == ScriptBaseClass.ALL_SIDES)
8354 { 9150 {
8355 for (face = 0; face < GetNumberOfSides(part); face++) 9151 for (face = 0; face < GetNumberOfSides(part); face++)
8356 { 9152 {
8357 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9153 primglow = tex.GetFace((uint)face).Glow;
8358 res.Add(new LSL_Float(texface.Glow)); 9154 res.Add(new LSL_Float(primglow));
8359 } 9155 }
8360 } 9156 }
8361 else 9157 else
8362 { 9158 {
8363 if (face >= 0 && face < GetNumberOfSides(part)) 9159 primglow = tex.GetFace((uint)face).Glow;
8364 { 9160 res.Add(new LSL_Float(primglow));
8365 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8366 res.Add(new LSL_Float(texface.Glow));
8367 }
8368 } 9161 }
8369 break; 9162 break;
8370 9163
@@ -8376,15 +9169,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8376 textColor.B)); 9169 textColor.B));
8377 res.Add(new LSL_Float(textColor.A)); 9170 res.Add(new LSL_Float(textColor.A));
8378 break; 9171 break;
9172
8379 case (int)ScriptBaseClass.PRIM_NAME: 9173 case (int)ScriptBaseClass.PRIM_NAME:
8380 res.Add(new LSL_String(part.Name)); 9174 res.Add(new LSL_String(part.Name));
8381 break; 9175 break;
9176
8382 case (int)ScriptBaseClass.PRIM_DESC: 9177 case (int)ScriptBaseClass.PRIM_DESC:
8383 res.Add(new LSL_String(part.Description)); 9178 res.Add(new LSL_String(part.Description));
8384 break; 9179 break;
9180
8385 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9181 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8386 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9182 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8387 break; 9183 break;
9184
8388 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9185 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8389 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9186 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8390 break; 9187 break;
@@ -8995,8 +9792,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8995 // The function returns an ordered list 9792 // The function returns an ordered list
8996 // representing the tokens found in the supplied 9793 // representing the tokens found in the supplied
8997 // sources string. If two successive tokenizers 9794 // sources string. If two successive tokenizers
8998 // are encountered, then a NULL entry is added 9795 // are encountered, then a null-string entry is
8999 // to the list. 9796 // added to the list.
9000 // 9797 //
9001 // It is a precondition that the source and 9798 // It is a precondition that the source and
9002 // toekizer lisst are non-null. If they are null, 9799 // toekizer lisst are non-null. If they are null,
@@ -9004,7 +9801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9004 // while their lengths are being determined. 9801 // while their lengths are being determined.
9005 // 9802 //
9006 // A small amount of working memoryis required 9803 // A small amount of working memoryis required
9007 // of approximately 8*#tokenizers. 9804 // of approximately 8*#tokenizers + 8*srcstrlen.
9008 // 9805 //
9009 // There are many ways in which this function 9806 // There are many ways in which this function
9010 // can be implemented, this implementation is 9807 // can be implemented, this implementation is
@@ -9020,155 +9817,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9020 // and eliminates redundant tokenizers as soon 9817 // and eliminates redundant tokenizers as soon
9021 // as is possible. 9818 // as is possible.
9022 // 9819 //
9023 // The implementation tries to avoid any copying 9820 // The implementation tries to minimize temporary
9024 // of arrays or other objects. 9821 // garbage generation.
9025 // </remarks> 9822 // </remarks>
9026 9823
9027 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9824 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9028 { 9825 {
9029 int beginning = 0; 9826 return ParseString2List(src, separators, spacers, true);
9030 int srclen = src.Length; 9827 }
9031 int seplen = separators.Length;
9032 object[] separray = separators.Data;
9033 int spclen = spacers.Length;
9034 object[] spcarray = spacers.Data;
9035 int mlen = seplen+spclen;
9036
9037 int[] offset = new int[mlen+1];
9038 bool[] active = new bool[mlen];
9039
9040 int best;
9041 int j;
9042
9043 // Initial capacity reduces resize cost
9044 9828
9045 LSL_List tokens = new LSL_List(); 9829 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9830 {
9831 int srclen = src.Length;
9832 int seplen = separators.Length;
9833 object[] separray = separators.Data;
9834 int spclen = spacers.Length;
9835 object[] spcarray = spacers.Data;
9836 int dellen = 0;
9837 string[] delarray = new string[seplen+spclen];
9046 9838
9047 // All entries are initially valid 9839 int outlen = 0;
9840 string[] outarray = new string[srclen*2+1];
9048 9841
9049 for (int i = 0; i < mlen; i++) 9842 int i, j;
9050 active[i] = true; 9843 string d;
9051 9844
9052 offset[mlen] = srclen; 9845 m_host.AddScriptLPS(1);
9053 9846
9054 while (beginning < srclen) 9847 /*
9848 * Convert separator and spacer lists to C# strings.
9849 * Also filter out null strings so we don't hang.
9850 */
9851 for (i = 0; i < seplen; i ++)
9055 { 9852 {
9853 d = separray[i].ToString();
9854 if (d.Length > 0)
9855 {
9856 delarray[dellen++] = d;
9857 }
9858 }
9859 seplen = dellen;
9056 9860
9057 best = mlen; // as bad as it gets 9861 for (i = 0; i < spclen; i ++)
9862 {
9863 d = spcarray[i].ToString();
9864 if (d.Length > 0)
9865 {
9866 delarray[dellen++] = d;
9867 }
9868 }
9058 9869
9059 // Scan for separators 9870 /*
9871 * Scan through source string from beginning to end.
9872 */
9873 for (i = 0;;)
9874 {
9060 9875
9061 for (j = 0; j < seplen; j++) 9876 /*
9877 * Find earliest delimeter in src starting at i (if any).
9878 */
9879 int earliestDel = -1;
9880 int earliestSrc = srclen;
9881 string earliestStr = null;
9882 for (j = 0; j < dellen; j ++)
9062 { 9883 {
9063 if (separray[j].ToString() == String.Empty) 9884 d = delarray[j];
9064 active[j] = false; 9885 if (d != null)
9065
9066 if (active[j])
9067 { 9886 {
9068 // scan all of the markers 9887 int index = src.IndexOf(d, i);
9069 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9888 if (index < 0)
9070 { 9889 {
9071 // not present at all 9890 delarray[j] = null; // delim nowhere in src, don't check it anymore
9072 active[j] = false;
9073 } 9891 }
9074 else 9892 else if (index < earliestSrc)
9075 { 9893 {
9076 // present and correct 9894 earliestSrc = index; // where delimeter starts in source string
9077 if (offset[j] < offset[best]) 9895 earliestDel = j; // where delimeter is in delarray[]
9078 { 9896 earliestStr = d; // the delimeter string from delarray[]
9079 // closest so far 9897 if (index == i) break; // can't do any better than found at beg of string
9080 best = j;
9081 if (offset[best] == beginning)
9082 break;
9083 }
9084 } 9898 }
9085 } 9899 }
9086 } 9900 }
9087 9901
9088 // Scan for spacers 9902 /*
9089 9903 * Output source string starting at i through start of earliest delimeter.
9090 if (offset[best] != beginning) 9904 */
9905 if (keepNulls || (earliestSrc > i))
9091 { 9906 {
9092 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9907 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9093 {
9094 if (spcarray[j-seplen].ToString() == String.Empty)
9095 active[j] = false;
9096
9097 if (active[j])
9098 {
9099 // scan all of the markers
9100 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9101 {
9102 // not present at all
9103 active[j] = false;
9104 }
9105 else
9106 {
9107 // present and correct
9108 if (offset[j] < offset[best])
9109 {
9110 // closest so far
9111 best = j;
9112 }
9113 }
9114 }
9115 }
9116 } 9908 }
9117 9909
9118 // This is the normal exit from the scanning loop 9910 /*
9911 * If no delimeter found at or after i, we're done scanning.
9912 */
9913 if (earliestDel < 0) break;
9119 9914
9120 if (best == mlen) 9915 /*
9916 * If delimeter was a spacer, output the spacer.
9917 */
9918 if (earliestDel >= seplen)
9121 { 9919 {
9122 // no markers were found on this pass 9920 outarray[outlen++] = earliestStr;
9123 // so we're pretty much done
9124 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9125 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9126 break;
9127 } 9921 }
9128 9922
9129 // Otherwise we just add the newly delimited token 9923 /*
9130 // and recalculate where the search should continue. 9924 * Look at rest of src string following delimeter.
9131 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9925 */
9132 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9926 i = earliestSrc + earliestStr.Length;
9133
9134 if (best < seplen)
9135 {
9136 beginning = offset[best] + (separray[best].ToString()).Length;
9137 }
9138 else
9139 {
9140 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9141 string str = spcarray[best - seplen].ToString();
9142 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9143 tokens.Add(new LSL_String(str));
9144 }
9145 } 9927 }
9146 9928
9147 // This an awkward an not very intuitive boundary case. If the 9929 /*
9148 // last substring is a tokenizer, then there is an implied trailing 9930 * Make up an exact-sized output array suitable for an LSL_List object.
9149 // null list entry. Hopefully the single comparison will not be too 9931 */
9150 // arduous. Alternatively the 'break' could be replced with a return 9932 object[] outlist = new object[outlen];
9151 // but that's shabby programming. 9933 for (i = 0; i < outlen; i ++)
9152
9153 if ((beginning == srclen) && (keepNulls))
9154 { 9934 {
9155 if (srclen != 0) 9935 outlist[i] = new LSL_String(outarray[i]);
9156 tokens.Add(new LSL_String(""));
9157 } 9936 }
9158 9937 return new LSL_List(outlist);
9159 return tokens;
9160 }
9161
9162 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9163 {
9164 m_host.AddScriptLPS(1);
9165 return this.ParseString(src, separators, spacers, false);
9166 }
9167
9168 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9169 {
9170 m_host.AddScriptLPS(1);
9171 return this.ParseString(src, separators, spacers, true);
9172 } 9938 }
9173 9939
9174 public LSL_Integer llGetObjectPermMask(int mask) 9940 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9263,6 +10029,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9263 case 4: 10029 case 4:
9264 return (int)item.NextPermissions; 10030 return (int)item.NextPermissions;
9265 } 10031 }
10032 m_host.TaskInventory.LockItemsForRead(false);
9266 10033
9267 return -1; 10034 return -1;
9268 } 10035 }
@@ -9465,31 +10232,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 UUID key = new UUID(); 10232 UUID key = new UUID();
9466 if (UUID.TryParse(id, out key)) 10233 if (UUID.TryParse(id, out key))
9467 { 10234 {
9468 try 10235 // return total object mass
9469 { 10236 SceneObjectPart part = World.GetSceneObjectPart(key);
9470 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10237 if (part != null)
9471 if (obj != null) 10238 return part.ParentGroup.GetMass();
9472 return (double)obj.GetMass(); 10239
9473 // the object is null so the key is for an avatar 10240 // the object is null so the key is for an avatar
9474 ScenePresence avatar = World.GetScenePresence(key); 10241 ScenePresence avatar = World.GetScenePresence(key);
9475 if (avatar != null) 10242 if (avatar != null)
9476 if (avatar.IsChildAgent)
9477 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9478 // child agents have a mass of 1.0
9479 return 1;
9480 else
9481 return (double)avatar.GetMass();
9482 }
9483 catch (KeyNotFoundException)
9484 { 10243 {
9485 return 0; // The Object/Agent not in the region so just return zero 10244 if (avatar.IsChildAgent)
10245 {
10246 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10247 // child agents have a mass of 1.0
10248 return 1;
10249 }
10250 else
10251 {
10252 return (double)avatar.GetMass();
10253 }
9486 } 10254 }
9487 } 10255 }
9488 return 0; 10256 return 0;
9489 } 10257 }
9490 10258
9491 /// <summary> 10259 /// <summary>
9492 /// illListReplaceList removes the sub-list defined by the inclusive indices 10260 /// llListReplaceList removes the sub-list defined by the inclusive indices
9493 /// start and end and inserts the src list in its place. The inclusive 10261 /// start and end and inserts the src list in its place. The inclusive
9494 /// nature of the indices means that at least one element must be deleted 10262 /// nature of the indices means that at least one element must be deleted
9495 /// if the indices are within the bounds of the existing list. I.e. 2,2 10263 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9546,16 +10314,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9546 // based upon end. Note that if end exceeds the upper 10314 // based upon end. Note that if end exceeds the upper
9547 // bound in this case, the entire destination list 10315 // bound in this case, the entire destination list
9548 // is removed. 10316 // is removed.
9549 else 10317 else if (start == 0)
9550 { 10318 {
9551 if (end + 1 < dest.Length) 10319 if (end + 1 < dest.Length)
9552 {
9553 return src + dest.GetSublist(end + 1, -1); 10320 return src + dest.GetSublist(end + 1, -1);
9554 }
9555 else 10321 else
9556 {
9557 return src; 10322 return src;
9558 } 10323 }
10324 else // Start < 0
10325 {
10326 if (end + 1 < dest.Length)
10327 return dest.GetSublist(end + 1, -1);
10328 else
10329 return new LSL_List();
9559 } 10330 }
9560 } 10331 }
9561 // Finally, if start > end, we strip away a prefix and 10332 // Finally, if start > end, we strip away a prefix and
@@ -9606,17 +10377,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9606 int width = 0; 10377 int width = 0;
9607 int height = 0; 10378 int height = 0;
9608 10379
9609 ParcelMediaCommandEnum? commandToSend = null; 10380 uint commandToSend = 0;
9610 float time = 0.0f; // default is from start 10381 float time = 0.0f; // default is from start
9611 10382
9612 ScenePresence presence = null; 10383 ScenePresence presence = null;
9613 10384
9614 for (int i = 0; i < commandList.Data.Length; i++) 10385 for (int i = 0; i < commandList.Data.Length; i++)
9615 { 10386 {
9616 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10387 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9617 switch (command) 10388 switch (command)
9618 { 10389 {
9619 case ParcelMediaCommandEnum.Agent: 10390 case (uint)ParcelMediaCommandEnum.Agent:
9620 // we send only to one agent 10391 // we send only to one agent
9621 if ((i + 1) < commandList.Length) 10392 if ((i + 1) < commandList.Length)
9622 { 10393 {
@@ -9633,25 +10404,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9633 } 10404 }
9634 break; 10405 break;
9635 10406
9636 case ParcelMediaCommandEnum.Loop: 10407 case (uint)ParcelMediaCommandEnum.Loop:
9637 loop = 1; 10408 loop = 1;
9638 commandToSend = command; 10409 commandToSend = command;
9639 update = true; //need to send the media update packet to set looping 10410 update = true; //need to send the media update packet to set looping
9640 break; 10411 break;
9641 10412
9642 case ParcelMediaCommandEnum.Play: 10413 case (uint)ParcelMediaCommandEnum.Play:
9643 loop = 0; 10414 loop = 0;
9644 commandToSend = command; 10415 commandToSend = command;
9645 update = true; //need to send the media update packet to make sure it doesn't loop 10416 update = true; //need to send the media update packet to make sure it doesn't loop
9646 break; 10417 break;
9647 10418
9648 case ParcelMediaCommandEnum.Pause: 10419 case (uint)ParcelMediaCommandEnum.Pause:
9649 case ParcelMediaCommandEnum.Stop: 10420 case (uint)ParcelMediaCommandEnum.Stop:
9650 case ParcelMediaCommandEnum.Unload: 10421 case (uint)ParcelMediaCommandEnum.Unload:
9651 commandToSend = command; 10422 commandToSend = command;
9652 break; 10423 break;
9653 10424
9654 case ParcelMediaCommandEnum.Url: 10425 case (uint)ParcelMediaCommandEnum.Url:
9655 if ((i + 1) < commandList.Length) 10426 if ((i + 1) < commandList.Length)
9656 { 10427 {
9657 if (commandList.Data[i + 1] is LSL_String) 10428 if (commandList.Data[i + 1] is LSL_String)
@@ -9664,7 +10435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9664 } 10435 }
9665 break; 10436 break;
9666 10437
9667 case ParcelMediaCommandEnum.Texture: 10438 case (uint)ParcelMediaCommandEnum.Texture:
9668 if ((i + 1) < commandList.Length) 10439 if ((i + 1) < commandList.Length)
9669 { 10440 {
9670 if (commandList.Data[i + 1] is LSL_String) 10441 if (commandList.Data[i + 1] is LSL_String)
@@ -9677,7 +10448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9677 } 10448 }
9678 break; 10449 break;
9679 10450
9680 case ParcelMediaCommandEnum.Time: 10451 case (uint)ParcelMediaCommandEnum.Time:
9681 if ((i + 1) < commandList.Length) 10452 if ((i + 1) < commandList.Length)
9682 { 10453 {
9683 if (commandList.Data[i + 1] is LSL_Float) 10454 if (commandList.Data[i + 1] is LSL_Float)
@@ -9689,7 +10460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9689 } 10460 }
9690 break; 10461 break;
9691 10462
9692 case ParcelMediaCommandEnum.AutoAlign: 10463 case (uint)ParcelMediaCommandEnum.AutoAlign:
9693 if ((i + 1) < commandList.Length) 10464 if ((i + 1) < commandList.Length)
9694 { 10465 {
9695 if (commandList.Data[i + 1] is LSL_Integer) 10466 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9703,7 +10474,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9703 } 10474 }
9704 break; 10475 break;
9705 10476
9706 case ParcelMediaCommandEnum.Type: 10477 case (uint)ParcelMediaCommandEnum.Type:
9707 if ((i + 1) < commandList.Length) 10478 if ((i + 1) < commandList.Length)
9708 { 10479 {
9709 if (commandList.Data[i + 1] is LSL_String) 10480 if (commandList.Data[i + 1] is LSL_String)
@@ -9716,7 +10487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9716 } 10487 }
9717 break; 10488 break;
9718 10489
9719 case ParcelMediaCommandEnum.Desc: 10490 case (uint)ParcelMediaCommandEnum.Desc:
9720 if ((i + 1) < commandList.Length) 10491 if ((i + 1) < commandList.Length)
9721 { 10492 {
9722 if (commandList.Data[i + 1] is LSL_String) 10493 if (commandList.Data[i + 1] is LSL_String)
@@ -9729,7 +10500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9729 } 10500 }
9730 break; 10501 break;
9731 10502
9732 case ParcelMediaCommandEnum.Size: 10503 case (uint)ParcelMediaCommandEnum.Size:
9733 if ((i + 2) < commandList.Length) 10504 if ((i + 2) < commandList.Length)
9734 { 10505 {
9735 if (commandList.Data[i + 1] is LSL_Integer) 10506 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9799,7 +10570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9799 } 10570 }
9800 } 10571 }
9801 10572
9802 if (commandToSend != null) 10573 if (commandToSend != 0)
9803 { 10574 {
9804 // the commandList contained a start/stop/... command, too 10575 // the commandList contained a start/stop/... command, too
9805 if (presence == null) 10576 if (presence == null)
@@ -9836,7 +10607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9836 10607
9837 if (aList.Data[i] != null) 10608 if (aList.Data[i] != null)
9838 { 10609 {
9839 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10610 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9840 { 10611 {
9841 case ParcelMediaCommandEnum.Url: 10612 case ParcelMediaCommandEnum.Url:
9842 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10613 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9893,15 +10664,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9893 10664
9894 if (quick_pay_buttons.Data.Length < 4) 10665 if (quick_pay_buttons.Data.Length < 4)
9895 { 10666 {
9896 LSLError("List must have at least 4 elements"); 10667 int x;
9897 return; 10668 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10669 {
10670 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10671 }
9898 } 10672 }
9899 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10673 int[] nPrice = new int[5];
9900 10674 nPrice[0] = price;
9901 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10675 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9902 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10676 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9903 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10677 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9904 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10678 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10679 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9905 m_host.ParentGroup.HasGroupChanged = true; 10680 m_host.ParentGroup.HasGroupChanged = true;
9906 } 10681 }
9907 10682
@@ -9918,7 +10693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9918 return new LSL_Vector(); 10693 return new LSL_Vector();
9919 } 10694 }
9920 10695
9921 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10696// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10697 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9922 if (presence != null) 10698 if (presence != null)
9923 { 10699 {
9924 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10700 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9940,7 +10716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9940 return new LSL_Rotation(); 10716 return new LSL_Rotation();
9941 } 10717 }
9942 10718
9943 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10719// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10720 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9944 if (presence != null) 10721 if (presence != null)
9945 { 10722 {
9946 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10723 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10000,14 +10777,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10000 { 10777 {
10001 m_host.AddScriptLPS(1); 10778 m_host.AddScriptLPS(1);
10002 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10779 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10003 if (detectedParams == null) return; // only works on the first detected avatar 10780 if (detectedParams == null)
10004 10781 {
10782 if (m_host.ParentGroup.IsAttachment == true)
10783 {
10784 detectedParams = new DetectParams();
10785 detectedParams.Key = m_host.OwnerID;
10786 }
10787 else
10788 {
10789 return;
10790 }
10791 }
10792
10005 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10793 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10006 if (avatar != null) 10794 if (avatar != null)
10007 { 10795 {
10008 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10796 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10009 simname, pos, lookAt); 10797 simname, pos, lookAt);
10010 } 10798 }
10799
10011 ScriptSleep(1000); 10800 ScriptSleep(1000);
10012 } 10801 }
10013 10802
@@ -10131,12 +10920,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10131 10920
10132 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10921 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10133 object[] data = rules.Data; 10922 object[] data = rules.Data;
10134 for (int i = 0; i < data.Length; ++i) { 10923 for (int i = 0; i < data.Length; ++i)
10924 {
10135 int type = Convert.ToInt32(data[i++].ToString()); 10925 int type = Convert.ToInt32(data[i++].ToString());
10136 if (i >= data.Length) break; // odd number of entries => ignore the last 10926 if (i >= data.Length) break; // odd number of entries => ignore the last
10137 10927
10138 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10928 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10139 switch (type) { 10929 switch (type)
10930 {
10140 case ScriptBaseClass.CAMERA_FOCUS: 10931 case ScriptBaseClass.CAMERA_FOCUS:
10141 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10932 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10142 case ScriptBaseClass.CAMERA_POSITION: 10933 case ScriptBaseClass.CAMERA_POSITION:
@@ -10241,19 +11032,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10241 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11032 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10242 { 11033 {
10243 m_host.AddScriptLPS(1); 11034 m_host.AddScriptLPS(1);
10244 string ret = String.Empty; 11035
10245 string src1 = llBase64ToString(str1); 11036 if (str1 == String.Empty)
10246 string src2 = llBase64ToString(str2); 11037 return String.Empty;
10247 int c = 0; 11038 if (str2 == String.Empty)
10248 for (int i = 0; i < src1.Length; i++) 11039 return str1;
11040
11041 int len = str2.Length;
11042 if ((len % 4) != 0) // LL is EVIL!!!!
11043 {
11044 while (str2.EndsWith("="))
11045 str2 = str2.Substring(0, str2.Length - 1);
11046
11047 len = str2.Length;
11048 int mod = len % 4;
11049
11050 if (mod == 1)
11051 str2 = str2.Substring(0, str2.Length - 1);
11052 else if (mod == 2)
11053 str2 += "==";
11054 else if (mod == 3)
11055 str2 += "=";
11056 }
11057
11058 byte[] data1;
11059 byte[] data2;
11060 try
11061 {
11062 data1 = Convert.FromBase64String(str1);
11063 data2 = Convert.FromBase64String(str2);
11064 }
11065 catch (Exception)
11066 {
11067 return new LSL_String(String.Empty);
11068 }
11069
11070 byte[] d2 = new Byte[data1.Length];
11071 int pos = 0;
11072
11073 if (data1.Length <= data2.Length)
11074 {
11075 Array.Copy(data2, 0, d2, 0, data1.Length);
11076 }
11077 else
10249 { 11078 {
10250 ret += (char) (src1[i] ^ src2[c]); 11079 while (pos < data1.Length)
11080 {
11081 len = data1.Length - pos;
11082 if (len > data2.Length)
11083 len = data2.Length;
10251 11084
10252 c++; 11085 Array.Copy(data2, 0, d2, pos, len);
10253 if (c >= src2.Length) 11086 pos += len;
10254 c = 0; 11087 }
10255 } 11088 }
10256 return llStringToBase64(ret); 11089
11090 for (pos = 0 ; pos < data1.Length ; pos++ )
11091 data1[pos] ^= d2[pos];
11092
11093 return Convert.ToBase64String(data1);
10257 } 11094 }
10258 11095
10259 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11096 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10306,16 +11143,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10306 if (userAgent != null) 11143 if (userAgent != null)
10307 httpHeaders["User-Agent"] = userAgent; 11144 httpHeaders["User-Agent"] = userAgent;
10308 11145
11146 // See if the URL contains any header hacks
11147 string[] urlParts = url.Split(new char[] {'\n'});
11148 if (urlParts.Length > 1)
11149 {
11150 // Iterate the passed headers and parse them
11151 for (int i = 1 ; i < urlParts.Length ; i++ )
11152 {
11153 // The rest of those would be added to the body in SL.
11154 // Let's not do that.
11155 if (urlParts[i] == String.Empty)
11156 break;
11157
11158 // See if this could be a valid header
11159 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11160 if (headerParts.Length != 2)
11161 continue;
11162
11163 string headerName = headerParts[0].Trim();
11164 string headerValue = headerParts[1].Trim();
11165
11166 // Filter out headers that could be used to abuse
11167 // another system or cloak the request
11168 if (headerName.ToLower() == "x-secondlife-shard" ||
11169 headerName.ToLower() == "x-secondlife-object-name" ||
11170 headerName.ToLower() == "x-secondlife-object-key" ||
11171 headerName.ToLower() == "x-secondlife-region" ||
11172 headerName.ToLower() == "x-secondlife-local-position" ||
11173 headerName.ToLower() == "x-secondlife-local-velocity" ||
11174 headerName.ToLower() == "x-secondlife-local-rotation" ||
11175 headerName.ToLower() == "x-secondlife-owner-name" ||
11176 headerName.ToLower() == "x-secondlife-owner-key" ||
11177 headerName.ToLower() == "connection" ||
11178 headerName.ToLower() == "content-length" ||
11179 headerName.ToLower() == "from" ||
11180 headerName.ToLower() == "host" ||
11181 headerName.ToLower() == "proxy-authorization" ||
11182 headerName.ToLower() == "referer" ||
11183 headerName.ToLower() == "trailer" ||
11184 headerName.ToLower() == "transfer-encoding" ||
11185 headerName.ToLower() == "via" ||
11186 headerName.ToLower() == "authorization")
11187 continue;
11188
11189 httpHeaders[headerName] = headerValue;
11190 }
11191
11192 // Finally, strip any protocol specifier from the URL
11193 url = urlParts[0].Trim();
11194 int idx = url.IndexOf(" HTTP/");
11195 if (idx != -1)
11196 url = url.Substring(0, idx);
11197 }
11198
10309 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11199 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10310 Regex r = new Regex(authregex); 11200 Regex r = new Regex(authregex);
10311 int[] gnums = r.GetGroupNumbers(); 11201 int[] gnums = r.GetGroupNumbers();
10312 Match m = r.Match(url); 11202 Match m = r.Match(url);
10313 if (m.Success) { 11203 if (m.Success)
10314 for (int i = 1; i < gnums.Length; i++) { 11204 {
11205 for (int i = 1; i < gnums.Length; i++)
11206 {
10315 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11207 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10316 //CaptureCollection cc = g.Captures; 11208 //CaptureCollection cc = g.Captures;
10317 } 11209 }
10318 if (m.Groups.Count == 5) { 11210 if (m.Groups.Count == 5)
11211 {
10319 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11212 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10320 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11213 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10321 } 11214 }
@@ -10518,6 +11411,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10518 11411
10519 LSL_List ret = new LSL_List(); 11412 LSL_List ret = new LSL_List();
10520 UUID key = new UUID(); 11413 UUID key = new UUID();
11414
11415
10521 if (UUID.TryParse(id, out key)) 11416 if (UUID.TryParse(id, out key))
10522 { 11417 {
10523 ScenePresence av = World.GetScenePresence(key); 11418 ScenePresence av = World.GetScenePresence(key);
@@ -10535,13 +11430,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10535 ret.Add(new LSL_String("")); 11430 ret.Add(new LSL_String(""));
10536 break; 11431 break;
10537 case ScriptBaseClass.OBJECT_POS: 11432 case ScriptBaseClass.OBJECT_POS:
10538 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11433 Vector3 avpos;
11434
11435 if (av.ParentID != 0 && av.ParentPart != null)
11436 {
11437 avpos = av.OffsetPosition;
11438
11439 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11440 avpos -= sitOffset;
11441
11442 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11443 }
11444 else
11445 avpos = av.AbsolutePosition;
11446
11447 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10539 break; 11448 break;
10540 case ScriptBaseClass.OBJECT_ROT: 11449 case ScriptBaseClass.OBJECT_ROT:
10541 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11450 Quaternion avrot = av.Rotation;
11451 if (av.ParentID != 0 && av.ParentPart != null)
11452 {
11453 avrot = av.ParentPart.GetWorldRotation() * avrot;
11454 }
11455 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10542 break; 11456 break;
10543 case ScriptBaseClass.OBJECT_VELOCITY: 11457 case ScriptBaseClass.OBJECT_VELOCITY:
10544 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11458 Vector3 avvel = av.Velocity;
11459 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10545 break; 11460 break;
10546 case ScriptBaseClass.OBJECT_OWNER: 11461 case ScriptBaseClass.OBJECT_OWNER:
10547 ret.Add(new LSL_String(id)); 11462 ret.Add(new LSL_String(id));
@@ -10597,11 +11512,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10597 case ScriptBaseClass.OBJECT_NAME: 11512 case ScriptBaseClass.OBJECT_NAME:
10598 ret.Add(new LSL_String(obj.Name)); 11513 ret.Add(new LSL_String(obj.Name));
10599 break; 11514 break;
10600 case ScriptBaseClass.OBJECT_DESC: 11515 case ScriptBaseClass.OBJECT_DESC:
10601 ret.Add(new LSL_String(obj.Description)); 11516 ret.Add(new LSL_String(obj.Description));
10602 break; 11517 break;
10603 case ScriptBaseClass.OBJECT_POS: 11518 case ScriptBaseClass.OBJECT_POS:
10604 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11519 Vector3 opos = obj.AbsolutePosition;
11520 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10605 break; 11521 break;
10606 case ScriptBaseClass.OBJECT_ROT: 11522 case ScriptBaseClass.OBJECT_ROT:
10607 { 11523 {
@@ -10651,9 +11567,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 // The value returned in SL for normal prims is prim count 11567 // The value returned in SL for normal prims is prim count
10652 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11568 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10653 break; 11569 break;
10654 // The following 3 costs I have intentionaly coded to return zero. They are part of 11570
10655 // "Land Impact" calculations. These calculations are probably not applicable 11571 // costs below may need to be diferent for root parts, need to check
10656 // to OpenSim and are not yet complete in SL
10657 case ScriptBaseClass.OBJECT_SERVER_COST: 11572 case ScriptBaseClass.OBJECT_SERVER_COST:
10658 // The linden calculation is here 11573 // The linden calculation is here
10659 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11574 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10661,16 +11576,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10661 ret.Add(new LSL_Float(0)); 11576 ret.Add(new LSL_Float(0));
10662 break; 11577 break;
10663 case ScriptBaseClass.OBJECT_STREAMING_COST: 11578 case ScriptBaseClass.OBJECT_STREAMING_COST:
10664 // The linden calculation is here 11579 // The value returned in SL for normal prims is prim count * 0.06
10665 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11580 ret.Add(new LSL_Float(obj.StreamingCost));
10666 // The value returned in SL for normal prims looks like the prim count * 0.06
10667 ret.Add(new LSL_Float(0));
10668 break; 11581 break;
10669 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11582 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10670 // The linden calculation is here 11583 // The value returned in SL for normal prims is prim count
10671 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11584 ret.Add(new LSL_Float(obj.PhysicsCost));
10672 // The value returned in SL for normal prims looks like the prim count
10673 ret.Add(new LSL_Float(0));
10674 break; 11585 break;
10675 default: 11586 default:
10676 // Invalid or unhandled constant. 11587 // Invalid or unhandled constant.
@@ -10881,15 +11792,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10881 return result; 11792 return result;
10882 } 11793 }
10883 11794
10884 public void print(string str) 11795 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10885 { 11796 {
10886 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11797 List<SceneObjectPart> parts = GetLinkParts(link);
10887 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11798 if (parts.Count < 1)
10888 if (ossl != null) 11799 return 0;
10889 { 11800
10890 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11801 return GetNumberOfSides(parts[0]);
10891 m_log.Info("LSL print():" + str);
10892 }
10893 } 11802 }
10894 11803
10895 private string Name2Username(string name) 11804 private string Name2Username(string name)
@@ -10934,7 +11843,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10934 11843
10935 return rq.ToString(); 11844 return rq.ToString();
10936 } 11845 }
10937 11846/*
11847 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11848 {
11849 m_SayShoutCount = 0;
11850 }
11851*/
10938 private struct Tri 11852 private struct Tri
10939 { 11853 {
10940 public Vector3 p1; 11854 public Vector3 p1;
@@ -11074,9 +11988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11074 11988
11075 ContactResult result = new ContactResult (); 11989 ContactResult result = new ContactResult ();
11076 result.ConsumerID = group.LocalId; 11990 result.ConsumerID = group.LocalId;
11077 result.Depth = intersection.distance; 11991// result.Depth = intersection.distance;
11078 result.Normal = intersection.normal; 11992 result.Normal = intersection.normal;
11079 result.Pos = intersection.ipoint; 11993 result.Pos = intersection.ipoint;
11994 result.Depth = Vector3.Mag(rayStart - result.Pos);
11080 11995
11081 contacts.Add(result); 11996 contacts.Add(result);
11082 }); 11997 });
@@ -11209,6 +12124,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11209 12124
11210 return contacts[0]; 12125 return contacts[0];
11211 } 12126 }
12127/*
12128 // not done:
12129 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12130 {
12131 ContactResult[] contacts = null;
12132 World.ForEachSOG(delegate(SceneObjectGroup group)
12133 {
12134 if (m_host.ParentGroup == group)
12135 return;
12136
12137 if (group.IsAttachment)
12138 return;
12139
12140 if(group.RootPart.PhysActor != null)
12141 return;
12142
12143 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12144 });
12145 return contacts;
12146 }
12147*/
11212 12148
11213 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12149 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11214 { 12150 {
@@ -11250,32 +12186,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11250 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12186 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11251 12187
11252 12188
11253 if (checkTerrain) 12189 if (World.SuportsRayCastFiltered())
11254 { 12190 {
11255 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12191 if (dist == 0)
11256 if (groundContact != null) 12192 return list;
11257 results.Add((ContactResult)groundContact);
11258 }
11259 12193
11260 if (checkAgents) 12194 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11261 { 12195 if (checkTerrain)
11262 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12196 rayfilter |= RayFilterFlags.land;
11263 foreach (ContactResult r in agentHits) 12197// if (checkAgents)
11264 results.Add(r); 12198// rayfilter |= RayFilterFlags.agent;
11265 } 12199 if (checkPhysical)
12200 rayfilter |= RayFilterFlags.physical;
12201 if (checkNonPhysical)
12202 rayfilter |= RayFilterFlags.nonphysical;
12203 if (detectPhantom)
12204 rayfilter |= RayFilterFlags.LSLPhanton;
12205
12206 Vector3 direction = dir * ( 1/dist);
11266 12207
11267 if (checkPhysical || checkNonPhysical || detectPhantom) 12208 if(rayfilter == 0)
12209 {
12210 list.Add(new LSL_Integer(0));
12211 return list;
12212 }
12213
12214 // get some more contacts to sort ???
12215 int physcount = 4 * count;
12216 if (physcount > 20)
12217 physcount = 20;
12218
12219 object physresults;
12220 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12221
12222 if (physresults == null)
12223 {
12224 list.Add(new LSL_Integer(-3)); // timeout error
12225 return list;
12226 }
12227
12228 results = (List<ContactResult>)physresults;
12229
12230 // for now physics doesn't detect sitted avatars so do it outside physics
12231 if (checkAgents)
12232 {
12233 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12234 foreach (ContactResult r in agentHits)
12235 results.Add(r);
12236 }
12237
12238 // TODO: Replace this with a better solution. ObjectIntersection can only
12239 // detect nonphysical phantoms. They are detected by virtue of being
12240 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12241 // physicsl phantoms as done by the physics scene
12242 // We don't want anything else but phantoms here.
12243 if (detectPhantom)
12244 {
12245 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12246 foreach (ContactResult r in objectHits)
12247 results.Add(r);
12248 }
12249 }
12250 else
11268 { 12251 {
11269 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12252 if (checkTerrain)
11270 foreach (ContactResult r in objectHits) 12253 {
11271 results.Add(r); 12254 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12255 if (groundContact != null)
12256 results.Add((ContactResult)groundContact);
12257 }
12258
12259 if (checkAgents)
12260 {
12261 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12262 foreach (ContactResult r in agentHits)
12263 results.Add(r);
12264 }
12265
12266 if (checkPhysical || checkNonPhysical || detectPhantom)
12267 {
12268 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12269 foreach (ContactResult r in objectHits)
12270 results.Add(r);
12271 }
11272 } 12272 }
11273 12273
11274 results.Sort(delegate(ContactResult a, ContactResult b) 12274 results.Sort(delegate(ContactResult a, ContactResult b)
11275 { 12275 {
11276 return a.Depth.CompareTo(b.Depth); 12276 return a.Depth.CompareTo(b.Depth);
11277 }); 12277 });
11278 12278
11279 int values = 0; 12279 int values = 0;
11280 SceneObjectGroup thisgrp = m_host.ParentGroup; 12280 SceneObjectGroup thisgrp = m_host.ParentGroup;
11281 12281
@@ -11368,7 +12368,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11368 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12368 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11369 if (!isAccount) return 0; 12369 if (!isAccount) return 0;
11370 if (estate.HasAccess(id)) return 1; 12370 if (estate.HasAccess(id)) return 1;
11371 if (estate.IsBanned(id)) 12371 if (estate.IsBanned(id, World.GetUserFlags(id)))
11372 estate.RemoveBan(id); 12372 estate.RemoveBan(id);
11373 estate.AddEstateUser(id); 12373 estate.AddEstateUser(id);
11374 break; 12374 break;
@@ -11387,14 +12387,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11387 break; 12387 break;
11388 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12388 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11389 if (!isAccount) return 0; 12389 if (!isAccount) return 0;
11390 if (estate.IsBanned(id)) return 1; 12390 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11391 EstateBan ban = new EstateBan(); 12391 EstateBan ban = new EstateBan();
11392 ban.EstateID = estate.EstateID; 12392 ban.EstateID = estate.EstateID;
11393 ban.BannedUserID = id; 12393 ban.BannedUserID = id;
11394 estate.AddBan(ban); 12394 estate.AddBan(ban);
11395 break; 12395 break;
11396 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12396 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11397 if (!isAccount || !estate.IsBanned(id)) return 0; 12397 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11398 estate.RemoveBan(id); 12398 estate.RemoveBan(id);
11399 break; 12399 break;
11400 default: return 0; 12400 default: return 0;
@@ -11423,7 +12423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11423 return 16384; 12423 return 16384;
11424 } 12424 }
11425 12425
11426 public LSL_Integer llGetUsedMemory() 12426 public virtual LSL_Integer llGetUsedMemory()
11427 { 12427 {
11428 m_host.AddScriptLPS(1); 12428 m_host.AddScriptLPS(1);
11429 // The value returned for LSO scripts in SL 12429 // The value returned for LSO scripts in SL
@@ -11451,22 +12451,734 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11451 public void llSetSoundQueueing(int queue) 12451 public void llSetSoundQueueing(int queue)
11452 { 12452 {
11453 m_host.AddScriptLPS(1); 12453 m_host.AddScriptLPS(1);
11454 NotImplemented("llSetSoundQueueing");
11455 } 12454 }
11456 12455
11457 public void llCollisionSprite(string impact_sprite) 12456 public void llCollisionSprite(string impact_sprite)
11458 { 12457 {
11459 m_host.AddScriptLPS(1); 12458 m_host.AddScriptLPS(1);
11460 NotImplemented("llCollisionSprite"); 12459 // Viewer 2.0 broke this and it's likely LL has no intention
12460 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11461 } 12461 }
11462 12462
11463 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12463 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11464 { 12464 {
11465 m_host.AddScriptLPS(1); 12465 m_host.AddScriptLPS(1);
11466 NotImplemented("llGodLikeRezObject"); 12466
12467 if (!World.Permissions.IsGod(m_host.OwnerID))
12468 NotImplemented("llGodLikeRezObject");
12469
12470 AssetBase rezAsset = World.AssetService.Get(inventory);
12471 if (rezAsset == null)
12472 {
12473 llSay(0, "Asset not found");
12474 return;
12475 }
12476
12477 SceneObjectGroup group = null;
12478
12479 try
12480 {
12481 string xmlData = Utils.BytesToString(rezAsset.Data);
12482 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12483 }
12484 catch
12485 {
12486 llSay(0, "Asset not found");
12487 return;
12488 }
12489
12490 if (group == null)
12491 {
12492 llSay(0, "Asset not found");
12493 return;
12494 }
12495
12496 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12497 group.RootPart.AttachOffset = group.AbsolutePosition;
12498
12499 group.ResetIDs();
12500
12501 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12502 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12503 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12504 group.ScheduleGroupForFullUpdate();
12505
12506 // objects rezzed with this method are die_at_edge by default.
12507 group.RootPart.SetDieAtEdge(true);
12508
12509 group.ResumeScripts();
12510
12511 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12512 "object_rez", new Object[] {
12513 new LSL_String(
12514 group.RootPart.UUID.ToString()) },
12515 new DetectParams[0]));
12516 }
12517
12518 public LSL_String llTransferLindenDollars(string destination, int amount)
12519 {
12520 UUID txn = UUID.Random();
12521
12522 Util.FireAndForget(delegate(object x)
12523 {
12524 int replycode = 0;
12525 string replydata = destination + "," + amount.ToString();
12526
12527 try
12528 {
12529 TaskInventoryItem item = m_item;
12530 if (item == null)
12531 {
12532 replydata = "SERVICE_ERROR";
12533 return;
12534 }
12535
12536 m_host.AddScriptLPS(1);
12537
12538 if (item.PermsGranter == UUID.Zero)
12539 {
12540 replydata = "MISSING_PERMISSION_DEBIT";
12541 return;
12542 }
12543
12544 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12545 {
12546 replydata = "MISSING_PERMISSION_DEBIT";
12547 return;
12548 }
12549
12550 UUID toID = new UUID();
12551
12552 if (!UUID.TryParse(destination, out toID))
12553 {
12554 replydata = "INVALID_AGENT";
12555 return;
12556 }
12557
12558 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12559
12560 if (money == null)
12561 {
12562 replydata = "TRANSFERS_DISABLED";
12563 return;
12564 }
12565
12566 bool result = money.ObjectGiveMoney(
12567 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12568
12569 if (result)
12570 {
12571 replycode = 1;
12572 return;
12573 }
12574
12575 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12576 }
12577 finally
12578 {
12579 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12580 "transaction_result", new Object[] {
12581 new LSL_String(txn.ToString()),
12582 new LSL_Integer(replycode),
12583 new LSL_String(replydata) },
12584 new DetectParams[0]));
12585 }
12586 });
12587
12588 return txn.ToString();
11467 } 12589 }
11468 12590
11469 #endregion 12591 #endregion
12592
12593 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12594 {
12595 SceneObjectGroup group = m_host.ParentGroup;
12596
12597 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12598 return;
12599 if (group.IsAttachment)
12600 return;
12601
12602 if (frames.Data.Length > 0) // We are getting a new motion
12603 {
12604 if (group.RootPart.KeyframeMotion != null)
12605 group.RootPart.KeyframeMotion.Delete();
12606 group.RootPart.KeyframeMotion = null;
12607
12608 int idx = 0;
12609
12610 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12611 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12612
12613 while (idx < options.Data.Length)
12614 {
12615 int option = (int)options.GetLSLIntegerItem(idx++);
12616 int remain = options.Data.Length - idx;
12617
12618 switch (option)
12619 {
12620 case ScriptBaseClass.KFM_MODE:
12621 if (remain < 1)
12622 break;
12623 int modeval = (int)options.GetLSLIntegerItem(idx++);
12624 switch(modeval)
12625 {
12626 case ScriptBaseClass.KFM_FORWARD:
12627 mode = KeyframeMotion.PlayMode.Forward;
12628 break;
12629 case ScriptBaseClass.KFM_REVERSE:
12630 mode = KeyframeMotion.PlayMode.Reverse;
12631 break;
12632 case ScriptBaseClass.KFM_LOOP:
12633 mode = KeyframeMotion.PlayMode.Loop;
12634 break;
12635 case ScriptBaseClass.KFM_PING_PONG:
12636 mode = KeyframeMotion.PlayMode.PingPong;
12637 break;
12638 }
12639 break;
12640 case ScriptBaseClass.KFM_DATA:
12641 if (remain < 1)
12642 break;
12643 int dataval = (int)options.GetLSLIntegerItem(idx++);
12644 data = (KeyframeMotion.DataFormat)dataval;
12645 break;
12646 }
12647 }
12648
12649 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12650
12651 idx = 0;
12652
12653 int elemLength = 2;
12654 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12655 elemLength = 3;
12656
12657 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12658 while (idx < frames.Data.Length)
12659 {
12660 int remain = frames.Data.Length - idx;
12661
12662 if (remain < elemLength)
12663 break;
12664
12665 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12666 frame.Position = null;
12667 frame.Rotation = null;
12668
12669 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12670 {
12671 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12672 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12673 }
12674 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12675 {
12676 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12677 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12678 }
12679
12680 float tempf = (float)frames.GetLSLFloatItem(idx++);
12681 frame.TimeMS = (int)(tempf * 1000.0f);
12682
12683 keyframes.Add(frame);
12684 }
12685
12686 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12687 group.RootPart.KeyframeMotion.Start();
12688 }
12689 else
12690 {
12691 if (group.RootPart.KeyframeMotion == null)
12692 return;
12693
12694 if (options.Data.Length == 0)
12695 {
12696 group.RootPart.KeyframeMotion.Stop();
12697 return;
12698 }
12699
12700 int code = (int)options.GetLSLIntegerItem(0);
12701
12702 int idx = 0;
12703
12704 while (idx < options.Data.Length)
12705 {
12706 int option = (int)options.GetLSLIntegerItem(idx++);
12707 int remain = options.Data.Length - idx;
12708
12709 switch (option)
12710 {
12711 case ScriptBaseClass.KFM_COMMAND:
12712 int cmd = (int)options.GetLSLIntegerItem(idx++);
12713 switch (cmd)
12714 {
12715 case ScriptBaseClass.KFM_CMD_PLAY:
12716 group.RootPart.KeyframeMotion.Start();
12717 break;
12718 case ScriptBaseClass.KFM_CMD_STOP:
12719 group.RootPart.KeyframeMotion.Stop();
12720 break;
12721 case ScriptBaseClass.KFM_CMD_PAUSE:
12722 group.RootPart.KeyframeMotion.Pause();
12723 break;
12724 }
12725 break;
12726 }
12727 }
12728 }
12729 }
12730
12731 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12732 {
12733 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12734
12735 int idx = 0;
12736 int idxStart = 0;
12737
12738 bool positionChanged = false;
12739 Vector3 finalPos = Vector3.Zero;
12740
12741 try
12742 {
12743 while (idx < rules.Length)
12744 {
12745 ++rulesParsed;
12746 int code = rules.GetLSLIntegerItem(idx++);
12747
12748 int remain = rules.Length - idx;
12749 idxStart = idx;
12750
12751 switch (code)
12752 {
12753 case (int)ScriptBaseClass.PRIM_POSITION:
12754 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12755 {
12756 if (remain < 1)
12757 return null;
12758
12759 LSL_Vector v;
12760 v = rules.GetVector3Item(idx++);
12761
12762 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12763 if (part == null)
12764 break;
12765
12766 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12767 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12768 if (part.LinkNum > 1)
12769 {
12770 localRot = GetPartLocalRot(part);
12771 localPos = GetPartLocalPos(part);
12772 }
12773
12774 v -= localPos;
12775 v /= localRot;
12776
12777 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12778
12779 v = v + 2 * sitOffset;
12780
12781 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12782 av.SendAvatarDataToAllAgents();
12783
12784 }
12785 break;
12786
12787 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12788 case (int)ScriptBaseClass.PRIM_ROTATION:
12789 {
12790 if (remain < 1)
12791 return null;
12792
12793 LSL_Rotation r;
12794 r = rules.GetQuaternionItem(idx++);
12795
12796 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12797 if (part == null)
12798 break;
12799
12800 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12801 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12802
12803 if (part.LinkNum > 1)
12804 localRot = GetPartLocalRot(part);
12805
12806 r = r * llGetRootRotation() / localRot;
12807 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12808 av.SendAvatarDataToAllAgents();
12809 }
12810 break;
12811
12812 // parse rest doing nothing but number of parameters error check
12813 case (int)ScriptBaseClass.PRIM_SIZE:
12814 case (int)ScriptBaseClass.PRIM_MATERIAL:
12815 case (int)ScriptBaseClass.PRIM_PHANTOM:
12816 case (int)ScriptBaseClass.PRIM_PHYSICS:
12817 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12818 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12819 case (int)ScriptBaseClass.PRIM_NAME:
12820 case (int)ScriptBaseClass.PRIM_DESC:
12821 if (remain < 1)
12822 return null;
12823 idx++;
12824 break;
12825
12826 case (int)ScriptBaseClass.PRIM_GLOW:
12827 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12828 case (int)ScriptBaseClass.PRIM_TEXGEN:
12829 if (remain < 2)
12830 return null;
12831 idx += 2;
12832 break;
12833
12834 case (int)ScriptBaseClass.PRIM_TYPE:
12835 if (remain < 3)
12836 return null;
12837 code = (int)rules.GetLSLIntegerItem(idx++);
12838 remain = rules.Length - idx;
12839 switch (code)
12840 {
12841 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12842 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12843 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12844 if (remain < 6)
12845 return null;
12846 idx += 6;
12847 break;
12848
12849 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12850 if (remain < 5)
12851 return null;
12852 idx += 5;
12853 break;
12854
12855 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12856 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12857 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12858 if (remain < 11)
12859 return null;
12860 idx += 11;
12861 break;
12862
12863 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12864 if (remain < 2)
12865 return null;
12866 idx += 2;
12867 break;
12868 }
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_COLOR:
12872 case (int)ScriptBaseClass.PRIM_TEXT:
12873 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12874 case (int)ScriptBaseClass.PRIM_OMEGA:
12875 if (remain < 3)
12876 return null;
12877 idx += 3;
12878 break;
12879
12880 case (int)ScriptBaseClass.PRIM_TEXTURE:
12881 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12882 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12883 if (remain < 5)
12884 return null;
12885 idx += 5;
12886 break;
12887
12888 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12889 if (remain < 7)
12890 return null;
12891
12892 idx += 7;
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12896 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12897 return null;
12898
12899 return rules.GetSublist(idx, -1);
12900 }
12901 }
12902 }
12903 catch (InvalidCastException e)
12904 {
12905 ShoutError(string.Format(
12906 "{0} error running rule #{1}: arg #{2} ",
12907 originFunc, rulesParsed, idx - idxStart) + e.Message);
12908 }
12909 finally
12910 {
12911 if (positionChanged)
12912 {
12913 av.OffsetPosition = finalPos;
12914// av.SendAvatarDataToAllAgents();
12915 av.SendTerseUpdateToAllClients();
12916 positionChanged = false;
12917 }
12918 }
12919 return null;
12920 }
12921
12922 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12923 {
12924 // avatars case
12925 // replies as SL wiki
12926
12927// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12928 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12929
12930 int idx = 0;
12931 while (idx < rules.Length)
12932 {
12933 int code = (int)rules.GetLSLIntegerItem(idx++);
12934 int remain = rules.Length - idx;
12935
12936 switch (code)
12937 {
12938 case (int)ScriptBaseClass.PRIM_MATERIAL:
12939 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12940 break;
12941
12942 case (int)ScriptBaseClass.PRIM_PHYSICS:
12943 res.Add(new LSL_Integer(0));
12944 break;
12945
12946 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12947 res.Add(new LSL_Integer(0));
12948 break;
12949
12950 case (int)ScriptBaseClass.PRIM_PHANTOM:
12951 res.Add(new LSL_Integer(0));
12952 break;
12953
12954 case (int)ScriptBaseClass.PRIM_POSITION:
12955
12956 Vector3 pos = avatar.OffsetPosition;
12957
12958 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12959 pos -= sitOffset;
12960
12961 if( sitPart != null)
12962 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12963
12964 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12965 break;
12966
12967 case (int)ScriptBaseClass.PRIM_SIZE:
12968 // as in llGetAgentSize above
12969// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12970 Vector3 s = avatar.Appearance.AvatarSize;
12971 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
12972
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_ROTATION:
12976 Quaternion rot = avatar.Rotation;
12977 if (sitPart != null)
12978 {
12979 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12980 }
12981
12982 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12983 break;
12984
12985 case (int)ScriptBaseClass.PRIM_TYPE:
12986 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12987 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12988 res.Add(new LSL_Vector(0f,1.0f,0f));
12989 res.Add(new LSL_Float(0.0f));
12990 res.Add(new LSL_Vector(0, 0, 0));
12991 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12992 res.Add(new LSL_Vector(0, 0, 0));
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_TEXTURE:
12996 if (remain < 1)
12997 return null;
12998
12999 int face = (int)rules.GetLSLIntegerItem(idx++);
13000 if (face == ScriptBaseClass.ALL_SIDES)
13001 {
13002 for (face = 0; face < 21; face++)
13003 {
13004 res.Add(new LSL_String(""));
13005 res.Add(new LSL_Vector(0,0,0));
13006 res.Add(new LSL_Vector(0,0,0));
13007 res.Add(new LSL_Float(0.0));
13008 }
13009 }
13010 else
13011 {
13012 if (face >= 0 && face < 21)
13013 {
13014 res.Add(new LSL_String(""));
13015 res.Add(new LSL_Vector(0,0,0));
13016 res.Add(new LSL_Vector(0,0,0));
13017 res.Add(new LSL_Float(0.0));
13018 }
13019 }
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_COLOR:
13023 if (remain < 1)
13024 return null;
13025
13026 face = (int)rules.GetLSLIntegerItem(idx++);
13027
13028 if (face == ScriptBaseClass.ALL_SIDES)
13029 {
13030 for (face = 0; face < 21; face++)
13031 {
13032 res.Add(new LSL_Vector(0,0,0));
13033 res.Add(new LSL_Float(0));
13034 }
13035 }
13036 else
13037 {
13038 res.Add(new LSL_Vector(0,0,0));
13039 res.Add(new LSL_Float(0));
13040 }
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13044 if (remain < 1)
13045 return null;
13046 face = (int)rules.GetLSLIntegerItem(idx++);
13047
13048 if (face == ScriptBaseClass.ALL_SIDES)
13049 {
13050 for (face = 0; face < 21; face++)
13051 {
13052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13054 }
13055 }
13056 else
13057 {
13058 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13059 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13060 }
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13064 if (remain < 1)
13065 return null;
13066 face = (int)rules.GetLSLIntegerItem(idx++);
13067
13068 if (face == ScriptBaseClass.ALL_SIDES)
13069 {
13070 for (face = 0; face < 21; face++)
13071 {
13072 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13073 }
13074 }
13075 else
13076 {
13077 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13078 }
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13082 res.Add(new LSL_Integer(0));
13083 res.Add(new LSL_Integer(0));// softness
13084 res.Add(new LSL_Float(0.0f)); // gravity
13085 res.Add(new LSL_Float(0.0f)); // friction
13086 res.Add(new LSL_Float(0.0f)); // wind
13087 res.Add(new LSL_Float(0.0f)); // tension
13088 res.Add(new LSL_Vector(0f,0f,0f));
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_TEXGEN:
13092 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13093 if (remain < 1)
13094 return null;
13095 face = (int)rules.GetLSLIntegerItem(idx++);
13096
13097 if (face == ScriptBaseClass.ALL_SIDES)
13098 {
13099 for (face = 0; face < 21; face++)
13100 {
13101 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13102 }
13103 }
13104 else
13105 {
13106 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13107 }
13108 break;
13109
13110 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13111 res.Add(new LSL_Integer(0));
13112 res.Add(new LSL_Vector(0f,0f,0f));
13113 res.Add(new LSL_Float(0f)); // intensity
13114 res.Add(new LSL_Float(0f)); // radius
13115 res.Add(new LSL_Float(0f)); // falloff
13116 break;
13117
13118 case (int)ScriptBaseClass.PRIM_GLOW:
13119 if (remain < 1)
13120 return null;
13121 face = (int)rules.GetLSLIntegerItem(idx++);
13122
13123 if (face == ScriptBaseClass.ALL_SIDES)
13124 {
13125 for (face = 0; face < 21; face++)
13126 {
13127 res.Add(new LSL_Float(0f));
13128 }
13129 }
13130 else
13131 {
13132 res.Add(new LSL_Float(0f));
13133 }
13134 break;
13135
13136 case (int)ScriptBaseClass.PRIM_TEXT:
13137 res.Add(new LSL_String(""));
13138 res.Add(new LSL_Vector(0f,0f,0f));
13139 res.Add(new LSL_Float(1.0f));
13140 break;
13141
13142 case (int)ScriptBaseClass.PRIM_NAME:
13143 res.Add(new LSL_String(avatar.Name));
13144 break;
13145
13146 case (int)ScriptBaseClass.PRIM_DESC:
13147 res.Add(new LSL_String(""));
13148 break;
13149
13150 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13151 Quaternion lrot = avatar.Rotation;
13152
13153 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13154 {
13155 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13156 }
13157 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13158 break;
13159
13160 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13161 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13162 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13163 lpos -= lsitOffset;
13164
13165 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13166 {
13167 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13168 }
13169 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13170 break;
13171
13172 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13173 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13174 return null;
13175
13176 return rules.GetSublist(idx, -1);
13177 }
13178 }
13179
13180 return null;
13181 }
11470 } 13182 }
11471 13183
11472 public class NotecardCache 13184 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 98f8be7..9bf6f9b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,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);
@@ -356,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
356 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
357 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
358 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
359 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
360 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
361 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
362 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
363 LSL_Integer llSetRegionPos(LSL_Vector pos);
364 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
365 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
366 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -380,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
380 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
381 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
382 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
383 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
384 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
385 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -423,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
423 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
424 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
425 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
426 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
427 432
428 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
430 } 436 }
431} 437}
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 36803a4..8ecc4f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -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);
@@ -1608,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1608 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1609 } 1626 }
1610 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1611 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1612 { 1634 {
1613 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1623,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1623 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1624 } 1646 }
1625 1647
1626 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1627 {
1628 return m_LSL_Functions.llSetRegionPos(pos);
1629 }
1630
1631 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1632 { 1649 {
1633 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1723,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1723 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1724 } 1741 }
1725 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1726 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1727 { 1749 {
1728 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1973,9 +1995,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1973 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1974 } 1996 }
1975 1997
1976 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1977 { 2009 {
1978 m_LSL_Functions.print(str); 2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1979 } 2011 }
1980 } 2012 }
1981} 2013}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 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 01a5e34..ff4d130 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;
@@ -232,13 +233,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
232 233
233 if (part != null) 234 if (part != null)
234 { 235 {
235 lock (part.TaskInventory) 236 part.TaskInventory.LockItemsForRead(true);
237 if (part.TaskInventory.ContainsKey(ItemID))
236 { 238 {
237 if (part.TaskInventory.ContainsKey(ItemID)) 239 ScriptTask = part.TaskInventory[ItemID];
238 {
239 ScriptTask = part.TaskInventory[ItemID];
240 }
241 } 240 }
241 part.TaskInventory.LockItemsForRead(false);
242 } 242 }
243 243
244 ApiManager am = new ApiManager(); 244 ApiManager am = new ApiManager();
@@ -430,14 +430,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
430 { 430 {
431 int permsMask; 431 int permsMask;
432 UUID permsGranter; 432 UUID permsGranter;
433 lock (part.TaskInventory) 433 part.TaskInventory.LockItemsForRead(true);
434 if (!part.TaskInventory.ContainsKey(ItemID))
434 { 435 {
435 if (!part.TaskInventory.ContainsKey(ItemID)) 436 part.TaskInventory.LockItemsForRead(false);
436 return; 437 return;
437
438 permsGranter = part.TaskInventory[ItemID].PermsGranter;
439 permsMask = part.TaskInventory[ItemID].PermsMask;
440 } 438 }
439 permsGranter = part.TaskInventory[ItemID].PermsGranter;
440 permsMask = part.TaskInventory[ItemID].PermsMask;
441 part.TaskInventory.LockItemsForRead(false);
441 442
442 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 443 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
443 { 444 {
@@ -565,6 +566,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
565 return true; 566 return true;
566 } 567 }
567 568
569 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
568 public void SetState(string state) 570 public void SetState(string state)
569 { 571 {
570 if (state == State) 572 if (state == State)
@@ -576,7 +578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
576 new DetectParams[0])); 578 new DetectParams[0]));
577 PostEvent(new EventParams("state_entry", new Object[0], 579 PostEvent(new EventParams("state_entry", new Object[0],
578 new DetectParams[0])); 580 new DetectParams[0]));
579 581
580 throw new EventAbortException(); 582 throw new EventAbortException();
581 } 583 }
582 584
@@ -666,46 +668,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
666 /// <returns></returns> 668 /// <returns></returns>
667 public object EventProcessor() 669 public object EventProcessor()
668 { 670 {
671 EventParams data = null;
669 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 672 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
670 if (!Running) 673 if (!Running)
671 return 0; 674 return 0;
672 675
673 lock (m_Script)
674 {
675// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 676// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
676 677
677 if (Suspended) 678 if (Suspended)
678 return 0; 679 return 0;
679
680 EventParams data = null;
681 680
682 lock (EventQueue) 681 lock (EventQueue)
682 {
683 data = (EventParams) EventQueue.Dequeue();
684 if (data == null) // Shouldn't happen
683 { 685 {
684 data = (EventParams)EventQueue.Dequeue(); 686 if (EventQueue.Count > 0 && Running && !ShuttingDown)
685 if (data == null) // Shouldn't happen
686 { 687 {
687 if (EventQueue.Count > 0 && Running && !ShuttingDown) 688 m_CurrentWorkItem = Engine.QueueEventHandler(this);
688 {
689 m_CurrentWorkItem = Engine.QueueEventHandler(this);
690 }
691 else
692 {
693 m_CurrentWorkItem = null;
694 }
695 return 0;
696 } 689 }
697 690 else
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 { 691 {
702 if (m_ControlEventsInQueue > 0) 692 m_CurrentWorkItem = null;
703 m_ControlEventsInQueue--;
704 } 693 }
705 if (data.EventName == "collision") 694 return 0;
706 m_CollisionInQueue = false; 695 }
696
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 {
701 if (m_ControlEventsInQueue > 0)
702 m_ControlEventsInQueue--;
707 } 703 }
704 if (data.EventName == "collision")
705 m_CollisionInQueue = false;
706 }
708 707
708 lock(m_Script)
709 {
710
711// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 712 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
710 713
711 if (DebugLevel >= 2) 714 if (DebugLevel >= 2)
@@ -891,6 +894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 894 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
892 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 895 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
893 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 896 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
897 part.CollisionSound = UUID.Zero;
894 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 898 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
895 EventQueue.Clear(); 899 EventQueue.Clear();
896 m_Script.ResetVars(); 900 m_Script.ResetVars();
@@ -905,6 +909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
905 new Object[0], new DetectParams[0])); 909 new Object[0], new DetectParams[0]));
906 } 910 }
907 911
912 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
908 public void ApiResetScript() 913 public void ApiResetScript()
909 { 914 {
910 // bool running = Running; 915 // bool running = Running;
@@ -916,6 +921,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
916 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 921 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
917 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 922 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
918 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 923 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
924 part.CollisionSound = UUID.Zero;
919 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 925 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
920 926
921 EventQueue.Clear(); 927 EventQueue.Clear();
@@ -936,10 +942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
936 942
937 public Dictionary<string, object> GetVars() 943 public Dictionary<string, object> GetVars()
938 { 944 {
939 if (m_Script != null) 945 return m_Script.GetVars();
940 return m_Script.GetVars();
941 else
942 return new Dictionary<string, object>();
943 } 946 }
944 947
945 public void SetVars(Dictionary<string, object> vars) 948 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 79cec04..05dd7ab 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Linq; 34using System.Linq;
@@ -147,6 +148,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
147 private Dictionary<UUID, IScriptInstance> m_Scripts = 148 private Dictionary<UUID, IScriptInstance> m_Scripts =
148 new Dictionary<UUID, IScriptInstance>(); 149 new Dictionary<UUID, IScriptInstance>();
149 150
151 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152
150 // Maps the asset ID to the assembly 153 // Maps the asset ID to the assembly
151 154
152 private Dictionary<UUID, string> m_Assemblies = 155 private Dictionary<UUID, string> m_Assemblies =
@@ -169,6 +172,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
169 IWorkItemResult m_CurrentCompile = null; 172 IWorkItemResult m_CurrentCompile = null;
170 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 173 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
171 174
175 private void lockScriptsForRead(bool locked)
176 {
177 if (locked)
178 {
179 if (m_scriptsLock.RecursiveReadCount > 0)
180 {
181 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.");
182 m_scriptsLock.ExitReadLock();
183 }
184 if (m_scriptsLock.RecursiveWriteCount > 0)
185 {
186 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
187 m_scriptsLock.ExitWriteLock();
188 }
189
190 while (!m_scriptsLock.TryEnterReadLock(60000))
191 {
192 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.");
193 if (m_scriptsLock.IsWriteLockHeld)
194 {
195 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
196 }
197 }
198 }
199 else
200 {
201 if (m_scriptsLock.RecursiveReadCount > 0)
202 {
203 m_scriptsLock.ExitReadLock();
204 }
205 }
206 }
207 private void lockScriptsForWrite(bool locked)
208 {
209 if (locked)
210 {
211 if (m_scriptsLock.RecursiveReadCount > 0)
212 {
213 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.");
214 m_scriptsLock.ExitReadLock();
215 }
216 if (m_scriptsLock.RecursiveWriteCount > 0)
217 {
218 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
219 m_scriptsLock.ExitWriteLock();
220 }
221
222 while (!m_scriptsLock.TryEnterWriteLock(60000))
223 {
224 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.");
225 if (m_scriptsLock.IsWriteLockHeld)
226 {
227 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
228 }
229 }
230 }
231 else
232 {
233 if (m_scriptsLock.RecursiveWriteCount > 0)
234 {
235 m_scriptsLock.ExitWriteLock();
236 }
237 }
238 }
239
172 public string ScriptEngineName 240 public string ScriptEngineName
173 { 241 {
174 get { return "XEngine"; } 242 get { return "XEngine"; }
@@ -670,64 +738,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
670 { 738 {
671 if (!m_Enabled) 739 if (!m_Enabled)
672 return; 740 return;
741 lockScriptsForRead(true);
673 742
674 lock (m_Scripts) 743 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
675 {
676 m_log.InfoFormat(
677 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
678 744
679 foreach (IScriptInstance instance in m_Scripts.Values) 745// foreach (IScriptInstance instance in m_Scripts.Values)
746 foreach (IScriptInstance instance in instancesToDel)
747 {
748 // Force a final state save
749 //
750 if (m_Assemblies.ContainsKey(instance.AssetID))
680 { 751 {
681 // Force a final state save 752 string assembly = m_Assemblies[instance.AssetID];
682 //
683 if (m_Assemblies.ContainsKey(instance.AssetID))
684 {
685 string assembly = m_Assemblies[instance.AssetID];
686 753
687 try 754 try
688 { 755 {
689 instance.SaveState(assembly); 756 instance.SaveState(assembly);
690 }
691 catch (Exception e)
692 {
693 m_log.Error(
694 string.Format(
695 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
696 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
697 , e);
698 }
699 } 757 }
758 catch (Exception e)
759 {
760 m_log.Error(
761 string.Format(
762 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
763 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
764 , e);
765 }
766 }
700 767
701 // Clear the event queue and abort the instance thread 768 // Clear the event queue and abort the instance thread
702 // 769 //
703 instance.ClearQueue(); 770 instance.ClearQueue();
704 instance.Stop(0); 771 instance.Stop(0);
705 772
706 // Release events, timer, etc 773 // Release events, timer, etc
707 // 774 //
708 instance.DestroyScriptInstance(); 775 instance.DestroyScriptInstance();
709 776
710 // Unload scripts and app domains. 777 // Unload scripts and app domains
711 // Must be done explicitly because they have infinite 778 // Must be done explicitly because they have infinite
712 // lifetime. 779 // lifetime
713 // However, don't bother to do this if the simulator is shutting 780 //
714 // down since it takes a long time with many scripts. 781// if (!m_SimulatorShuttingDown)
715 if (!m_SimulatorShuttingDown) 782 {
783 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
784 if (m_DomainScripts[instance.AppDomain].Count == 0)
716 { 785 {
717 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 786 m_DomainScripts.Remove(instance.AppDomain);
718 if (m_DomainScripts[instance.AppDomain].Count == 0) 787 UnloadAppDomain(instance.AppDomain);
719 {
720 m_DomainScripts.Remove(instance.AppDomain);
721 UnloadAppDomain(instance.AppDomain);
722 }
723 } 788 }
724 } 789 }
725 790
726 m_Scripts.Clear(); 791// m_Scripts.Clear();
727 m_PrimObjects.Clear(); 792// m_PrimObjects.Clear();
728 m_Assemblies.Clear(); 793// m_Assemblies.Clear();
729 m_DomainScripts.Clear(); 794// m_DomainScripts.Clear();
730 } 795 }
796 lockScriptsForRead(false);
797 lockScriptsForWrite(true);
798 m_Scripts.Clear();
799 lockScriptsForWrite(false);
800 m_PrimObjects.Clear();
801 m_Assemblies.Clear();
802 m_DomainScripts.Clear();
803
731 lock (m_ScriptEngines) 804 lock (m_ScriptEngines)
732 { 805 {
733 m_ScriptEngines.Remove(this); 806 m_ScriptEngines.Remove(this);
@@ -796,22 +869,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
796 869
797 List<IScriptInstance> instances = new List<IScriptInstance>(); 870 List<IScriptInstance> instances = new List<IScriptInstance>();
798 871
799 lock (m_Scripts) 872 lockScriptsForRead(true);
800 { 873 foreach (IScriptInstance instance in m_Scripts.Values)
801 foreach (IScriptInstance instance in m_Scripts.Values)
802 instances.Add(instance); 874 instances.Add(instance);
803 } 875 lockScriptsForRead(false);
804 876
805 foreach (IScriptInstance i in instances) 877 foreach (IScriptInstance i in instances)
806 { 878 {
807 string assembly = String.Empty; 879 string assembly = String.Empty;
808 880
809 lock (m_Scripts) 881
810 {
811 if (!m_Assemblies.ContainsKey(i.AssetID)) 882 if (!m_Assemblies.ContainsKey(i.AssetID))
812 continue; 883 continue;
813 assembly = m_Assemblies[i.AssetID]; 884 assembly = m_Assemblies[i.AssetID];
814 } 885
815 886
816 try 887 try
817 { 888 {
@@ -1212,96 +1283,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1212 } 1283 }
1213 1284
1214 ScriptInstance instance = null; 1285 ScriptInstance instance = null;
1215 lock (m_Scripts) 1286 // Create the object record
1287 lockScriptsForRead(true);
1288 if ((!m_Scripts.ContainsKey(itemID)) ||
1289 (m_Scripts[itemID].AssetID != assetID))
1216 { 1290 {
1217 // Create the object record 1291 lockScriptsForRead(false);
1218 if ((!m_Scripts.ContainsKey(itemID)) ||
1219 (m_Scripts[itemID].AssetID != assetID))
1220 {
1221 UUID appDomain = assetID;
1222 1292
1223 if (part.ParentGroup.IsAttachment) 1293 UUID appDomain = assetID;
1224 appDomain = part.ParentGroup.RootPart.UUID;
1225 1294
1226 if (!m_AppDomains.ContainsKey(appDomain)) 1295 if (part.ParentGroup.IsAttachment)
1227 { 1296 appDomain = part.ParentGroup.RootPart.UUID;
1228 try
1229 {
1230 AppDomainSetup appSetup = new AppDomainSetup();
1231 appSetup.PrivateBinPath = Path.Combine(
1232 m_ScriptEnginesPath,
1233 m_Scene.RegionInfo.RegionID.ToString());
1234 1297
1235 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1298 if (!m_AppDomains.ContainsKey(appDomain))
1236 Evidence evidence = new Evidence(baseEvidence); 1299 {
1300 try
1301 {
1302 AppDomainSetup appSetup = new AppDomainSetup();
1303 appSetup.PrivateBinPath = Path.Combine(
1304 m_ScriptEnginesPath,
1305 m_Scene.RegionInfo.RegionID.ToString());
1237 1306
1238 AppDomain sandbox; 1307 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1239 if (m_AppDomainLoading) 1308 Evidence evidence = new Evidence(baseEvidence);
1240 {
1241 sandbox = AppDomain.CreateDomain(
1242 m_Scene.RegionInfo.RegionID.ToString(),
1243 evidence, appSetup);
1244 sandbox.AssemblyResolve +=
1245 new ResolveEventHandler(
1246 AssemblyResolver.OnAssemblyResolve);
1247 }
1248 else
1249 {
1250 sandbox = AppDomain.CurrentDomain;
1251 }
1252
1253 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1254 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1255 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1256 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1257 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1258 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1259 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1260
1261 m_AppDomains[appDomain] = sandbox;
1262 1309
1263 m_DomainScripts[appDomain] = new List<UUID>(); 1310 AppDomain sandbox;
1311 if (m_AppDomainLoading)
1312 {
1313 sandbox = AppDomain.CreateDomain(
1314 m_Scene.RegionInfo.RegionID.ToString(),
1315 evidence, appSetup);
1316 m_AppDomains[appDomain].AssemblyResolve +=
1317 new ResolveEventHandler(
1318 AssemblyResolver.OnAssemblyResolve);
1264 } 1319 }
1265 catch (Exception e) 1320 else
1266 { 1321 {
1267 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1322 sandbox = AppDomain.CurrentDomain;
1268 m_ScriptErrorMessage += "Exception creating app domain:\n";
1269 m_ScriptFailCount++;
1270 lock (m_AddingAssemblies)
1271 {
1272 m_AddingAssemblies[assembly]--;
1273 }
1274 return false;
1275 } 1323 }
1276 }
1277 m_DomainScripts[appDomain].Add(itemID);
1278
1279 instance = new ScriptInstance(this, part,
1280 itemID, assetID, assembly,
1281 m_AppDomains[appDomain],
1282 part.ParentGroup.RootPart.Name,
1283 item.Name, startParam, postOnRez,
1284 stateSource, m_MaxScriptQueue);
1285
1286// if (DebugLevel >= 1)
1287// m_log.DebugFormat(
1288// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1289// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1290// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1291 1324
1292 if (presence != null) 1325 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1326 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1327 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1328 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1329 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1330 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1331 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1332
1333 m_AppDomains[appDomain] = sandbox;
1334
1335 m_DomainScripts[appDomain] = new List<UUID>();
1336 }
1337 catch (Exception e)
1293 { 1338 {
1294 ShowScriptSaveResponse(item.OwnerID, 1339 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1295 assetID, "Compile successful", true); 1340 m_ScriptErrorMessage += "Exception creating app domain:\n";
1341 m_ScriptFailCount++;
1342 lock (m_AddingAssemblies)
1343 {
1344 m_AddingAssemblies[assembly]--;
1345 }
1346 return false;
1296 } 1347 }
1348 }
1349 m_DomainScripts[appDomain].Add(itemID);
1350
1351 instance = new ScriptInstance(this, part,
1352 itemID, assetID, assembly,
1353 m_AppDomains[appDomain],
1354 part.ParentGroup.RootPart.Name,
1355 item.Name, startParam, postOnRez,
1356 stateSource, m_MaxScriptQueue);
1357
1358// m_log.DebugFormat(
1359// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1360// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1361// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1297 1362
1298 instance.AppDomain = appDomain; 1363 if (presence != null)
1299 instance.LineMap = linemap; 1364 {
1300 1365 ShowScriptSaveResponse(item.OwnerID,
1301 m_Scripts[itemID] = instance; 1366 assetID, "Compile successful", true);
1302 } 1367 }
1303 }
1304 1368
1369 instance.AppDomain = appDomain;
1370 instance.LineMap = linemap;
1371 lockScriptsForWrite(true);
1372 m_Scripts[itemID] = instance;
1373 lockScriptsForWrite(false);
1374 }
1375 else
1376 {
1377 lockScriptsForRead(false);
1378 }
1305 lock (m_PrimObjects) 1379 lock (m_PrimObjects)
1306 { 1380 {
1307 if (!m_PrimObjects.ContainsKey(localID)) 1381 if (!m_PrimObjects.ContainsKey(localID))
@@ -1319,7 +1393,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1319 m_AddingAssemblies[assembly]--; 1393 m_AddingAssemblies[assembly]--;
1320 } 1394 }
1321 1395
1322 if (instance != null) 1396 if (instance!=null)
1323 instance.Init(); 1397 instance.Init();
1324 1398
1325 bool runIt; 1399 bool runIt;
@@ -1342,18 +1416,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1342 m_CompileDict.Remove(itemID); 1416 m_CompileDict.Remove(itemID);
1343 } 1417 }
1344 1418
1345 IScriptInstance instance = null; 1419 lockScriptsForRead(true);
1346 1420 // Do we even have it?
1347 lock (m_Scripts) 1421 if (!m_Scripts.ContainsKey(itemID))
1348 { 1422 {
1349 // Do we even have it? 1423 // Do we even have it?
1350 if (!m_Scripts.ContainsKey(itemID)) 1424 if (!m_Scripts.ContainsKey(itemID))
1351 return; 1425 return;
1352 1426
1353 instance = m_Scripts[itemID]; 1427 lockScriptsForRead(false);
1428 lockScriptsForWrite(true);
1354 m_Scripts.Remove(itemID); 1429 m_Scripts.Remove(itemID);
1430 lockScriptsForWrite(false);
1431
1432 return;
1355 } 1433 }
1434
1356 1435
1436 IScriptInstance instance=m_Scripts[itemID];
1437 lockScriptsForRead(false);
1438 lockScriptsForWrite(true);
1439 m_Scripts.Remove(itemID);
1440 lockScriptsForWrite(false);
1357 instance.ClearQueue(); 1441 instance.ClearQueue();
1358 1442
1359 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1443 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1390,8 +1474,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1390 1474
1391 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1475 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1392 if (handlerObjectRemoved != null) 1476 if (handlerObjectRemoved != null)
1393 handlerObjectRemoved(instance.ObjectID); 1477 {
1478 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1479 handlerObjectRemoved(part.UUID);
1480 }
1394 1481
1482 CleanAssemblies();
1483
1395 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1484 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1396 if (handlerScriptRemoved != null) 1485 if (handlerScriptRemoved != null)
1397 handlerScriptRemoved(itemID); 1486 handlerScriptRemoved(itemID);
@@ -1652,12 +1741,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1652 private IScriptInstance GetInstance(UUID itemID) 1741 private IScriptInstance GetInstance(UUID itemID)
1653 { 1742 {
1654 IScriptInstance instance; 1743 IScriptInstance instance;
1655 lock (m_Scripts) 1744 lockScriptsForRead(true);
1745 if (!m_Scripts.ContainsKey(itemID))
1656 { 1746 {
1657 if (!m_Scripts.ContainsKey(itemID)) 1747 lockScriptsForRead(false);
1658 return null; 1748 return null;
1659 instance = m_Scripts[itemID];
1660 } 1749 }
1750 instance = m_Scripts[itemID];
1751 lockScriptsForRead(false);
1661 return instance; 1752 return instance;
1662 } 1753 }
1663 1754
@@ -1681,6 +1772,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1681 return false; 1772 return false;
1682 } 1773 }
1683 1774
1775 [DebuggerNonUserCode]
1684 public void ApiResetScript(UUID itemID) 1776 public void ApiResetScript(UUID itemID)
1685 { 1777 {
1686 IScriptInstance instance = GetInstance(itemID); 1778 IScriptInstance instance = GetInstance(itemID);
@@ -1737,6 +1829,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1737 return UUID.Zero; 1829 return UUID.Zero;
1738 } 1830 }
1739 1831
1832 [DebuggerNonUserCode]
1740 public void SetState(UUID itemID, string newState) 1833 public void SetState(UUID itemID, string newState)
1741 { 1834 {
1742 IScriptInstance instance = GetInstance(itemID); 1835 IScriptInstance instance = GetInstance(itemID);
@@ -1759,11 +1852,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1759 1852
1760 List<IScriptInstance> instances = new List<IScriptInstance>(); 1853 List<IScriptInstance> instances = new List<IScriptInstance>();
1761 1854
1762 lock (m_Scripts) 1855 lockScriptsForRead(true);
1763 { 1856 foreach (IScriptInstance instance in m_Scripts.Values)
1764 foreach (IScriptInstance instance in m_Scripts.Values)
1765 instances.Add(instance); 1857 instances.Add(instance);
1766 } 1858 lockScriptsForRead(false);
1767 1859
1768 foreach (IScriptInstance i in instances) 1860 foreach (IScriptInstance i in instances)
1769 { 1861 {