aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-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.cs3220
-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
18 files changed, 3030 insertions, 900 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 837779d..30bacc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -104,16 +108,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
110 protected ISoundModule m_SoundModule = null; 116 protected ISoundModule m_SoundModule = null;
111 117
118// protected Timer m_ShoutSayTimer;
119 protected int m_SayShoutCount = 0;
120 DateTime m_lastSayShoutCheck;
121
122 private Dictionary<string, string> MovementAnimationsForLSL =
123 new Dictionary<string, string> {
124 {"FLY", "Flying"},
125 {"FLYSLOW", "FlyingSlow"},
126 {"HOVER_UP", "Hovering Up"},
127 {"HOVER_DOWN", "Hovering Down"},
128 {"HOVER", "Hovering"},
129 {"LAND", "Landing"},
130 {"FALLDOWN", "Falling Down"},
131 {"PREJUMP", "PreJumping"},
132 {"JUMP", "Jumping"},
133 {"STANDUP", "Standing Up"},
134 {"SOFT_LAND", "Soft Landing"},
135 {"STAND", "Standing"},
136 {"CROUCHWALK", "CrouchWalking"},
137 {"RUN", "Running"},
138 {"WALK", "Walking"},
139 {"CROUCH", "Crouching"},
140 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"}
142 };
143
112 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
113 { 145 {
146/*
147 m_ShoutSayTimer = new Timer(1000);
148 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
149 m_ShoutSayTimer.AutoReset = true;
150 m_ShoutSayTimer.Start();
151*/
152 m_lastSayShoutCheck = DateTime.UtcNow;
153
114 m_ScriptEngine = ScriptEngine; 154 m_ScriptEngine = ScriptEngine;
115 m_host = host; 155 m_host = host;
116 m_item = item; 156 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
117 158
118 LoadLimits(); // read script limits from config. 159 LoadLimits(); // read script limits from config.
119 160
@@ -174,6 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
174 get { return m_ScriptEngine.World; } 215 get { return m_ScriptEngine.World; }
175 } 216 }
176 217
218 [DebuggerNonUserCode]
177 public void state(string newState) 219 public void state(string newState)
178 { 220 {
179 m_ScriptEngine.SetState(m_item.ItemID, newState); 221 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -183,6 +225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
183 /// Reset the named script. The script must be present 225 /// Reset the named script. The script must be present
184 /// in the same prim. 226 /// in the same prim.
185 /// </summary> 227 /// </summary>
228 [DebuggerNonUserCode]
186 public void llResetScript() 229 public void llResetScript()
187 { 230 {
188 m_host.AddScriptLPS(1); 231 m_host.AddScriptLPS(1);
@@ -245,6 +288,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
245 } 288 }
246 } 289 }
247 290
291 public List<ScenePresence> GetLinkAvatars(int linkType)
292 {
293 List<ScenePresence> ret = new List<ScenePresence>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
296
297 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
298
299 switch (linkType)
300 {
301 case ScriptBaseClass.LINK_SET:
302 return avs;
303
304 case ScriptBaseClass.LINK_ROOT:
305 return ret;
306
307 case ScriptBaseClass.LINK_ALL_OTHERS:
308 return avs;
309
310 case ScriptBaseClass.LINK_ALL_CHILDREN:
311 return avs;
312
313 case ScriptBaseClass.LINK_THIS:
314 return ret;
315
316 default:
317 if (linkType < 0)
318 return ret;
319
320 int partCount = m_host.ParentGroup.GetPartCount();
321
322 if (linkType <= partCount)
323 {
324 return ret;
325 }
326 else
327 {
328 linkType = linkType - partCount;
329 if (linkType > avs.Count)
330 {
331 return ret;
332 }
333 else
334 {
335 ret.Add(avs[linkType-1]);
336 return ret;
337 }
338 }
339 }
340 }
341
248 public List<SceneObjectPart> GetLinkParts(int linkType) 342 public List<SceneObjectPart> GetLinkParts(int linkType)
249 { 343 {
250 return GetLinkParts(m_host, linkType); 344 return GetLinkParts(m_host, linkType);
@@ -253,6 +347,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
253 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 347 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
254 { 348 {
255 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 349 List<SceneObjectPart> ret = new List<SceneObjectPart>();
350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
351 return ret;
256 ret.Add(part); 352 ret.Add(part);
257 353
258 switch (linkType) 354 switch (linkType)
@@ -479,31 +575,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
479 575
480 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 576 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
481 577
482 /// <summary> 578 // Utility function for llRot2Euler
483 /// Convert an LSL rotation to a Euler vector. 579
484 /// </summary> 580 // normalize an angle between -PI and PI (-180 to +180 degrees)
485 /// <remarks> 581 protected double NormalizeAngle(double angle)
486 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
487 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
488 /// </remarks>
489 /// <param name="r"></param>
490 /// <returns></returns>
491 public LSL_Vector llRot2Euler(LSL_Rotation r)
492 { 582 {
493 m_host.AddScriptLPS(1); 583 if (angle > -Math.PI && angle < Math.PI)
584 return angle;
494 585
495 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 586 int numPis = (int)(Math.PI / angle);
496 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 587 double remainder = angle - Math.PI * numPis;
497 if (m == 0.0) return new LSL_Vector(); 588 if (numPis % 2 == 1)
498 double x = Math.Atan2(-v.y, v.z); 589 return Math.PI - angle;
499 double sin = v.x / m; 590 return remainder;
500 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 591 }
501 double y = Math.Asin(sin);
502 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
503 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
504 double z = Math.Atan2(v.y, v.x);
505 592
506 return new LSL_Vector(x, y, z); 593 public LSL_Vector llRot2Euler(LSL_Rotation q1)
594 {
595 m_host.AddScriptLPS(1);
596 LSL_Vector eul = new LSL_Vector();
597
598 double sqw = q1.s*q1.s;
599 double sqx = q1.x*q1.x;
600 double sqy = q1.z*q1.z;
601 double sqz = q1.y*q1.y;
602 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
603 double test = q1.x*q1.z + q1.y*q1.s;
604 if (test > 0.4999*unit) { // singularity at north pole
605 eul.z = 2 * Math.Atan2(q1.x,q1.s);
606 eul.y = Math.PI/2;
607 eul.x = 0;
608 return eul;
609 }
610 if (test < -0.4999*unit) { // singularity at south pole
611 eul.z = -2 * Math.Atan2(q1.x,q1.s);
612 eul.y = -Math.PI/2;
613 eul.x = 0;
614 return eul;
615 }
616 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
617 eul.y = Math.Asin(2*test/unit);
618 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
619 return eul;
507 } 620 }
508 621
509 /* From wiki: 622 /* From wiki:
@@ -556,18 +669,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
556 m_host.AddScriptLPS(1); 669 m_host.AddScriptLPS(1);
557 670
558 double x,y,z,s; 671 double x,y,z,s;
559 672 v.x *= 0.5;
560 double c1 = Math.Cos(v.x * 0.5); 673 v.y *= 0.5;
561 double c2 = Math.Cos(v.y * 0.5); 674 v.z *= 0.5;
562 double c3 = Math.Cos(v.z * 0.5); 675 double c1 = Math.Cos(v.x);
563 double s1 = Math.Sin(v.x * 0.5); 676 double c2 = Math.Cos(v.y);
564 double s2 = Math.Sin(v.y * 0.5); 677 double c1c2 = c1 * c2;
565 double s3 = Math.Sin(v.z * 0.5); 678 double s1 = Math.Sin(v.x);
566 679 double s2 = Math.Sin(v.y);
567 x = s1 * c2 * c3 + c1 * s2 * s3; 680 double s1s2 = s1 * s2;
568 y = c1 * s2 * c3 - s1 * c2 * s3; 681 double c1s2 = c1 * s2;
569 z = s1 * s2 * c3 + c1 * c2 * s3; 682 double s1c2 = s1 * c2;
570 s = c1 * c2 * c3 - s1 * s2 * s3; 683 double c3 = Math.Cos(v.z);
684 double s3 = Math.Sin(v.z);
685
686 x = s1c2 * c3 + c1s2 * s3;
687 y = c1s2 * c3 - s1c2 * s3;
688 z = s1s2 * c3 + c1c2 * s3;
689 s = c1c2 * c3 - s1s2 * s3;
571 690
572 return new LSL_Rotation(x, y, z, s); 691 return new LSL_Rotation(x, y, z, s);
573 } 692 }
@@ -705,77 +824,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 824 {
706 //A and B should both be normalized 825 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 826 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 827 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 828 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 829
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 830 double dotProduct = LSL_Vector.Dot(a, b);
831 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
832 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
833 double angle = Math.Acos(dotProduct / magProduct);
834 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
835 double s = Math.Sin(angle / 2);
836
837 double x = axis.x * s;
838 double y = axis.y * s;
839 double z = axis.z * s;
840 double w = Math.Cos(angle / 2);
841
842 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
844
845 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
846 */
847
848 // This method mimics the 180 errors found in SL
849 // See www.euclideanspace.com... angleBetween
850 LSL_Vector vec_a = a;
851 LSL_Vector vec_b = b;
852
853 // Eliminate zero length
854 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
855 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
856 if (vec_a_mag < 0.00001 ||
857 vec_b_mag < 0.00001)
712 { 858 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 859 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 860 }
715 else 861
862 // Normalize
863 vec_a = llVecNorm(vec_a);
864 vec_b = llVecNorm(vec_b);
865
866 // Calculate axis and rotation angle
867 LSL_Vector axis = vec_a % vec_b;
868 LSL_Float cos_theta = vec_a * vec_b;
869
870 // Check if parallel
871 if (cos_theta > 0.99999)
716 { 872 {
717 a = LSL_Vector.Norm(a); 873 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 874 }
719 double dotProduct = LSL_Vector.Dot(a, b); 875
720 // There are two degenerate cases possible. These are for vectors 180 or 876 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 877 else if (cos_theta < -0.99999)
722 // 878 {
723 // Check for vectors 180 degrees apart. 879 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 880 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 881 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 882 }
727 // First assume X axis is orthogonal to the vectors. 883 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 884 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 885 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 886 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 887 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 888 s = Math.Cos(theta);
733 { 889 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 890 x = axis.x * t;
735 } 891 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 892 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 893 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 894 }
776 return rotBetween;
777 } 895 }
778 896
779 public void llWhisper(int channelID, string text) 897 public void llWhisper(int channelID, string text)
780 { 898 {
781 m_host.AddScriptLPS(1); 899 m_host.AddScriptLPS(1);
@@ -791,10 +909,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
791 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 909 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
792 } 910 }
793 911
912 private void CheckSayShoutTime()
913 {
914 DateTime now = DateTime.UtcNow;
915 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
916 {
917 m_lastSayShoutCheck = now;
918 m_SayShoutCount = 0;
919 }
920 else
921 m_SayShoutCount++;
922 }
923
794 public void llSay(int channelID, string text) 924 public void llSay(int channelID, string text)
795 { 925 {
796 m_host.AddScriptLPS(1); 926 m_host.AddScriptLPS(1);
797 927
928 if (channelID == 0)
929// m_SayShoutCount++;
930 CheckSayShoutTime();
931
932 if (m_SayShoutCount >= 11)
933 ScriptSleep(2000);
934
798 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 935 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
799 { 936 {
800 Console.WriteLine(text); 937 Console.WriteLine(text);
@@ -817,6 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 { 954 {
818 m_host.AddScriptLPS(1); 955 m_host.AddScriptLPS(1);
819 956
957 if (channelID == 0)
958// m_SayShoutCount++;
959 CheckSayShoutTime();
960
961 if (m_SayShoutCount >= 11)
962 ScriptSleep(2000);
963
820 if (text.Length > 1023) 964 if (text.Length > 1023)
821 text = text.Substring(0, 1023); 965 text = text.Substring(0, 1023);
822 966
@@ -848,22 +992,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 992
849 public void llRegionSayTo(string target, int channel, string msg) 993 public void llRegionSayTo(string target, int channel, string msg)
850 { 994 {
995 string error = String.Empty;
996
851 if (msg.Length > 1023) 997 if (msg.Length > 1023)
852 msg = msg.Substring(0, 1023); 998 msg = msg.Substring(0, 1023);
853 999
854 m_host.AddScriptLPS(1); 1000 m_host.AddScriptLPS(1);
855 1001
856 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
857 {
858 return;
859 }
860
861 UUID TargetID; 1002 UUID TargetID;
862 UUID.TryParse(target, out TargetID); 1003 UUID.TryParse(target, out TargetID);
863 1004
864 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1005 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
865 if (wComm != null) 1006 if (wComm != null)
866 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1007 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1008 LSLError(error);
867 } 1009 }
868 1010
869 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1011 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1119,10 +1261,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1119 return detectedParams.TouchUV; 1261 return detectedParams.TouchUV;
1120 } 1262 }
1121 1263
1264 [DebuggerNonUserCode]
1122 public virtual void llDie() 1265 public virtual void llDie()
1123 { 1266 {
1124 m_host.AddScriptLPS(1); 1267 m_host.AddScriptLPS(1);
1125 throw new SelfDeleteException(); 1268 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1126 } 1269 }
1127 1270
1128 public LSL_Float llGround(LSL_Vector offset) 1271 public LSL_Float llGround(LSL_Vector offset)
@@ -1193,6 +1336,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1193 1336
1194 public void llSetStatus(int status, int value) 1337 public void llSetStatus(int status, int value)
1195 { 1338 {
1339 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1340 return;
1196 m_host.AddScriptLPS(1); 1341 m_host.AddScriptLPS(1);
1197 1342
1198 int statusrotationaxis = 0; 1343 int statusrotationaxis = 0;
@@ -1216,6 +1361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1216 if (!allow) 1361 if (!allow)
1217 return; 1362 return;
1218 1363
1364 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1365 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1366 return;
1367
1219 m_host.ScriptSetPhysicsStatus(true); 1368 m_host.ScriptSetPhysicsStatus(true);
1220 } 1369 }
1221 else 1370 else
@@ -1416,6 +1565,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 { 1565 {
1417 m_host.AddScriptLPS(1); 1566 m_host.AddScriptLPS(1);
1418 1567
1568 SetColor(m_host, color, face);
1569 }
1570
1571 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1572 {
1573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1574 return;
1575
1576 Primitive.TextureEntry tex = part.Shape.Textures;
1577 Color4 texcolor;
1578 if (face >= 0 && face < GetNumberOfSides(part))
1579 {
1580 texcolor = tex.CreateFace((uint)face).RGBA;
1581 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1582 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1583 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1584 tex.FaceTextures[face].RGBA = texcolor;
1585 part.UpdateTextureEntry(tex.GetBytes());
1586 return;
1587 }
1588 else if (face == ScriptBaseClass.ALL_SIDES)
1589 {
1590 for (uint i = 0; i < GetNumberOfSides(part); i++)
1591 {
1592 if (tex.FaceTextures[i] != null)
1593 {
1594 texcolor = tex.FaceTextures[i].RGBA;
1595 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1596 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1597 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1598 tex.FaceTextures[i].RGBA = texcolor;
1599 }
1600 texcolor = tex.DefaultTexture.RGBA;
1601 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1602 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1603 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1604 tex.DefaultTexture.RGBA = texcolor;
1605 }
1606 part.UpdateTextureEntry(tex.GetBytes());
1607 return;
1608 }
1609
1419 if (face == ScriptBaseClass.ALL_SIDES) 1610 if (face == ScriptBaseClass.ALL_SIDES)
1420 face = SceneObjectPart.ALL_SIDES; 1611 face = SceneObjectPart.ALL_SIDES;
1421 1612
@@ -1424,6 +1615,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1424 1615
1425 public void SetTexGen(SceneObjectPart part, int face,int style) 1616 public void SetTexGen(SceneObjectPart part, int face,int style)
1426 { 1617 {
1618 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1619 return;
1620
1427 Primitive.TextureEntry tex = part.Shape.Textures; 1621 Primitive.TextureEntry tex = part.Shape.Textures;
1428 MappingType textype; 1622 MappingType textype;
1429 textype = MappingType.Default; 1623 textype = MappingType.Default;
@@ -1454,6 +1648,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1454 1648
1455 public void SetGlow(SceneObjectPart part, int face, float glow) 1649 public void SetGlow(SceneObjectPart part, int face, float glow)
1456 { 1650 {
1651 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1652 return;
1653
1457 Primitive.TextureEntry tex = part.Shape.Textures; 1654 Primitive.TextureEntry tex = part.Shape.Textures;
1458 if (face >= 0 && face < GetNumberOfSides(part)) 1655 if (face >= 0 && face < GetNumberOfSides(part))
1459 { 1656 {
@@ -1479,6 +1676,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1479 1676
1480 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1677 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1481 { 1678 {
1679 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1680 return;
1482 1681
1483 Shininess sval = new Shininess(); 1682 Shininess sval = new Shininess();
1484 1683
@@ -1529,6 +1728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1529 1728
1530 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1729 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1531 { 1730 {
1731 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1732 return;
1733
1532 Primitive.TextureEntry tex = part.Shape.Textures; 1734 Primitive.TextureEntry tex = part.Shape.Textures;
1533 if (face >= 0 && face < GetNumberOfSides(part)) 1735 if (face >= 0 && face < GetNumberOfSides(part))
1534 { 1736 {
@@ -1589,13 +1791,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1589 m_host.AddScriptLPS(1); 1791 m_host.AddScriptLPS(1);
1590 1792
1591 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1793 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1592 1794 if (parts.Count > 0)
1593 foreach (SceneObjectPart part in parts) 1795 {
1594 SetAlpha(part, alpha, face); 1796 try
1797 {
1798 foreach (SceneObjectPart part in parts)
1799 SetAlpha(part, alpha, face);
1800 }
1801 finally
1802 {
1803 }
1804 }
1595 } 1805 }
1596 1806
1597 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1807 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1598 { 1808 {
1809 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1810 return;
1811
1599 Primitive.TextureEntry tex = part.Shape.Textures; 1812 Primitive.TextureEntry tex = part.Shape.Textures;
1600 Color4 texcolor; 1813 Color4 texcolor;
1601 if (face >= 0 && face < GetNumberOfSides(part)) 1814 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1648,7 +1861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1648 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1861 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1649 float wind, float tension, LSL_Vector Force) 1862 float wind, float tension, LSL_Vector Force)
1650 { 1863 {
1651 if (part == null) 1864 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1652 return; 1865 return;
1653 1866
1654 if (flexi) 1867 if (flexi)
@@ -1682,7 +1895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1682 /// <param name="falloff"></param> 1895 /// <param name="falloff"></param>
1683 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1896 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1684 { 1897 {
1685 if (part == null) 1898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1686 return; 1899 return;
1687 1900
1688 if (light) 1901 if (light)
@@ -1715,11 +1928,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 Primitive.TextureEntry tex = part.Shape.Textures; 1928 Primitive.TextureEntry tex = part.Shape.Textures;
1716 Color4 texcolor; 1929 Color4 texcolor;
1717 LSL_Vector rgb = new LSL_Vector(); 1930 LSL_Vector rgb = new LSL_Vector();
1931 int nsides = GetNumberOfSides(part);
1932
1718 if (face == ScriptBaseClass.ALL_SIDES) 1933 if (face == ScriptBaseClass.ALL_SIDES)
1719 { 1934 {
1720 int i; 1935 int i;
1721 1936 for (i = 0; i < nsides; i++)
1722 for (i = 0 ; i < GetNumberOfSides(part); i++)
1723 { 1937 {
1724 texcolor = tex.GetFace((uint)i).RGBA; 1938 texcolor = tex.GetFace((uint)i).RGBA;
1725 rgb.x += texcolor.R; 1939 rgb.x += texcolor.R;
@@ -1727,14 +1941,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1727 rgb.z += texcolor.B; 1941 rgb.z += texcolor.B;
1728 } 1942 }
1729 1943
1730 rgb.x /= (float)GetNumberOfSides(part); 1944 float invnsides = 1.0f / (float)nsides;
1731 rgb.y /= (float)GetNumberOfSides(part); 1945
1732 rgb.z /= (float)GetNumberOfSides(part); 1946 rgb.x *= invnsides;
1947 rgb.y *= invnsides;
1948 rgb.z *= invnsides;
1733 1949
1734 return rgb; 1950 return rgb;
1735 } 1951 }
1736 1952 if (face >= 0 && face < nsides)
1737 if (face >= 0 && face < GetNumberOfSides(part))
1738 { 1953 {
1739 texcolor = tex.GetFace((uint)face).RGBA; 1954 texcolor = tex.GetFace((uint)face).RGBA;
1740 rgb.x = texcolor.R; 1955 rgb.x = texcolor.R;
@@ -1761,15 +1976,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1761 m_host.AddScriptLPS(1); 1976 m_host.AddScriptLPS(1);
1762 1977
1763 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1978 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1764 1979 if (parts.Count > 0)
1765 foreach (SceneObjectPart part in parts) 1980 {
1766 SetTexture(part, texture, face); 1981 try
1767 1982 {
1983 foreach (SceneObjectPart part in parts)
1984 SetTexture(part, texture, face);
1985 }
1986 finally
1987 {
1988 }
1989 }
1768 ScriptSleep(200); 1990 ScriptSleep(200);
1769 } 1991 }
1770 1992
1771 protected void SetTexture(SceneObjectPart part, string texture, int face) 1993 protected void SetTexture(SceneObjectPart part, string texture, int face)
1772 { 1994 {
1995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1996 return;
1997
1773 UUID textureID = new UUID(); 1998 UUID textureID = new UUID();
1774 1999
1775 textureID = InventoryKey(texture, (int)AssetType.Texture); 2000 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1814,6 +2039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 2039
1815 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2040 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1816 { 2041 {
2042 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2043 return;
2044
1817 Primitive.TextureEntry tex = part.Shape.Textures; 2045 Primitive.TextureEntry tex = part.Shape.Textures;
1818 if (face >= 0 && face < GetNumberOfSides(part)) 2046 if (face >= 0 && face < GetNumberOfSides(part))
1819 { 2047 {
@@ -1850,6 +2078,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1850 2078
1851 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2079 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1852 { 2080 {
2081 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2082 return;
2083
1853 Primitive.TextureEntry tex = part.Shape.Textures; 2084 Primitive.TextureEntry tex = part.Shape.Textures;
1854 if (face >= 0 && face < GetNumberOfSides(part)) 2085 if (face >= 0 && face < GetNumberOfSides(part))
1855 { 2086 {
@@ -1886,6 +2117,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1886 2117
1887 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2118 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1888 { 2119 {
2120 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2121 return;
2122
1889 Primitive.TextureEntry tex = part.Shape.Textures; 2123 Primitive.TextureEntry tex = part.Shape.Textures;
1890 if (face >= 0 && face < GetNumberOfSides(part)) 2124 if (face >= 0 && face < GetNumberOfSides(part))
1891 { 2125 {
@@ -2056,24 +2290,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2056 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2290 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2057 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2291 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2058 { 2292 {
2059 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2293 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2294 return;
2295
2060 LSL_Vector currentPos = GetPartLocalPos(part); 2296 LSL_Vector currentPos = GetPartLocalPos(part);
2297 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2061 2298
2062 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2063 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2064 2299
2065 if (part.ParentGroup.RootPart == part) 2300 if (part.ParentGroup.RootPart == part)
2066 { 2301 {
2067 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2068 targetPos.z = ground;
2069 SceneObjectGroup parent = part.ParentGroup; 2302 SceneObjectGroup parent = part.ParentGroup;
2070 parent.UpdateGroupPosition(!adjust ? targetPos : 2303 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2071 SetPosAdjust(currentPos, targetPos)); 2304 return;
2305 Util.FireAndForget(delegate(object x) {
2306 parent.UpdateGroupPosition((Vector3)toPos);
2307 });
2072 } 2308 }
2073 else 2309 else
2074 { 2310 {
2075 part.OffsetPosition = !adjust ? targetPos : 2311 part.OffsetPosition = (Vector3)toPos;
2076 SetPosAdjust(currentPos, targetPos);
2077 SceneObjectGroup parent = part.ParentGroup; 2312 SceneObjectGroup parent = part.ParentGroup;
2078 parent.HasGroupChanged = true; 2313 parent.HasGroupChanged = true;
2079 parent.ScheduleGroupForTerseUpdate(); 2314 parent.ScheduleGroupForTerseUpdate();
@@ -2105,13 +2340,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2105 else 2340 else
2106 { 2341 {
2107 if (part.ParentGroup.IsAttachment) 2342 if (part.ParentGroup.IsAttachment)
2108 {
2109 pos = part.AttachedPos; 2343 pos = part.AttachedPos;
2110 }
2111 else 2344 else
2112 {
2113 pos = part.AbsolutePosition; 2345 pos = part.AbsolutePosition;
2114 }
2115 } 2346 }
2116 2347
2117// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2348// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2151,25 +2382,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2151 2382
2152 protected void SetRot(SceneObjectPart part, Quaternion rot) 2383 protected void SetRot(SceneObjectPart part, Quaternion rot)
2153 { 2384 {
2154 part.UpdateRotation(rot); 2385 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2155 // Update rotation does not move the object in the physics scene if it's a linkset. 2386 return;
2156 2387
2157//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2388 bool isroot = (part == part.ParentGroup.RootPart);
2158// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2389 bool isphys;
2159 2390
2160 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2161 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2162 // It's perfectly okay when the object is not an active physical body though.
2163 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2164 // but only if the object is not physial and active. This is important for rotating doors.
2165 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2166 // scene
2167 PhysicsActor pa = part.PhysActor; 2391 PhysicsActor pa = part.PhysActor;
2168 2392
2169 if (pa != null && !pa.IsPhysical) 2393 // keep using physactor ideia of isphysical
2394 // it should be SOP ideia of that
2395 // not much of a issue with ubitODE
2396 if (pa != null && pa.IsPhysical)
2397 isphys = true;
2398 else
2399 isphys = false;
2400
2401 // SL doesn't let scripts rotate root of physical linksets
2402 if (isroot && isphys)
2403 return;
2404
2405 part.UpdateRotation(rot);
2406
2407 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2408 // so do a nasty update of parts positions if is a root part rotation
2409 if (isroot && pa != null) // with if above implies non physical root part
2170 { 2410 {
2171 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2411 part.ParentGroup.ResetChildPrimPhysicsPositions();
2172 } 2412 }
2413 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2414 {
2415 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2416 if (sittingavas.Count > 0)
2417 {
2418 foreach (ScenePresence av in sittingavas)
2419 {
2420 if (isroot || part.LocalId == av.ParentID)
2421 av.SendTerseUpdateToAllClients();
2422 }
2423 }
2424 }
2173 } 2425 }
2174 2426
2175 /// <summary> 2427 /// <summary>
@@ -2217,8 +2469,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2217 2469
2218 public LSL_Rotation llGetLocalRot() 2470 public LSL_Rotation llGetLocalRot()
2219 { 2471 {
2472 return GetPartLocalRot(m_host);
2473 }
2474
2475 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2476 {
2220 m_host.AddScriptLPS(1); 2477 m_host.AddScriptLPS(1);
2221 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2478 Quaternion rot = part.RotationOffset;
2479 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2222 } 2480 }
2223 2481
2224 public void llSetForce(LSL_Vector force, int local) 2482 public void llSetForce(LSL_Vector force, int local)
@@ -2298,16 +2556,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2298 m_host.ApplyImpulse(v, local != 0); 2556 m_host.ApplyImpulse(v, local != 0);
2299 } 2557 }
2300 2558
2559
2301 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2560 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2302 { 2561 {
2303 m_host.AddScriptLPS(1); 2562 m_host.AddScriptLPS(1);
2304 m_host.ApplyAngularImpulse(force, local != 0); 2563 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2305 } 2564 }
2306 2565
2307 public void llSetTorque(LSL_Vector torque, int local) 2566 public void llSetTorque(LSL_Vector torque, int local)
2308 { 2567 {
2309 m_host.AddScriptLPS(1); 2568 m_host.AddScriptLPS(1);
2310 m_host.SetAngularImpulse(torque, local != 0); 2569 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2311 } 2570 }
2312 2571
2313 public LSL_Vector llGetTorque() 2572 public LSL_Vector llGetTorque()
@@ -2324,20 +2583,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2324 llSetTorque(torque, local); 2583 llSetTorque(torque, local);
2325 } 2584 }
2326 2585
2586 public void llSetVelocity(LSL_Vector vel, int local)
2587 {
2588 m_host.AddScriptLPS(1);
2589 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2590 }
2591
2327 public LSL_Vector llGetVel() 2592 public LSL_Vector llGetVel()
2328 { 2593 {
2329 m_host.AddScriptLPS(1); 2594 m_host.AddScriptLPS(1);
2330 2595
2331 Vector3 vel; 2596 Vector3 vel = Vector3.Zero;
2332 2597
2333 if (m_host.ParentGroup.IsAttachment) 2598 if (m_host.ParentGroup.IsAttachment)
2334 { 2599 {
2335 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2600 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2336 vel = avatar.Velocity; 2601 if (avatar != null)
2602 vel = avatar.Velocity;
2337 } 2603 }
2338 else 2604 else
2339 { 2605 {
2340 vel = m_host.Velocity; 2606 vel = m_host.ParentGroup.RootPart.Velocity;
2341 } 2607 }
2342 2608
2343 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2609 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2349,10 +2615,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2349 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2615 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2350 } 2616 }
2351 2617
2618 public void llSetAngularVelocity(LSL_Vector avel, int local)
2619 {
2620 m_host.AddScriptLPS(1);
2621 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2622 }
2623
2352 public LSL_Vector llGetOmega() 2624 public LSL_Vector llGetOmega()
2353 { 2625 {
2354 m_host.AddScriptLPS(1); 2626 m_host.AddScriptLPS(1);
2355 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2627 Vector3 avel = m_host.AngularVelocity;
2628 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2356 } 2629 }
2357 2630
2358 public LSL_Float llGetTimeOfDay() 2631 public LSL_Float llGetTimeOfDay()
@@ -2741,7 +3014,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2741 } 3014 }
2742 3015
2743 bool result = money.ObjectGiveMoney( 3016 bool result = money.ObjectGiveMoney(
2744 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3017 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2745 3018
2746 if (result) 3019 if (result)
2747 return 1; 3020 return 1;
@@ -2825,16 +3098,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2825 new_group.RootPart.UUID.ToString()) }, 3098 new_group.RootPart.UUID.ToString()) },
2826 new DetectParams[0])); 3099 new DetectParams[0]));
2827 3100
2828 float groupmass = new_group.GetMass(); 3101 // do recoil
3102 SceneObjectGroup hostgrp = m_host.ParentGroup;
3103 if (hostgrp == null)
3104 return;
3105
3106 if (hostgrp.IsAttachment) // don't recoil avatars
3107 return;
2829 3108
2830 PhysicsActor pa = new_group.RootPart.PhysActor; 3109 PhysicsActor pa = new_group.RootPart.PhysActor;
2831 3110
2832 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3111 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2833 { 3112 {
2834 //Recoil. 3113 float groupmass = new_group.GetMass();
2835 llApplyImpulse(vel * groupmass, 0); 3114 vel *= -groupmass;
3115 llApplyImpulse(vel, 0);
2836 } 3116 }
2837 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3117 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3118 return;
3119
2838 }); 3120 });
2839 3121
2840 //ScriptSleep((int)((groupmass * velmag) / 10)); 3122 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2849,35 +3131,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2849 public void llLookAt(LSL_Vector target, double strength, double damping) 3131 public void llLookAt(LSL_Vector target, double strength, double damping)
2850 { 3132 {
2851 m_host.AddScriptLPS(1); 3133 m_host.AddScriptLPS(1);
2852 // Determine where we are looking from
2853 LSL_Vector from = llGetPos();
2854 3134
2855 // Work out the normalised vector from the source to the target 3135 // Get the normalized vector to the target
2856 LSL_Vector delta = llVecNorm(target - from); 3136 LSL_Vector d1 = llVecNorm(target - llGetPos());
2857 LSL_Vector angle = new LSL_Vector(0,0,0);
2858 3137
2859 // Calculate the yaw 3138 // Get the bearing (yaw)
2860 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3139 LSL_Vector a1 = new LSL_Vector(0,0,0);
2861 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3140 a1.z = llAtan2(d1.y, d1.x);
2862 3141
2863 // Calculate pitch 3142 // Get the elevation (pitch)
2864 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3143 LSL_Vector a2 = new LSL_Vector(0,0,0);
3144 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2865 3145
2866 // we need to convert from a vector describing 3146 LSL_Rotation r1 = llEuler2Rot(a1);
2867 // the angles of rotation in radians into rotation value 3147 LSL_Rotation r2 = llEuler2Rot(a2);
2868 LSL_Rotation rot = llEuler2Rot(angle); 3148 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2869
2870 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2871 // set the rotation of the object, copy that behavior
2872 PhysicsActor pa = m_host.PhysActor;
2873 3149
2874 if (strength == 0 || pa == null || !pa.IsPhysical) 3150 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2875 { 3151 {
2876 llSetRot(rot); 3152 // Do nothing if either value is 0 (this has been checked in SL)
3153 if (strength <= 0.0 || damping <= 0.0)
3154 return;
3155
3156 llSetRot(r3 * r2 * r1);
2877 } 3157 }
2878 else 3158 else
2879 { 3159 {
2880 m_host.StartLookAt(rot, (float)strength, (float)damping); 3160 if (strength == 0)
3161 {
3162 llSetRot(r3 * r2 * r1);
3163 return;
3164 }
3165
3166 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2881 } 3167 }
2882 } 3168 }
2883 3169
@@ -2923,17 +3209,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2923 } 3209 }
2924 else 3210 else
2925 { 3211 {
2926 if (m_host.IsRoot) 3212 // new SL always returns object mass
2927 { 3213// if (m_host.IsRoot)
3214// {
2928 return m_host.ParentGroup.GetMass(); 3215 return m_host.ParentGroup.GetMass();
2929 } 3216// }
2930 else 3217// else
2931 { 3218// {
2932 return m_host.GetMass(); 3219// return m_host.GetMass();
2933 } 3220// }
2934 } 3221 }
2935 } 3222 }
2936 3223
3224
3225 public LSL_Float llGetMassMKS()
3226 {
3227 return 100f * llGetMass();
3228 }
3229
2937 public void llCollisionFilter(string name, string id, int accept) 3230 public void llCollisionFilter(string name, string id, int accept)
2938 { 3231 {
2939 m_host.AddScriptLPS(1); 3232 m_host.AddScriptLPS(1);
@@ -2981,8 +3274,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 { 3274 {
2982 // Unregister controls from Presence 3275 // Unregister controls from Presence
2983 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3276 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2984 // Remove Take Control permission.
2985 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2986 } 3277 }
2987 } 3278 }
2988 } 3279 }
@@ -3008,7 +3299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3008 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3299 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3009 3300
3010 if (attachmentsModule != null) 3301 if (attachmentsModule != null)
3011 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3302 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3012 else 3303 else
3013 return false; 3304 return false;
3014 } 3305 }
@@ -3038,9 +3329,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3038 { 3329 {
3039 m_host.AddScriptLPS(1); 3330 m_host.AddScriptLPS(1);
3040 3331
3041// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3042// return;
3043
3044 if (m_item.PermsGranter != m_host.OwnerID) 3332 if (m_item.PermsGranter != m_host.OwnerID)
3045 return; 3333 return;
3046 3334
@@ -3083,6 +3371,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3083 3371
3084 public void llInstantMessage(string user, string message) 3372 public void llInstantMessage(string user, string message)
3085 { 3373 {
3374 UUID result;
3375 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3376 {
3377 ShoutError("An invalid key was passed to llInstantMessage");
3378 ScriptSleep(2000);
3379 return;
3380 }
3381
3382
3086 m_host.AddScriptLPS(1); 3383 m_host.AddScriptLPS(1);
3087 3384
3088 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3385 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3097,14 +3394,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 UUID friendTransactionID = UUID.Random(); 3394 UUID friendTransactionID = UUID.Random();
3098 3395
3099 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3396 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3100 3397
3101 GridInstantMessage msg = new GridInstantMessage(); 3398 GridInstantMessage msg = new GridInstantMessage();
3102 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3399 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3103 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3400 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3104 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3401 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3105// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3402// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3106// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3403// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3107 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3404// DateTime dt = DateTime.UtcNow;
3405//
3406// // Ticks from UtcNow, but make it look like local. Evil, huh?
3407// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3408//
3409// try
3410// {
3411// // Convert that to the PST timezone
3412// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3413// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3414// }
3415// catch
3416// {
3417// // No logging here, as it could be VERY spammy
3418// }
3419//
3420// // And make it look local again to fool the unix time util
3421// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3422
3423 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3424
3108 //if (client != null) 3425 //if (client != null)
3109 //{ 3426 //{
3110 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3427 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3118,12 +3435,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3118 msg.message = message.Substring(0, 1024); 3435 msg.message = message.Substring(0, 1024);
3119 else 3436 else
3120 msg.message = message; 3437 msg.message = message;
3121 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3438 msg.dialog = (byte)19; // MessageFromObject
3122 msg.fromGroup = false;// fromGroup; 3439 msg.fromGroup = false;// fromGroup;
3123 msg.offline = (byte)0; //offline; 3440 msg.offline = (byte)0; //offline;
3124 msg.ParentEstateID = 0; //ParentEstateID; 3441 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3125 msg.Position = new Vector3(m_host.AbsolutePosition); 3442 msg.Position = new Vector3(m_host.AbsolutePosition);
3126 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3443 msg.RegionID = World.RegionInfo.RegionID.Guid;
3127 msg.binaryBucket 3444 msg.binaryBucket
3128 = Util.StringToBytes256( 3445 = Util.StringToBytes256(
3129 "{0}/{1}/{2}/{3}", 3446 "{0}/{1}/{2}/{3}",
@@ -3151,7 +3468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3151 } 3468 }
3152 3469
3153 emailModule.SendEmail(m_host.UUID, address, subject, message); 3470 emailModule.SendEmail(m_host.UUID, address, subject, message);
3154 llSleep(EMAIL_PAUSE_TIME); 3471 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3155 } 3472 }
3156 3473
3157 public void llGetNextEmail(string address, string subject) 3474 public void llGetNextEmail(string address, string subject)
@@ -3397,7 +3714,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3397 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3714 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3398 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3715 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3399 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3716 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3717 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3400 ScriptBaseClass.PERMISSION_ATTACH; 3718 ScriptBaseClass.PERMISSION_ATTACH;
3719
3401 } 3720 }
3402 else 3721 else
3403 { 3722 {
@@ -3428,15 +3747,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3428 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3747 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3429 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3748 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3430 } 3749 }
3750 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3751 {
3752 implicitPerms = perm;
3753 }
3431 } 3754 }
3432 3755
3433 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3756 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3434 { 3757 {
3435 lock (m_host.TaskInventory) 3758 m_host.TaskInventory.LockItemsForWrite(true);
3436 { 3759 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3437 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3760 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3438 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3761 m_host.TaskInventory.LockItemsForWrite(false);
3439 }
3440 3762
3441 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3763 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3442 "run_time_permissions", new Object[] { 3764 "run_time_permissions", new Object[] {
@@ -3479,11 +3801,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3479 3801
3480 if (!m_waitingForScriptAnswer) 3802 if (!m_waitingForScriptAnswer)
3481 { 3803 {
3482 lock (m_host.TaskInventory) 3804 m_host.TaskInventory.LockItemsForWrite(true);
3483 { 3805 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3484 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3806 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3485 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3807 m_host.TaskInventory.LockItemsForWrite(false);
3486 }
3487 3808
3488 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3809 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3489 m_waitingForScriptAnswer=true; 3810 m_waitingForScriptAnswer=true;
@@ -3512,14 +3833,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3833 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3834 llReleaseControls();
3514 3835
3515 lock (m_host.TaskInventory) 3836 m_host.TaskInventory.LockItemsForWrite(true);
3516 { 3837 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3517 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3838 m_host.TaskInventory.LockItemsForWrite(false);
3518 } 3839
3519 3840 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3520 m_ScriptEngine.PostScriptEvent( 3841 "run_time_permissions", new Object[] {
3521 m_item.ItemID, 3842 new LSL_Integer(answer) },
3522 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3843 new DetectParams[0]));
3523 } 3844 }
3524 3845
3525 public LSL_String llGetPermissionsKey() 3846 public LSL_String llGetPermissionsKey()
@@ -3558,14 +3879,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3558 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3879 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3559 { 3880 {
3560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3881 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3561 3882 if (parts.Count > 0)
3562 foreach (SceneObjectPart part in parts) 3883 {
3563 part.SetFaceColorAlpha(face, color, null); 3884 try
3885 {
3886 foreach (SceneObjectPart part in parts)
3887 part.SetFaceColorAlpha(face, color, null);
3888 }
3889 finally
3890 {
3891 }
3892 }
3564 } 3893 }
3565 3894
3566 public void llCreateLink(string target, int parent) 3895 public void llCreateLink(string target, int parent)
3567 { 3896 {
3568 m_host.AddScriptLPS(1); 3897 m_host.AddScriptLPS(1);
3898
3569 UUID targetID; 3899 UUID targetID;
3570 3900
3571 if (!UUID.TryParse(target, out targetID)) 3901 if (!UUID.TryParse(target, out targetID))
@@ -3671,10 +4001,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3671 // Restructuring Multiple Prims. 4001 // Restructuring Multiple Prims.
3672 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4002 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3673 parts.Remove(parentPrim.RootPart); 4003 parts.Remove(parentPrim.RootPart);
3674 foreach (SceneObjectPart part in parts) 4004 if (parts.Count > 0)
3675 { 4005 {
3676 parentPrim.DelinkFromGroup(part.LocalId, true); 4006 try
4007 {
4008 foreach (SceneObjectPart part in parts)
4009 {
4010 parentPrim.DelinkFromGroup(part.LocalId, true);
4011 }
4012 }
4013 finally
4014 {
4015 }
3677 } 4016 }
4017
3678 parentPrim.HasGroupChanged = true; 4018 parentPrim.HasGroupChanged = true;
3679 parentPrim.ScheduleGroupForFullUpdate(); 4019 parentPrim.ScheduleGroupForFullUpdate();
3680 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4020 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3683,12 +4023,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3683 { 4023 {
3684 SceneObjectPart newRoot = parts[0]; 4024 SceneObjectPart newRoot = parts[0];
3685 parts.Remove(newRoot); 4025 parts.Remove(newRoot);
3686 foreach (SceneObjectPart part in parts) 4026
4027 try
3687 { 4028 {
3688 // Required for linking 4029 foreach (SceneObjectPart part in parts)
3689 part.ClearUpdateSchedule(); 4030 {
3690 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4031 part.ClearUpdateSchedule();
4032 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4033 }
3691 } 4034 }
4035 finally
4036 {
4037 }
4038
4039
3692 newRoot.ParentGroup.HasGroupChanged = true; 4040 newRoot.ParentGroup.HasGroupChanged = true;
3693 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4041 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3694 } 4042 }
@@ -3708,6 +4056,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3708 public void llBreakAllLinks() 4056 public void llBreakAllLinks()
3709 { 4057 {
3710 m_host.AddScriptLPS(1); 4058 m_host.AddScriptLPS(1);
4059
4060 TaskInventoryItem item = m_item;
4061
4062 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4063 && !m_automaticLinkPermission)
4064 {
4065 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4066 return;
4067 }
4068
3711 SceneObjectGroup parentPrim = m_host.ParentGroup; 4069 SceneObjectGroup parentPrim = m_host.ParentGroup;
3712 if (parentPrim.AttachmentPoint != 0) 4070 if (parentPrim.AttachmentPoint != 0)
3713 return; // Fail silently if attached 4071 return; // Fail silently if attached
@@ -3727,25 +4085,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3727 public LSL_String llGetLinkKey(int linknum) 4085 public LSL_String llGetLinkKey(int linknum)
3728 { 4086 {
3729 m_host.AddScriptLPS(1); 4087 m_host.AddScriptLPS(1);
3730 List<UUID> keytable = new List<UUID>();
3731 // parse for sitting avatare-uuids
3732 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3733 {
3734 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3735 keytable.Add(presence.UUID);
3736 });
3737
3738 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3739 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3740 {
3741 return keytable[totalprims - linknum].ToString();
3742 }
3743
3744 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3745 {
3746 return m_host.UUID.ToString();
3747 }
3748
3749 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4088 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3750 if (part != null) 4089 if (part != null)
3751 { 4090 {
@@ -3753,6 +4092,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3753 } 4092 }
3754 else 4093 else
3755 { 4094 {
4095 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4096 {
4097 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4098
4099 if (linknum < 0)
4100 return UUID.Zero.ToString();
4101
4102 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4103 if (avatars.Count > linknum)
4104 {
4105 return avatars[linknum].UUID.ToString();
4106 }
4107 }
3756 return UUID.Zero.ToString(); 4108 return UUID.Zero.ToString();
3757 } 4109 }
3758 } 4110 }
@@ -3862,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3862 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3863 int count = 0; 4215 int count = 0;
3864 4216
3865 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3866 { 4219 {
3867 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3868 { 4221 {
3869 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3870 {
3871 count = count + 1;
3872 }
3873 } 4223 }
3874 } 4224 }
3875 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3876 return count; 4227 return count;
3877 } 4228 }
3878 4229
@@ -3881,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3881 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3882 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3883 4234
3884 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3885 { 4237 {
3886 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3887 { 4239 {
3888 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3889 {
3890 keys.Add(inv.Value.Name);
3891 }
3892 } 4241 }
3893 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3894 4244
3895 if (keys.Count == 0) 4245 if (keys.Count == 0)
3896 { 4246 {
@@ -3928,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3928 if (item == null) 4278 if (item == null)
3929 { 4279 {
3930 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3931 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3932 } 4283 }
3933 4284
3934 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3956,33 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3956 return; 4307 return;
3957 } 4308 }
3958 } 4309 }
4310
3959 // destination is an avatar 4311 // destination is an avatar
3960 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3961 4313
3962 if (agentItem == null) 4314 if (agentItem == null)
3963 return; 4315 return;
3964 4316
3965 if (m_TransferModule != null) 4317 byte[] bucket = new byte[1];
3966 { 4318 bucket[0] = (byte)item.Type;
3967 byte[] bucket = new byte[1]; 4319 //byte[] objBytes = agentItem.ID.GetBytes();
3968 bucket[0] = (byte)item.Type; 4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
3969 4321
3970 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
3971 m_host.OwnerID, m_host.Name, destId, 4323 m_host.OwnerID, m_host.Name, destId,
3972 (byte)InstantMessageDialog.TaskInventoryOffered, 4324 (byte)InstantMessageDialog.TaskInventoryOffered,
3973 false, item.Name+". "+m_host.Name+" is located at "+ 4325 false, item.Name+". "+m_host.Name+" is located at "+
3974 World.RegionInfo.RegionName+" "+ 4326 World.RegionInfo.RegionName+" "+
3975 m_host.AbsolutePosition.ToString(), 4327 m_host.AbsolutePosition.ToString(),
3976 agentItem.ID, true, m_host.AbsolutePosition, 4328 agentItem.ID, true, m_host.AbsolutePosition,
3977 bucket, true); 4329 bucket, true);
3978 4330
3979 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4331 ScenePresence sp;
3980 }
3981 4332
4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
4336 }
4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3982 ScriptSleep(3000); 4344 ScriptSleep(3000);
3983 } 4345 }
3984 } 4346 }
3985 4347
4348 [DebuggerNonUserCode]
3986 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3987 { 4350 {
3988 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -4037,109 +4400,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4037 { 4400 {
4038 m_host.AddScriptLPS(1); 4401 m_host.AddScriptLPS(1);
4039 4402
4040 UUID uuid = (UUID)id; 4403 UUID uuid;
4041 PresenceInfo pinfo = null; 4404 if (UUID.TryParse(id, out uuid))
4042 UserAccount account;
4043
4044 UserInfoCacheEntry ce;
4045 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4046 { 4405 {
4047 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4406 PresenceInfo pinfo = null;
4048 if (account == null) 4407 UserAccount account;
4408
4409 UserInfoCacheEntry ce;
4410 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4049 { 4411 {
4050 m_userInfoCache[uuid] = null; // Cache negative 4412 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4051 return UUID.Zero.ToString(); 4413 if (account == null)
4052 } 4414 {
4415 m_userInfoCache[uuid] = null; // Cache negative
4416 return UUID.Zero.ToString();
4417 }
4053 4418
4054 4419
4055 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4420 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4056 if (pinfos != null && pinfos.Length > 0) 4421 if (pinfos != null && pinfos.Length > 0)
4057 {
4058 foreach (PresenceInfo p in pinfos)
4059 { 4422 {
4060 if (p.RegionID != UUID.Zero) 4423 foreach (PresenceInfo p in pinfos)
4061 { 4424 {
4062 pinfo = p; 4425 if (p.RegionID != UUID.Zero)
4426 {
4427 pinfo = p;
4428 }
4063 } 4429 }
4064 } 4430 }
4065 }
4066 4431
4067 ce = new UserInfoCacheEntry(); 4432 ce = new UserInfoCacheEntry();
4068 ce.time = Util.EnvironmentTickCount(); 4433 ce.time = Util.EnvironmentTickCount();
4069 ce.account = account; 4434 ce.account = account;
4070 ce.pinfo = pinfo; 4435 ce.pinfo = pinfo;
4071 } 4436 m_userInfoCache[uuid] = ce;
4072 else 4437 }
4073 { 4438 else
4074 if (ce == null) 4439 {
4075 return UUID.Zero.ToString(); 4440 if (ce == null)
4441 return UUID.Zero.ToString();
4076 4442
4077 account = ce.account; 4443 account = ce.account;
4078 pinfo = ce.pinfo; 4444 pinfo = ce.pinfo;
4079 } 4445 }
4080 4446
4081 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4447 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4082 {
4083 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4084 if (pinfos != null && pinfos.Length > 0)
4085 { 4448 {
4086 foreach (PresenceInfo p in pinfos) 4449 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4450 if (pinfos != null && pinfos.Length > 0)
4087 { 4451 {
4088 if (p.RegionID != UUID.Zero) 4452 foreach (PresenceInfo p in pinfos)
4089 { 4453 {
4090 pinfo = p; 4454 if (p.RegionID != UUID.Zero)
4455 {
4456 pinfo = p;
4457 }
4091 } 4458 }
4092 } 4459 }
4093 } 4460 else
4094 else 4461 pinfo = null;
4095 pinfo = null;
4096 4462
4097 ce.time = Util.EnvironmentTickCount(); 4463 ce.time = Util.EnvironmentTickCount();
4098 ce.pinfo = pinfo; 4464 ce.pinfo = pinfo;
4099 } 4465 }
4100 4466
4101 string reply = String.Empty; 4467 string reply = String.Empty;
4102 4468
4103 switch (data) 4469 switch (data)
4104 { 4470 {
4105 case 1: // DATA_ONLINE (0|1) 4471 case 1: // DATA_ONLINE (0|1)
4106 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4472 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4107 reply = "1"; 4473 reply = "1";
4108 else 4474 else
4109 reply = "0"; 4475 reply = "0";
4110 break; 4476 break;
4111 case 2: // DATA_NAME (First Last) 4477 case 2: // DATA_NAME (First Last)
4112 reply = account.FirstName + " " + account.LastName; 4478 reply = account.FirstName + " " + account.LastName;
4113 break; 4479 break;
4114 case 3: // DATA_BORN (YYYY-MM-DD) 4480 case 3: // DATA_BORN (YYYY-MM-DD)
4115 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4481 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4116 born = born.AddSeconds(account.Created); 4482 born = born.AddSeconds(account.Created);
4117 reply = born.ToString("yyyy-MM-dd"); 4483 reply = born.ToString("yyyy-MM-dd");
4118 break; 4484 break;
4119 case 4: // DATA_RATING (0,0,0,0,0,0) 4485 case 4: // DATA_RATING (0,0,0,0,0,0)
4120 reply = "0,0,0,0,0,0"; 4486 reply = "0,0,0,0,0,0";
4121 break; 4487 break;
4122 case 7: // DATA_USERLEVEL (integer) 4488 case 8: // DATA_PAYINFO (0|1|2|3)
4123 reply = account.UserLevel.ToString(); 4489 reply = "0";
4124 break; 4490 break;
4125 case 8: // DATA_PAYINFO (0|1|2|3) 4491 default:
4126 reply = "0"; 4492 return UUID.Zero.ToString(); // Raise no event
4127 break; 4493 }
4128 default:
4129 return UUID.Zero.ToString(); // Raise no event
4130 }
4131 4494
4132 UUID rq = UUID.Random(); 4495 UUID rq = UUID.Random();
4133 4496
4134 UUID tid = AsyncCommands. 4497 UUID tid = AsyncCommands.
4135 DataserverPlugin.RegisterRequest(m_host.LocalId, 4498 DataserverPlugin.RegisterRequest(m_host.LocalId,
4136 m_item.ItemID, rq.ToString()); 4499 m_item.ItemID, rq.ToString());
4137 4500
4138 AsyncCommands. 4501 AsyncCommands.
4139 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4502 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4140 4503
4141 ScriptSleep(100); 4504 ScriptSleep(100);
4142 return tid.ToString(); 4505 return tid.ToString();
4506 }
4507 else
4508 {
4509 ShoutError("Invalid UUID passed to llRequestAgentData.");
4510 }
4511 return "";
4143 } 4512 }
4144 4513
4145 public LSL_String llRequestInventoryData(string name) 4514 public LSL_String llRequestInventoryData(string name)
@@ -4196,13 +4565,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4196 if (UUID.TryParse(agent, out agentId)) 4565 if (UUID.TryParse(agent, out agentId))
4197 { 4566 {
4198 ScenePresence presence = World.GetScenePresence(agentId); 4567 ScenePresence presence = World.GetScenePresence(agentId);
4199 if (presence != null) 4568 if (presence != null && presence.PresenceType != PresenceType.Npc)
4200 { 4569 {
4570 // agent must not be a god
4571 if (presence.UserLevel >= 200) return;
4572
4201 // agent must be over the owners land 4573 // agent must be over the owners land
4202 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4574 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4203 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4575 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4204 { 4576 {
4205 World.TeleportClientHome(agentId, presence.ControllingClient); 4577 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4578 {
4579 // They can't be teleported home for some reason
4580 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4581 if (regionInfo != null)
4582 {
4583 World.RequestTeleportLocation(
4584 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4585 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4586 }
4587 }
4206 } 4588 }
4207 } 4589 }
4208 } 4590 }
@@ -4309,7 +4691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4309 UUID av = new UUID(); 4691 UUID av = new UUID();
4310 if (!UUID.TryParse(agent,out av)) 4692 if (!UUID.TryParse(agent,out av))
4311 { 4693 {
4312 LSLError("First parameter to llDialog needs to be a key"); 4694 //LSLError("First parameter to llDialog needs to be a key");
4313 return; 4695 return;
4314 } 4696 }
4315 4697
@@ -4341,10 +4723,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4341 public void llCollisionSound(string impact_sound, double impact_volume) 4723 public void llCollisionSound(string impact_sound, double impact_volume)
4342 { 4724 {
4343 m_host.AddScriptLPS(1); 4725 m_host.AddScriptLPS(1);
4344 4726
4727 if(impact_sound == "")
4728 {
4729 m_host.CollisionSoundVolume = (float)impact_volume;
4730 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4731 m_host.CollisionSoundType = 0;
4732 return;
4733 }
4345 // TODO: Parameter check logic required. 4734 // TODO: Parameter check logic required.
4346 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4735 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4347 m_host.CollisionSoundVolume = (float)impact_volume; 4736 m_host.CollisionSoundVolume = (float)impact_volume;
4737 m_host.CollisionSoundType = 1;
4348 } 4738 }
4349 4739
4350 public LSL_String llGetAnimation(string id) 4740 public LSL_String llGetAnimation(string id)
@@ -4358,14 +4748,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4358 4748
4359 if (m_host.RegionHandle == presence.RegionHandle) 4749 if (m_host.RegionHandle == presence.RegionHandle)
4360 { 4750 {
4361 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4362
4363 if (presence != null) 4751 if (presence != null)
4364 { 4752 {
4365 AnimationSet currentAnims = presence.Animator.Animations; 4753 if (presence.SitGround)
4366 string currentAnimationState = String.Empty; 4754 return "Sitting on Ground";
4367 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4755 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4368 return currentAnimationState; 4756 return "Sitting";
4757
4758 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4759 string lslMovementAnimation;
4760
4761 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4762 return lslMovementAnimation;
4369 } 4763 }
4370 } 4764 }
4371 4765
@@ -4512,7 +4906,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4512 { 4906 {
4513 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4907 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4514 float distance_term = distance * distance * distance; // Script Energy 4908 float distance_term = distance * distance * distance; // Script Energy
4515 float pusher_mass = m_host.GetMass(); 4909 // use total object mass and not part
4910 float pusher_mass = m_host.ParentGroup.GetMass();
4516 4911
4517 float PUSH_ATTENUATION_DISTANCE = 17f; 4912 float PUSH_ATTENUATION_DISTANCE = 17f;
4518 float PUSH_ATTENUATION_SCALE = 5f; 4913 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4762,6 +5157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4762 { 5157 {
4763 return item.AssetID.ToString(); 5158 return item.AssetID.ToString();
4764 } 5159 }
5160 m_host.TaskInventory.LockItemsForRead(false);
4765 5161
4766 return UUID.Zero.ToString(); 5162 return UUID.Zero.ToString();
4767 } 5163 }
@@ -4895,7 +5291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4895 public LSL_Vector llGetCenterOfMass() 5291 public LSL_Vector llGetCenterOfMass()
4896 { 5292 {
4897 m_host.AddScriptLPS(1); 5293 m_host.AddScriptLPS(1);
4898 Vector3 center = m_host.GetGeometricCenter(); 5294 Vector3 center = m_host.GetCenterOfMass();
4899 return new LSL_Vector(center.X,center.Y,center.Z); 5295 return new LSL_Vector(center.X,center.Y,center.Z);
4900 } 5296 }
4901 5297
@@ -4914,14 +5310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4914 { 5310 {
4915 m_host.AddScriptLPS(1); 5311 m_host.AddScriptLPS(1);
4916 5312
4917 if (src == null) 5313 return src.Length;
4918 {
4919 return 0;
4920 }
4921 else
4922 {
4923 return src.Length;
4924 }
4925 } 5314 }
4926 5315
4927 public LSL_Integer llList2Integer(LSL_List src, int index) 5316 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4992,7 +5381,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4992 else if (src.Data[index] is LSL_Float) 5381 else if (src.Data[index] is LSL_Float)
4993 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5382 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4994 else if (src.Data[index] is LSL_String) 5383 else if (src.Data[index] is LSL_String)
4995 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5384 {
5385 string str = ((LSL_String) src.Data[index]).m_string;
5386 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5387 if (m != Match.Empty)
5388 {
5389 str = m.Value;
5390 double d = 0.0;
5391 if (!Double.TryParse(str, out d))
5392 return 0.0;
5393
5394 return d;
5395 }
5396 return 0.0;
5397 }
4996 return Convert.ToDouble(src.Data[index]); 5398 return Convert.ToDouble(src.Data[index]);
4997 } 5399 }
4998 catch (FormatException) 5400 catch (FormatException)
@@ -5034,7 +5436,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5034 // for completion and should LSL_Key ever be implemented 5436 // for completion and should LSL_Key ever be implemented
5035 // as it's own struct 5437 // as it's own struct
5036 else if (!(src.Data[index] is LSL_String || 5438 else if (!(src.Data[index] is LSL_String ||
5037 src.Data[index] is LSL_Key)) 5439 src.Data[index] is LSL_Key ||
5440 src.Data[index] is String))
5038 { 5441 {
5039 return ""; 5442 return "";
5040 } 5443 }
@@ -5292,7 +5695,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5292 } 5695 }
5293 } 5696 }
5294 } 5697 }
5295 else { 5698 else
5699 {
5296 object[] array = new object[src.Length]; 5700 object[] array = new object[src.Length];
5297 Array.Copy(src.Data, 0, array, 0, src.Length); 5701 Array.Copy(src.Data, 0, array, 0, src.Length);
5298 result = new LSL_List(array); 5702 result = new LSL_List(array);
@@ -5399,7 +5803,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5399 public LSL_Integer llGetRegionAgentCount() 5803 public LSL_Integer llGetRegionAgentCount()
5400 { 5804 {
5401 m_host.AddScriptLPS(1); 5805 m_host.AddScriptLPS(1);
5402 return new LSL_Integer(World.GetRootAgentCount()); 5806
5807 int count = 0;
5808 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5809 count++;
5810 });
5811
5812 return new LSL_Integer(count);
5403 } 5813 }
5404 5814
5405 public LSL_Vector llGetRegionCorner() 5815 public LSL_Vector llGetRegionCorner()
@@ -5640,6 +6050,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5640 flags |= ScriptBaseClass.AGENT_AWAY; 6050 flags |= ScriptBaseClass.AGENT_AWAY;
5641 } 6051 }
5642 6052
6053 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6054 UUID[] anims = agent.Animator.GetAnimationArray();
6055 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6056 {
6057 flags |= ScriptBaseClass.AGENT_BUSY;
6058 }
6059
5643 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6060 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5644 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6061 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5645 { 6062 {
@@ -5687,6 +6104,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5687 flags |= ScriptBaseClass.AGENT_SITTING; 6104 flags |= ScriptBaseClass.AGENT_SITTING;
5688 } 6105 }
5689 6106
6107 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6108 {
6109 flags |= ScriptBaseClass.AGENT_MALE;
6110 }
6111
5690 return flags; 6112 return flags;
5691 } 6113 }
5692 6114
@@ -5834,9 +6256,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5834 6256
5835 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6257 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5836 6258
5837 foreach (SceneObjectPart part in parts) 6259 try
6260 {
6261 foreach (SceneObjectPart part in parts)
6262 {
6263 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6264 }
6265 }
6266 finally
5838 { 6267 {
5839 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5840 } 6268 }
5841 } 6269 }
5842 6270
@@ -5890,13 +6318,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5890 6318
5891 if (m_host.OwnerID == land.LandData.OwnerID) 6319 if (m_host.OwnerID == land.LandData.OwnerID)
5892 { 6320 {
5893 World.TeleportClientHome(agentID, presence.ControllingClient); 6321 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6322 presence.TeleportWithMomentum(pos, null);
6323 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5894 } 6324 }
5895 } 6325 }
5896 } 6326 }
5897 ScriptSleep(5000); 6327 ScriptSleep(5000);
5898 } 6328 }
5899 6329
6330 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6331 {
6332 return ParseString2List(str, separators, in_spacers, false);
6333 }
6334
5900 public LSL_Integer llOverMyLand(string id) 6335 public LSL_Integer llOverMyLand(string id)
5901 { 6336 {
5902 m_host.AddScriptLPS(1); 6337 m_host.AddScriptLPS(1);
@@ -5950,25 +6385,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5950 } 6385 }
5951 else 6386 else
5952 { 6387 {
5953 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6388// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6389 Vector3 s = avatar.Appearance.AvatarSize;
6390 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5954 } 6391 }
5955 return agentSize; 6392 return agentSize;
5956 } 6393 }
5957 6394
5958 public LSL_Integer llSameGroup(string agent) 6395 public LSL_Integer llSameGroup(string id)
5959 { 6396 {
5960 m_host.AddScriptLPS(1); 6397 m_host.AddScriptLPS(1);
5961 UUID agentId = new UUID(); 6398 UUID uuid = new UUID();
5962 if (!UUID.TryParse(agent, out agentId)) 6399 if (!UUID.TryParse(id, out uuid))
5963 return new LSL_Integer(0);
5964 ScenePresence presence = World.GetScenePresence(agentId);
5965 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5966 return new LSL_Integer(0); 6400 return new LSL_Integer(0);
5967 IClientAPI client = presence.ControllingClient; 6401
5968 if (m_host.GroupID == client.ActiveGroupId) 6402 // Check if it's a group key
6403 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5969 return new LSL_Integer(1); 6404 return new LSL_Integer(1);
5970 else 6405
6406 // We got passed a UUID.Zero
6407 if (uuid == UUID.Zero)
5971 return new LSL_Integer(0); 6408 return new LSL_Integer(0);
6409
6410 // Handle the case where id names an avatar
6411 ScenePresence presence = World.GetScenePresence(uuid);
6412 if (presence != null)
6413 {
6414 if (presence.IsChildAgent)
6415 return new LSL_Integer(0);
6416
6417 IClientAPI client = presence.ControllingClient;
6418 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6419 return new LSL_Integer(1);
6420
6421 return new LSL_Integer(0);
6422 }
6423
6424 // Handle object case
6425 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6426 if (part != null)
6427 {
6428 // This will handle both deed and non-deed and also the no
6429 // group case
6430 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6431 return new LSL_Integer(1);
6432
6433 return new LSL_Integer(0);
6434 }
6435
6436 return new LSL_Integer(0);
5972 } 6437 }
5973 6438
5974 public void llUnSit(string id) 6439 public void llUnSit(string id)
@@ -6093,7 +6558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6093 return m_host.ParentGroup.AttachmentPoint; 6558 return m_host.ParentGroup.AttachmentPoint;
6094 } 6559 }
6095 6560
6096 public LSL_Integer llGetFreeMemory() 6561 public virtual LSL_Integer llGetFreeMemory()
6097 { 6562 {
6098 m_host.AddScriptLPS(1); 6563 m_host.AddScriptLPS(1);
6099 // Make scripts designed for LSO happy 6564 // Make scripts designed for LSO happy
@@ -6210,7 +6675,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6210 SetParticleSystem(m_host, rules); 6675 SetParticleSystem(m_host, rules);
6211 } 6676 }
6212 6677
6213 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6678 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6679 {
6214 6680
6215 6681
6216 if (rules.Length == 0) 6682 if (rules.Length == 0)
@@ -6525,6 +6991,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6525 6991
6526 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6992 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6527 { 6993 {
6994 // LSL quaternions can normalize to 0, normal Quaternions can't.
6995 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6996 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6997
6528 part.SitTargetPosition = offset; 6998 part.SitTargetPosition = offset;
6529 part.SitTargetOrientation = rot; 6999 part.SitTargetOrientation = rot;
6530 part.ParentGroup.HasGroupChanged = true; 7000 part.ParentGroup.HasGroupChanged = true;
@@ -6710,13 +7180,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 UUID av = new UUID(); 7180 UUID av = new UUID();
6711 if (!UUID.TryParse(avatar,out av)) 7181 if (!UUID.TryParse(avatar,out av))
6712 { 7182 {
6713 LSLError("First parameter to llDialog needs to be a key"); 7183 //LSLError("First parameter to llDialog needs to be a key");
6714 return; 7184 return;
6715 } 7185 }
6716 if (buttons.Length < 1) 7186 if (buttons.Length < 1)
6717 { 7187 {
6718 LSLError("No less than 1 button can be shown"); 7188 buttons.Add("OK");
6719 return;
6720 } 7189 }
6721 if (buttons.Length > 12) 7190 if (buttons.Length > 12)
6722 { 7191 {
@@ -6733,7 +7202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6733 } 7202 }
6734 if (buttons.Data[i].ToString().Length > 24) 7203 if (buttons.Data[i].ToString().Length > 24)
6735 { 7204 {
6736 LSLError("button label cannot be longer than 24 characters"); 7205 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6737 return; 7206 return;
6738 } 7207 }
6739 buts[i] = buttons.Data[i].ToString(); 7208 buts[i] = buttons.Data[i].ToString();
@@ -6800,9 +7269,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6800 return; 7269 return;
6801 } 7270 }
6802 7271
6803 // the rest of the permission checks are done in RezScript, so check the pin there as well 7272 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6804 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7273 if (dest != null)
7274 {
7275 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7276 {
7277 // the rest of the permission checks are done in RezScript, so check the pin there as well
7278 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6805 7279
7280 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7281 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7282 }
7283 }
6806 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7284 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6807 ScriptSleep(3000); 7285 ScriptSleep(3000);
6808 } 7286 }
@@ -6872,19 +7350,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6872 public LSL_String llMD5String(string src, int nonce) 7350 public LSL_String llMD5String(string src, int nonce)
6873 { 7351 {
6874 m_host.AddScriptLPS(1); 7352 m_host.AddScriptLPS(1);
6875 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7353 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6876 } 7354 }
6877 7355
6878 public LSL_String llSHA1String(string src) 7356 public LSL_String llSHA1String(string src)
6879 { 7357 {
6880 m_host.AddScriptLPS(1); 7358 m_host.AddScriptLPS(1);
6881 return Util.SHA1Hash(src).ToLower(); 7359 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6882 } 7360 }
6883 7361
6884 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7362 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6885 { 7363 {
6886 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7364 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6887 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7365 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7366 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7367 return shapeBlock;
6888 7368
6889 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7369 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6890 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7370 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6989,6 +7469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6989 // Prim type box, cylinder and prism. 7469 // Prim type box, cylinder and prism.
6990 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) 7470 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)
6991 { 7471 {
7472 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7473 return;
7474
6992 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7475 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6993 ObjectShapePacket.ObjectDataBlock shapeBlock; 7476 ObjectShapePacket.ObjectDataBlock shapeBlock;
6994 7477
@@ -7042,6 +7525,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7042 // Prim type sphere. 7525 // Prim type sphere.
7043 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7526 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7044 { 7527 {
7528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7529 return;
7530
7045 ObjectShapePacket.ObjectDataBlock shapeBlock; 7531 ObjectShapePacket.ObjectDataBlock shapeBlock;
7046 7532
7047 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7533 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7083,6 +7569,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7083 // Prim type torus, tube and ring. 7569 // Prim type torus, tube and ring.
7084 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) 7570 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)
7085 { 7571 {
7572 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7573 return;
7574
7086 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7575 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7087 ObjectShapePacket.ObjectDataBlock shapeBlock; 7576 ObjectShapePacket.ObjectDataBlock shapeBlock;
7088 7577
@@ -7218,6 +7707,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7218 // Prim type sculpt. 7707 // Prim type sculpt.
7219 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7708 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7220 { 7709 {
7710 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7711 return;
7712
7221 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7713 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7222 UUID sculptId; 7714 UUID sculptId;
7223 7715
@@ -7242,7 +7734,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7242 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7734 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7243 { 7735 {
7244 // default 7736 // default
7245 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7737 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7246 } 7738 }
7247 7739
7248 part.Shape.SetSculptProperties((byte)type, sculptId); 7740 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7259,48 +7751,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7259 ScriptSleep(200); 7751 ScriptSleep(200);
7260 } 7752 }
7261 7753
7262 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7754 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7263 { 7755 {
7264 m_host.AddScriptLPS(1); 7756 m_host.AddScriptLPS(1);
7265 7757
7266 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7758 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7267 7759
7268 ScriptSleep(200); 7760 ScriptSleep(200);
7269 } 7761 }
7270 7762
7271 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7763 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7272 { 7764 {
7273 m_host.AddScriptLPS(1); 7765 List<object> parts = new List<object>();
7766 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7767 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7768 foreach (SceneObjectPart p in prims)
7769 parts.Add(p);
7770 foreach (ScenePresence p in avatars)
7771 parts.Add(p);
7274 7772
7275 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7773 LSL_List remaining = null;
7774 uint rulesParsed = 0;
7775
7776 if (parts.Count > 0)
7777 {
7778 foreach (object part in parts)
7779 {
7780 if (part is SceneObjectPart)
7781 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7782 else
7783 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7784 }
7785
7786 while ((object)remaining != null && remaining.Length > 2)
7787 {
7788 linknumber = remaining.GetLSLIntegerItem(0);
7789 rules = remaining.GetSublist(1, -1);
7790 parts.Clear();
7791 prims = GetLinkParts(linknumber);
7792 avatars = GetLinkAvatars(linknumber);
7793 foreach (SceneObjectPart p in prims)
7794 parts.Add(p);
7795 foreach (ScenePresence p in avatars)
7796 parts.Add(p);
7797
7798 remaining = null;
7799 foreach (object part in parts)
7800 {
7801 if (part is SceneObjectPart)
7802 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7803 else
7804 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7805 }
7806 }
7807 }
7276 } 7808 }
7277 7809
7278 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7810 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7811 float material_density, float material_friction,
7812 float material_restitution, float material_gravity_modifier)
7279 { 7813 {
7280 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7814 ExtraPhysicsData physdata = new ExtraPhysicsData();
7815 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7816 physdata.Density = part.Density;
7817 physdata.Friction = part.Friction;
7818 physdata.Bounce = part.Bounciness;
7819 physdata.GravitationModifier = part.GravityModifier;
7281 7820
7282 LSL_List remaining = null; 7821 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7283 uint rulesParsed = 0; 7822 physdata.Density = material_density;
7823 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7824 physdata.Friction = material_friction;
7825 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7826 physdata.Bounce = material_restitution;
7827 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7828 physdata.GravitationModifier = material_gravity_modifier;
7284 7829
7285 foreach (SceneObjectPart part in parts) 7830 part.UpdateExtraPhysics(physdata);
7286 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7831 }
7287 7832
7288 while (remaining != null && remaining.Length > 2) 7833 public void llSetPhysicsMaterial(int material_bits,
7289 { 7834 float material_gravity_modifier, float material_restitution,
7290 linknumber = remaining.GetLSLIntegerItem(0); 7835 float material_friction, float material_density)
7291 rules = remaining.GetSublist(1, -1); 7836 {
7292 parts = GetLinkParts(linknumber); 7837 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7838 }
7293 7839
7294 foreach (SceneObjectPart part in parts) 7840 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7295 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7841 {
7842 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7843 llSetLinkPrimitiveParamsFast(linknumber, rules);
7844 ScriptSleep(200);
7845 }
7846
7847 // vector up using libomv (c&p from sop )
7848 // vector up rotated by r
7849 private Vector3 Zrot(Quaternion r)
7850 {
7851 double x, y, z, m;
7852
7853 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7854 if (Math.Abs(1.0 - m) > 0.000001)
7855 {
7856 m = 1.0 / Math.Sqrt(m);
7857 r.X *= (float)m;
7858 r.Y *= (float)m;
7859 r.Z *= (float)m;
7860 r.W *= (float)m;
7296 } 7861 }
7862
7863 x = 2 * (r.X * r.Z + r.Y * r.W);
7864 y = 2 * (-r.X * r.W + r.Y * r.Z);
7865 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7866
7867 return new Vector3((float)x, (float)y, (float)z);
7297 } 7868 }
7298 7869
7299 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7870 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7300 { 7871 {
7872 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7873 return null;
7874
7301 int idx = 0; 7875 int idx = 0;
7302 int idxStart = 0; 7876 int idxStart = 0;
7303 7877
7878 SceneObjectGroup parentgrp = part.ParentGroup;
7879
7304 bool positionChanged = false; 7880 bool positionChanged = false;
7305 LSL_Vector currentPosition = GetPartLocalPos(part); 7881 LSL_Vector currentPosition = GetPartLocalPos(part);
7306 7882
@@ -7325,8 +7901,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7325 return null; 7901 return null;
7326 7902
7327 v=rules.GetVector3Item(idx++); 7903 v=rules.GetVector3Item(idx++);
7328 positionChanged = true;
7329 currentPosition = GetSetPosTarget(part, v, currentPosition); 7904 currentPosition = GetSetPosTarget(part, v, currentPosition);
7905 positionChanged = true;
7330 7906
7331 break; 7907 break;
7332 case (int)ScriptBaseClass.PRIM_SIZE: 7908 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7603,7 +8179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 return null; 8179 return null;
7604 8180
7605 string ph = rules.Data[idx++].ToString(); 8181 string ph = rules.Data[idx++].ToString();
7606 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8182 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7607 8183
7608 break; 8184 break;
7609 8185
@@ -7621,12 +8197,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7621 part.ScriptSetPhysicsStatus(physics); 8197 part.ScriptSetPhysicsStatus(physics);
7622 break; 8198 break;
7623 8199
8200 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8201 if (remain < 1)
8202 return null;
8203
8204 int shape_type = rules.GetLSLIntegerItem(idx++);
8205
8206 ExtraPhysicsData physdata = new ExtraPhysicsData();
8207 physdata.Density = part.Density;
8208 physdata.Bounce = part.Bounciness;
8209 physdata.GravitationModifier = part.GravityModifier;
8210 physdata.PhysShapeType = (PhysShapeType)shape_type;
8211
8212 part.UpdateExtraPhysics(physdata);
8213
8214 break;
8215
8216 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8217 if (remain < 5)
8218 return null;
8219
8220 int material_bits = rules.GetLSLIntegerItem(idx++);
8221 float material_density = (float)rules.GetLSLFloatItem(idx++);
8222 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8223 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8224 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8225
8226 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8227
8228 break;
8229
7624 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8230 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7625 if (remain < 1) 8231 if (remain < 1)
7626 return null; 8232 return null;
7627 string temp = rules.Data[idx++].ToString(); 8233 string temp = rules.Data[idx++].ToString();
7628 8234
7629 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8235 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7630 8236
7631 break; 8237 break;
7632 8238
@@ -7700,7 +8306,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7700 if (part.ParentGroup.RootPart == part) 8306 if (part.ParentGroup.RootPart == part)
7701 { 8307 {
7702 SceneObjectGroup parent = part.ParentGroup; 8308 SceneObjectGroup parent = part.ParentGroup;
7703 parent.UpdateGroupPosition(currentPosition); 8309 Util.FireAndForget(delegate(object x) {
8310 parent.UpdateGroupPosition(currentPosition);
8311 });
7704 } 8312 }
7705 else 8313 else
7706 { 8314 {
@@ -7745,10 +8353,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7745 8353
7746 public LSL_String llXorBase64Strings(string str1, string str2) 8354 public LSL_String llXorBase64Strings(string str1, string str2)
7747 { 8355 {
7748 m_host.AddScriptLPS(1); 8356 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7749 Deprecated("llXorBase64Strings"); 8357
7750 ScriptSleep(300); 8358 ScriptSleep(300);
7751 return String.Empty; 8359 m_host.AddScriptLPS(1);
8360
8361 if (str1 == String.Empty)
8362 return String.Empty;
8363 if (str2 == String.Empty)
8364 return str1;
8365
8366 int len = str2.Length;
8367 if ((len % 4) != 0) // LL is EVIL!!!!
8368 {
8369 while (str2.EndsWith("="))
8370 str2 = str2.Substring(0, str2.Length - 1);
8371
8372 len = str2.Length;
8373 int mod = len % 4;
8374
8375 if (mod == 1)
8376 str2 = str2.Substring(0, str2.Length - 1);
8377 else if (mod == 2)
8378 str2 += "==";
8379 else if (mod == 3)
8380 str2 += "=";
8381 }
8382
8383 byte[] data1;
8384 byte[] data2;
8385 try
8386 {
8387 data1 = Convert.FromBase64String(str1);
8388 data2 = Convert.FromBase64String(str2);
8389 }
8390 catch (Exception)
8391 {
8392 return new LSL_String(String.Empty);
8393 }
8394
8395 // For cases where the decoded length of s2 is greater
8396 // than the decoded length of s1, simply perform a normal
8397 // decode and XOR
8398 //
8399 if (data2.Length >= data1.Length)
8400 {
8401 for (int pos = 0 ; pos < data1.Length ; pos++ )
8402 data1[pos] ^= data2[pos];
8403
8404 return Convert.ToBase64String(data1);
8405 }
8406
8407 // Remove padding
8408 while (str1.EndsWith("="))
8409 str1 = str1.Substring(0, str1.Length - 1);
8410 while (str2.EndsWith("="))
8411 str2 = str2.Substring(0, str2.Length - 1);
8412
8413 byte[] d1 = new byte[str1.Length];
8414 byte[] d2 = new byte[str2.Length];
8415
8416 for (int i = 0 ; i < str1.Length ; i++)
8417 {
8418 int idx = b64.IndexOf(str1.Substring(i, 1));
8419 if (idx == -1)
8420 idx = 0;
8421 d1[i] = (byte)idx;
8422 }
8423
8424 for (int i = 0 ; i < str2.Length ; i++)
8425 {
8426 int idx = b64.IndexOf(str2.Substring(i, 1));
8427 if (idx == -1)
8428 idx = 0;
8429 d2[i] = (byte)idx;
8430 }
8431
8432 string output = String.Empty;
8433
8434 for (int pos = 0 ; pos < d1.Length ; pos++)
8435 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8436
8437 while (output.Length % 3 > 0)
8438 output += "=";
8439
8440 return output;
7752 } 8441 }
7753 8442
7754 public void llRemoteDataSetRegion() 8443 public void llRemoteDataSetRegion()
@@ -7872,13 +8561,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7872 public LSL_Integer llGetNumberOfPrims() 8561 public LSL_Integer llGetNumberOfPrims()
7873 { 8562 {
7874 m_host.AddScriptLPS(1); 8563 m_host.AddScriptLPS(1);
7875 int avatarCount = 0; 8564 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7876 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8565
7877 {
7878 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7879 avatarCount++;
7880 });
7881
7882 return m_host.ParentGroup.PrimCount + avatarCount; 8566 return m_host.ParentGroup.PrimCount + avatarCount;
7883 } 8567 }
7884 8568
@@ -7894,55 +8578,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7894 m_host.AddScriptLPS(1); 8578 m_host.AddScriptLPS(1);
7895 UUID objID = UUID.Zero; 8579 UUID objID = UUID.Zero;
7896 LSL_List result = new LSL_List(); 8580 LSL_List result = new LSL_List();
8581
8582 // If the ID is not valid, return null result
7897 if (!UUID.TryParse(obj, out objID)) 8583 if (!UUID.TryParse(obj, out objID))
7898 { 8584 {
7899 result.Add(new LSL_Vector()); 8585 result.Add(new LSL_Vector());
7900 result.Add(new LSL_Vector()); 8586 result.Add(new LSL_Vector());
7901 return result; 8587 return result;
7902 } 8588 }
8589
8590 // Check if this is an attached prim. If so, replace
8591 // the UUID with the avatar UUID and report it's bounding box
8592 SceneObjectPart part = World.GetSceneObjectPart(objID);
8593 if (part != null && part.ParentGroup.IsAttachment)
8594 objID = part.ParentGroup.AttachedAvatar;
8595
8596 // Find out if this is an avatar ID. If so, return it's box
7903 ScenePresence presence = World.GetScenePresence(objID); 8597 ScenePresence presence = World.GetScenePresence(objID);
7904 if (presence != null) 8598 if (presence != null)
7905 { 8599 {
7906 if (presence.ParentID == 0) // not sat on an object 8600 // As per LSL Wiki, there is no difference between sitting
8601 // and standing avatar since server 1.36
8602 LSL_Vector lower;
8603 LSL_Vector upper;
8604
8605 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8606
8607 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8608 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8609/*
7907 { 8610 {
7908 LSL_Vector lower; 8611 // This is for ground sitting avatars
7909 LSL_Vector upper; 8612 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7910 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8613 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7911 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8614 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7912 {
7913 // This is for ground sitting avatars
7914 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7915 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7916 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7917 }
7918 else
7919 {
7920 // This is for standing/flying avatars
7921 float height = presence.Appearance.AvatarHeight / 2.0f;
7922 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7923 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7924 }
7925 result.Add(lower);
7926 result.Add(upper);
7927 return result;
7928 } 8615 }
7929 else 8616 else
7930 { 8617 {
7931 // sitting on an object so we need the bounding box of that 8618 // This is for standing/flying avatars
7932 // which should include the avatar so set the UUID to the 8619 float height = presence.Appearance.AvatarHeight / 2.0f;
7933 // UUID of the object the avatar is sat on and allow it to fall through 8620 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7934 // to processing an object 8621 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7935 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7936 objID = p.UUID;
7937 } 8622 }
8623
8624 // Adjust to the documented error offsets (see LSL Wiki)
8625 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8626 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8627*/
8628 {
8629 // This is for ground sitting avatars TODO!
8630 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8631 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8632 }
8633 else
8634 {
8635 // This is for standing/flying avatars
8636 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8637 upper = new LSL_Vector(box.X, box.Y, box.Z);
8638 }
8639
8640 if (lower.x > upper.x)
8641 lower.x = upper.x;
8642 if (lower.y > upper.y)
8643 lower.y = upper.y;
8644 if (lower.z > upper.z)
8645 lower.z = upper.z;
8646
8647 result.Add(lower);
8648 result.Add(upper);
8649 return result;
7938 } 8650 }
7939 SceneObjectPart part = World.GetSceneObjectPart(objID); 8651
8652 part = World.GetSceneObjectPart(objID);
7940 // Currently only works for single prims without a sitting avatar 8653 // Currently only works for single prims without a sitting avatar
7941 if (part != null) 8654 if (part != null)
7942 { 8655 {
7943 Vector3 halfSize = part.Scale / 2.0f; 8656 float minX;
7944 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8657 float maxX;
7945 LSL_Vector upper = new LSL_Vector(halfSize); 8658 float minY;
8659 float maxY;
8660 float minZ;
8661 float maxZ;
8662
8663 // This BBox is in sim coordinates, with the offset being
8664 // a contained point.
8665 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8666 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8667
8668 minX -= offsets[0].X;
8669 maxX -= offsets[0].X;
8670 minY -= offsets[0].Y;
8671 maxY -= offsets[0].Y;
8672 minZ -= offsets[0].Z;
8673 maxZ -= offsets[0].Z;
8674
8675 LSL_Vector lower;
8676 LSL_Vector upper;
8677
8678 // Adjust to the documented error offsets (see LSL Wiki)
8679 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8680 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8681
8682 if (lower.x > upper.x)
8683 lower.x = upper.x;
8684 if (lower.y > upper.y)
8685 lower.y = upper.y;
8686 if (lower.z > upper.z)
8687 lower.z = upper.z;
8688
7946 result.Add(lower); 8689 result.Add(lower);
7947 result.Add(upper); 8690 result.Add(upper);
7948 return result; 8691 return result;
@@ -7956,7 +8699,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7956 8699
7957 public LSL_Vector llGetGeometricCenter() 8700 public LSL_Vector llGetGeometricCenter()
7958 { 8701 {
7959 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8702 Vector3 tmp = m_host.GetGeometricCenter();
8703 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7960 } 8704 }
7961 8705
7962 public LSL_List llGetPrimitiveParams(LSL_List rules) 8706 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7984,24 +8728,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7984 { 8728 {
7985 m_host.AddScriptLPS(1); 8729 m_host.AddScriptLPS(1);
7986 8730
7987 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8731 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8732 // keep other options as before
7988 8733
8734 List<SceneObjectPart> parts;
8735 List<ScenePresence> avatars;
8736
7989 LSL_List res = new LSL_List(); 8737 LSL_List res = new LSL_List();
7990 LSL_List remaining = null; 8738 LSL_List remaining = null;
7991 8739
7992 foreach (SceneObjectPart part in parts) 8740 while (rules.Length > 0)
7993 {
7994 remaining = GetPrimParams(part, rules, ref res);
7995 }
7996
7997 while (remaining != null && remaining.Length > 2)
7998 { 8741 {
7999 linknumber = remaining.GetLSLIntegerItem(0);
8000 rules = remaining.GetSublist(1, -1);
8001 parts = GetLinkParts(linknumber); 8742 parts = GetLinkParts(linknumber);
8743 avatars = GetLinkAvatars(linknumber);
8002 8744
8745 remaining = null;
8003 foreach (SceneObjectPart part in parts) 8746 foreach (SceneObjectPart part in parts)
8747 {
8004 remaining = GetPrimParams(part, rules, ref res); 8748 remaining = GetPrimParams(part, rules, ref res);
8749 }
8750 foreach (ScenePresence avatar in avatars)
8751 {
8752 remaining = GetPrimParams(avatar, rules, ref res);
8753 }
8754
8755 if (remaining != null && remaining.Length > 0)
8756 {
8757 linknumber = remaining.GetLSLIntegerItem(0);
8758 rules = remaining.GetSublist(1, -1);
8759 }
8005 } 8760 }
8006 8761
8007 return res; 8762 return res;
@@ -8046,13 +8801,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8046 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8801 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8047 part.AbsolutePosition.Y, 8802 part.AbsolutePosition.Y,
8048 part.AbsolutePosition.Z); 8803 part.AbsolutePosition.Z);
8049 // For some reason, the part.AbsolutePosition.* values do not change if the
8050 // linkset is rotated; they always reflect the child prim's world position
8051 // as though the linkset is unrotated. This is incompatible behavior with SL's
8052 // implementation, so will break scripts imported from there (not to mention it
8053 // makes it more difficult to determine a child prim's actual inworld position).
8054 if (part.ParentID != 0)
8055 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8056 res.Add(v); 8804 res.Add(v);
8057 break; 8805 break;
8058 8806
@@ -8224,30 +8972,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8224 if (remain < 1) 8972 if (remain < 1)
8225 return null; 8973 return null;
8226 8974
8227 face=(int)rules.GetLSLIntegerItem(idx++); 8975 face = (int)rules.GetLSLIntegerItem(idx++);
8228 8976
8229 tex = part.Shape.Textures; 8977 tex = part.Shape.Textures;
8978 int shiny;
8230 if (face == ScriptBaseClass.ALL_SIDES) 8979 if (face == ScriptBaseClass.ALL_SIDES)
8231 { 8980 {
8232 for (face = 0; face < GetNumberOfSides(part); face++) 8981 for (face = 0; face < GetNumberOfSides(part); face++)
8233 { 8982 {
8234 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8983 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8235 // Convert Shininess to PRIM_SHINY_* 8984 if (shinyness == Shininess.High)
8236 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8985 {
8237 // PRIM_BUMP_* 8986 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8238 res.Add(new LSL_Integer((int)texface.Bump)); 8987 }
8988 else if (shinyness == Shininess.Medium)
8989 {
8990 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8991 }
8992 else if (shinyness == Shininess.Low)
8993 {
8994 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8995 }
8996 else
8997 {
8998 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8999 }
9000 res.Add(new LSL_Integer(shiny));
9001 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8239 } 9002 }
8240 } 9003 }
8241 else 9004 else
8242 { 9005 {
8243 if (face >= 0 && face < GetNumberOfSides(part)) 9006 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9007 if (shinyness == Shininess.High)
8244 { 9008 {
8245 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9009 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8246 // Convert Shininess to PRIM_SHINY_* 9010 }
8247 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9011 else if (shinyness == Shininess.Medium)
8248 // PRIM_BUMP_* 9012 {
8249 res.Add(new LSL_Integer((int)texface.Bump)); 9013 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9014 }
9015 else if (shinyness == Shininess.Low)
9016 {
9017 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9018 }
9019 else
9020 {
9021 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8250 } 9022 }
9023 res.Add(new LSL_Integer(shiny));
9024 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8251 } 9025 }
8252 break; 9026 break;
8253 9027
@@ -8255,24 +9029,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8255 if (remain < 1) 9029 if (remain < 1)
8256 return null; 9030 return null;
8257 9031
8258 face=(int)rules.GetLSLIntegerItem(idx++); 9032 face = (int)rules.GetLSLIntegerItem(idx++);
8259 9033
8260 tex = part.Shape.Textures; 9034 tex = part.Shape.Textures;
9035 int fullbright;
8261 if (face == ScriptBaseClass.ALL_SIDES) 9036 if (face == ScriptBaseClass.ALL_SIDES)
8262 { 9037 {
8263 for (face = 0; face < GetNumberOfSides(part); face++) 9038 for (face = 0; face < GetNumberOfSides(part); face++)
8264 { 9039 {
8265 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9040 if (tex.GetFace((uint)face).Fullbright == true)
8266 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9041 {
9042 fullbright = ScriptBaseClass.TRUE;
9043 }
9044 else
9045 {
9046 fullbright = ScriptBaseClass.FALSE;
9047 }
9048 res.Add(new LSL_Integer(fullbright));
8267 } 9049 }
8268 } 9050 }
8269 else 9051 else
8270 { 9052 {
8271 if (face >= 0 && face < GetNumberOfSides(part)) 9053 if (tex.GetFace((uint)face).Fullbright == true)
8272 { 9054 {
8273 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9055 fullbright = ScriptBaseClass.TRUE;
8274 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9056 }
9057 else
9058 {
9059 fullbright = ScriptBaseClass.FALSE;
8275 } 9060 }
9061 res.Add(new LSL_Integer(fullbright));
8276 } 9062 }
8277 break; 9063 break;
8278 9064
@@ -8294,27 +9080,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8294 break; 9080 break;
8295 9081
8296 case (int)ScriptBaseClass.PRIM_TEXGEN: 9082 case (int)ScriptBaseClass.PRIM_TEXGEN:
9083 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8297 if (remain < 1) 9084 if (remain < 1)
8298 return null; 9085 return null;
8299 9086
8300 face=(int)rules.GetLSLIntegerItem(idx++); 9087 face = (int)rules.GetLSLIntegerItem(idx++);
8301 9088
8302 tex = part.Shape.Textures; 9089 tex = part.Shape.Textures;
8303 if (face == ScriptBaseClass.ALL_SIDES) 9090 if (face == ScriptBaseClass.ALL_SIDES)
8304 { 9091 {
8305 for (face = 0; face < GetNumberOfSides(part); face++) 9092 for (face = 0; face < GetNumberOfSides(part); face++)
8306 { 9093 {
8307 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9094 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8308 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9095 {
8309 res.Add(new LSL_Integer((uint)texgen >> 1)); 9096 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9097 }
9098 else
9099 {
9100 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9101 }
8310 } 9102 }
8311 } 9103 }
8312 else 9104 else
8313 { 9105 {
8314 if (face >= 0 && face < GetNumberOfSides(part)) 9106 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8315 { 9107 {
8316 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9108 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8317 res.Add(new LSL_Integer((uint)texgen >> 1)); 9109 }
9110 else
9111 {
9112 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8318 } 9113 }
8319 } 9114 }
8320 break; 9115 break;
@@ -8338,24 +9133,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8338 if (remain < 1) 9133 if (remain < 1)
8339 return null; 9134 return null;
8340 9135
8341 face=(int)rules.GetLSLIntegerItem(idx++); 9136 face = (int)rules.GetLSLIntegerItem(idx++);
8342 9137
8343 tex = part.Shape.Textures; 9138 tex = part.Shape.Textures;
9139 float primglow;
8344 if (face == ScriptBaseClass.ALL_SIDES) 9140 if (face == ScriptBaseClass.ALL_SIDES)
8345 { 9141 {
8346 for (face = 0; face < GetNumberOfSides(part); face++) 9142 for (face = 0; face < GetNumberOfSides(part); face++)
8347 { 9143 {
8348 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9144 primglow = tex.GetFace((uint)face).Glow;
8349 res.Add(new LSL_Float(texface.Glow)); 9145 res.Add(new LSL_Float(primglow));
8350 } 9146 }
8351 } 9147 }
8352 else 9148 else
8353 { 9149 {
8354 if (face >= 0 && face < GetNumberOfSides(part)) 9150 primglow = tex.GetFace((uint)face).Glow;
8355 { 9151 res.Add(new LSL_Float(primglow));
8356 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8357 res.Add(new LSL_Float(texface.Glow));
8358 }
8359 } 9152 }
8360 break; 9153 break;
8361 9154
@@ -8367,15 +9160,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8367 textColor.B)); 9160 textColor.B));
8368 res.Add(new LSL_Float(textColor.A)); 9161 res.Add(new LSL_Float(textColor.A));
8369 break; 9162 break;
9163
8370 case (int)ScriptBaseClass.PRIM_NAME: 9164 case (int)ScriptBaseClass.PRIM_NAME:
8371 res.Add(new LSL_String(part.Name)); 9165 res.Add(new LSL_String(part.Name));
8372 break; 9166 break;
9167
8373 case (int)ScriptBaseClass.PRIM_DESC: 9168 case (int)ScriptBaseClass.PRIM_DESC:
8374 res.Add(new LSL_String(part.Description)); 9169 res.Add(new LSL_String(part.Description));
8375 break; 9170 break;
9171
8376 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9172 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8377 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9173 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8378 break; 9174 break;
9175
8379 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9176 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8380 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9177 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8381 break; 9178 break;
@@ -8986,8 +9783,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8986 // The function returns an ordered list 9783 // The function returns an ordered list
8987 // representing the tokens found in the supplied 9784 // representing the tokens found in the supplied
8988 // sources string. If two successive tokenizers 9785 // sources string. If two successive tokenizers
8989 // are encountered, then a NULL entry is added 9786 // are encountered, then a null-string entry is
8990 // to the list. 9787 // added to the list.
8991 // 9788 //
8992 // It is a precondition that the source and 9789 // It is a precondition that the source and
8993 // toekizer lisst are non-null. If they are null, 9790 // toekizer lisst are non-null. If they are null,
@@ -8995,7 +9792,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8995 // while their lengths are being determined. 9792 // while their lengths are being determined.
8996 // 9793 //
8997 // A small amount of working memoryis required 9794 // A small amount of working memoryis required
8998 // of approximately 8*#tokenizers. 9795 // of approximately 8*#tokenizers + 8*srcstrlen.
8999 // 9796 //
9000 // There are many ways in which this function 9797 // There are many ways in which this function
9001 // can be implemented, this implementation is 9798 // can be implemented, this implementation is
@@ -9011,155 +9808,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9011 // and eliminates redundant tokenizers as soon 9808 // and eliminates redundant tokenizers as soon
9012 // as is possible. 9809 // as is possible.
9013 // 9810 //
9014 // The implementation tries to avoid any copying 9811 // The implementation tries to minimize temporary
9015 // of arrays or other objects. 9812 // garbage generation.
9016 // </remarks> 9813 // </remarks>
9017 9814
9018 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9815 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9019 { 9816 {
9020 int beginning = 0; 9817 return ParseString2List(src, separators, spacers, true);
9021 int srclen = src.Length; 9818 }
9022 int seplen = separators.Length;
9023 object[] separray = separators.Data;
9024 int spclen = spacers.Length;
9025 object[] spcarray = spacers.Data;
9026 int mlen = seplen+spclen;
9027
9028 int[] offset = new int[mlen+1];
9029 bool[] active = new bool[mlen];
9030
9031 int best;
9032 int j;
9033
9034 // Initial capacity reduces resize cost
9035 9819
9036 LSL_List tokens = new LSL_List(); 9820 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9821 {
9822 int srclen = src.Length;
9823 int seplen = separators.Length;
9824 object[] separray = separators.Data;
9825 int spclen = spacers.Length;
9826 object[] spcarray = spacers.Data;
9827 int dellen = 0;
9828 string[] delarray = new string[seplen+spclen];
9037 9829
9038 // All entries are initially valid 9830 int outlen = 0;
9831 string[] outarray = new string[srclen*2+1];
9039 9832
9040 for (int i = 0; i < mlen; i++) 9833 int i, j;
9041 active[i] = true; 9834 string d;
9042 9835
9043 offset[mlen] = srclen; 9836 m_host.AddScriptLPS(1);
9044 9837
9045 while (beginning < srclen) 9838 /*
9839 * Convert separator and spacer lists to C# strings.
9840 * Also filter out null strings so we don't hang.
9841 */
9842 for (i = 0; i < seplen; i ++)
9046 { 9843 {
9844 d = separray[i].ToString();
9845 if (d.Length > 0)
9846 {
9847 delarray[dellen++] = d;
9848 }
9849 }
9850 seplen = dellen;
9047 9851
9048 best = mlen; // as bad as it gets 9852 for (i = 0; i < spclen; i ++)
9853 {
9854 d = spcarray[i].ToString();
9855 if (d.Length > 0)
9856 {
9857 delarray[dellen++] = d;
9858 }
9859 }
9049 9860
9050 // Scan for separators 9861 /*
9862 * Scan through source string from beginning to end.
9863 */
9864 for (i = 0;;)
9865 {
9051 9866
9052 for (j = 0; j < seplen; j++) 9867 /*
9868 * Find earliest delimeter in src starting at i (if any).
9869 */
9870 int earliestDel = -1;
9871 int earliestSrc = srclen;
9872 string earliestStr = null;
9873 for (j = 0; j < dellen; j ++)
9053 { 9874 {
9054 if (separray[j].ToString() == String.Empty) 9875 d = delarray[j];
9055 active[j] = false; 9876 if (d != null)
9056
9057 if (active[j])
9058 { 9877 {
9059 // scan all of the markers 9878 int index = src.IndexOf(d, i);
9060 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9879 if (index < 0)
9061 { 9880 {
9062 // not present at all 9881 delarray[j] = null; // delim nowhere in src, don't check it anymore
9063 active[j] = false;
9064 } 9882 }
9065 else 9883 else if (index < earliestSrc)
9066 { 9884 {
9067 // present and correct 9885 earliestSrc = index; // where delimeter starts in source string
9068 if (offset[j] < offset[best]) 9886 earliestDel = j; // where delimeter is in delarray[]
9069 { 9887 earliestStr = d; // the delimeter string from delarray[]
9070 // closest so far 9888 if (index == i) break; // can't do any better than found at beg of string
9071 best = j;
9072 if (offset[best] == beginning)
9073 break;
9074 }
9075 } 9889 }
9076 } 9890 }
9077 } 9891 }
9078 9892
9079 // Scan for spacers 9893 /*
9080 9894 * Output source string starting at i through start of earliest delimeter.
9081 if (offset[best] != beginning) 9895 */
9896 if (keepNulls || (earliestSrc > i))
9082 { 9897 {
9083 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9898 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9084 {
9085 if (spcarray[j-seplen].ToString() == String.Empty)
9086 active[j] = false;
9087
9088 if (active[j])
9089 {
9090 // scan all of the markers
9091 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9092 {
9093 // not present at all
9094 active[j] = false;
9095 }
9096 else
9097 {
9098 // present and correct
9099 if (offset[j] < offset[best])
9100 {
9101 // closest so far
9102 best = j;
9103 }
9104 }
9105 }
9106 }
9107 } 9899 }
9108 9900
9109 // This is the normal exit from the scanning loop 9901 /*
9902 * If no delimeter found at or after i, we're done scanning.
9903 */
9904 if (earliestDel < 0) break;
9110 9905
9111 if (best == mlen) 9906 /*
9907 * If delimeter was a spacer, output the spacer.
9908 */
9909 if (earliestDel >= seplen)
9112 { 9910 {
9113 // no markers were found on this pass 9911 outarray[outlen++] = earliestStr;
9114 // so we're pretty much done
9115 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9116 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9117 break;
9118 } 9912 }
9119 9913
9120 // Otherwise we just add the newly delimited token 9914 /*
9121 // and recalculate where the search should continue. 9915 * Look at rest of src string following delimeter.
9122 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9916 */
9123 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9917 i = earliestSrc + earliestStr.Length;
9124
9125 if (best < seplen)
9126 {
9127 beginning = offset[best] + (separray[best].ToString()).Length;
9128 }
9129 else
9130 {
9131 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9132 string str = spcarray[best - seplen].ToString();
9133 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9134 tokens.Add(new LSL_String(str));
9135 }
9136 } 9918 }
9137 9919
9138 // This an awkward an not very intuitive boundary case. If the 9920 /*
9139 // last substring is a tokenizer, then there is an implied trailing 9921 * Make up an exact-sized output array suitable for an LSL_List object.
9140 // null list entry. Hopefully the single comparison will not be too 9922 */
9141 // arduous. Alternatively the 'break' could be replced with a return 9923 object[] outlist = new object[outlen];
9142 // but that's shabby programming. 9924 for (i = 0; i < outlen; i ++)
9143
9144 if ((beginning == srclen) && (keepNulls))
9145 { 9925 {
9146 if (srclen != 0) 9926 outlist[i] = new LSL_String(outarray[i]);
9147 tokens.Add(new LSL_String(""));
9148 } 9927 }
9149 9928 return new LSL_List(outlist);
9150 return tokens;
9151 }
9152
9153 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9154 {
9155 m_host.AddScriptLPS(1);
9156 return this.ParseString(src, separators, spacers, false);
9157 }
9158
9159 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9160 {
9161 m_host.AddScriptLPS(1);
9162 return this.ParseString(src, separators, spacers, true);
9163 } 9929 }
9164 9930
9165 public LSL_Integer llGetObjectPermMask(int mask) 9931 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9254,6 +10020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9254 case 4: 10020 case 4:
9255 return (int)item.NextPermissions; 10021 return (int)item.NextPermissions;
9256 } 10022 }
10023 m_host.TaskInventory.LockItemsForRead(false);
9257 10024
9258 return -1; 10025 return -1;
9259 } 10026 }
@@ -9456,31 +10223,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9456 UUID key = new UUID(); 10223 UUID key = new UUID();
9457 if (UUID.TryParse(id, out key)) 10224 if (UUID.TryParse(id, out key))
9458 { 10225 {
9459 try 10226 // return total object mass
9460 { 10227 SceneObjectPart part = World.GetSceneObjectPart(key);
9461 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10228 if (part != null)
9462 if (obj != null) 10229 return part.ParentGroup.GetMass();
9463 return (double)obj.GetMass(); 10230
9464 // the object is null so the key is for an avatar 10231 // the object is null so the key is for an avatar
9465 ScenePresence avatar = World.GetScenePresence(key); 10232 ScenePresence avatar = World.GetScenePresence(key);
9466 if (avatar != null) 10233 if (avatar != null)
9467 if (avatar.IsChildAgent)
9468 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9469 // child agents have a mass of 1.0
9470 return 1;
9471 else
9472 return (double)avatar.GetMass();
9473 }
9474 catch (KeyNotFoundException)
9475 { 10234 {
9476 return 0; // The Object/Agent not in the region so just return zero 10235 if (avatar.IsChildAgent)
10236 {
10237 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10238 // child agents have a mass of 1.0
10239 return 1;
10240 }
10241 else
10242 {
10243 return (double)avatar.GetMass();
10244 }
9477 } 10245 }
9478 } 10246 }
9479 return 0; 10247 return 0;
9480 } 10248 }
9481 10249
9482 /// <summary> 10250 /// <summary>
9483 /// illListReplaceList removes the sub-list defined by the inclusive indices 10251 /// llListReplaceList removes the sub-list defined by the inclusive indices
9484 /// start and end and inserts the src list in its place. The inclusive 10252 /// start and end and inserts the src list in its place. The inclusive
9485 /// nature of the indices means that at least one element must be deleted 10253 /// nature of the indices means that at least one element must be deleted
9486 /// if the indices are within the bounds of the existing list. I.e. 2,2 10254 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9537,16 +10305,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9537 // based upon end. Note that if end exceeds the upper 10305 // based upon end. Note that if end exceeds the upper
9538 // bound in this case, the entire destination list 10306 // bound in this case, the entire destination list
9539 // is removed. 10307 // is removed.
9540 else 10308 else if (start == 0)
9541 { 10309 {
9542 if (end + 1 < dest.Length) 10310 if (end + 1 < dest.Length)
9543 {
9544 return src + dest.GetSublist(end + 1, -1); 10311 return src + dest.GetSublist(end + 1, -1);
9545 }
9546 else 10312 else
9547 {
9548 return src; 10313 return src;
9549 } 10314 }
10315 else // Start < 0
10316 {
10317 if (end + 1 < dest.Length)
10318 return dest.GetSublist(end + 1, -1);
10319 else
10320 return new LSL_List();
9550 } 10321 }
9551 } 10322 }
9552 // Finally, if start > end, we strip away a prefix and 10323 // Finally, if start > end, we strip away a prefix and
@@ -9597,17 +10368,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9597 int width = 0; 10368 int width = 0;
9598 int height = 0; 10369 int height = 0;
9599 10370
9600 ParcelMediaCommandEnum? commandToSend = null; 10371 uint commandToSend = 0;
9601 float time = 0.0f; // default is from start 10372 float time = 0.0f; // default is from start
9602 10373
9603 ScenePresence presence = null; 10374 ScenePresence presence = null;
9604 10375
9605 for (int i = 0; i < commandList.Data.Length; i++) 10376 for (int i = 0; i < commandList.Data.Length; i++)
9606 { 10377 {
9607 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10378 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9608 switch (command) 10379 switch (command)
9609 { 10380 {
9610 case ParcelMediaCommandEnum.Agent: 10381 case (uint)ParcelMediaCommandEnum.Agent:
9611 // we send only to one agent 10382 // we send only to one agent
9612 if ((i + 1) < commandList.Length) 10383 if ((i + 1) < commandList.Length)
9613 { 10384 {
@@ -9624,25 +10395,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9624 } 10395 }
9625 break; 10396 break;
9626 10397
9627 case ParcelMediaCommandEnum.Loop: 10398 case (uint)ParcelMediaCommandEnum.Loop:
9628 loop = 1; 10399 loop = 1;
9629 commandToSend = command; 10400 commandToSend = command;
9630 update = true; //need to send the media update packet to set looping 10401 update = true; //need to send the media update packet to set looping
9631 break; 10402 break;
9632 10403
9633 case ParcelMediaCommandEnum.Play: 10404 case (uint)ParcelMediaCommandEnum.Play:
9634 loop = 0; 10405 loop = 0;
9635 commandToSend = command; 10406 commandToSend = command;
9636 update = true; //need to send the media update packet to make sure it doesn't loop 10407 update = true; //need to send the media update packet to make sure it doesn't loop
9637 break; 10408 break;
9638 10409
9639 case ParcelMediaCommandEnum.Pause: 10410 case (uint)ParcelMediaCommandEnum.Pause:
9640 case ParcelMediaCommandEnum.Stop: 10411 case (uint)ParcelMediaCommandEnum.Stop:
9641 case ParcelMediaCommandEnum.Unload: 10412 case (uint)ParcelMediaCommandEnum.Unload:
9642 commandToSend = command; 10413 commandToSend = command;
9643 break; 10414 break;
9644 10415
9645 case ParcelMediaCommandEnum.Url: 10416 case (uint)ParcelMediaCommandEnum.Url:
9646 if ((i + 1) < commandList.Length) 10417 if ((i + 1) < commandList.Length)
9647 { 10418 {
9648 if (commandList.Data[i + 1] is LSL_String) 10419 if (commandList.Data[i + 1] is LSL_String)
@@ -9655,7 +10426,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9655 } 10426 }
9656 break; 10427 break;
9657 10428
9658 case ParcelMediaCommandEnum.Texture: 10429 case (uint)ParcelMediaCommandEnum.Texture:
9659 if ((i + 1) < commandList.Length) 10430 if ((i + 1) < commandList.Length)
9660 { 10431 {
9661 if (commandList.Data[i + 1] is LSL_String) 10432 if (commandList.Data[i + 1] is LSL_String)
@@ -9668,7 +10439,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9668 } 10439 }
9669 break; 10440 break;
9670 10441
9671 case ParcelMediaCommandEnum.Time: 10442 case (uint)ParcelMediaCommandEnum.Time:
9672 if ((i + 1) < commandList.Length) 10443 if ((i + 1) < commandList.Length)
9673 { 10444 {
9674 if (commandList.Data[i + 1] is LSL_Float) 10445 if (commandList.Data[i + 1] is LSL_Float)
@@ -9680,7 +10451,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 } 10451 }
9681 break; 10452 break;
9682 10453
9683 case ParcelMediaCommandEnum.AutoAlign: 10454 case (uint)ParcelMediaCommandEnum.AutoAlign:
9684 if ((i + 1) < commandList.Length) 10455 if ((i + 1) < commandList.Length)
9685 { 10456 {
9686 if (commandList.Data[i + 1] is LSL_Integer) 10457 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9694,7 +10465,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9694 } 10465 }
9695 break; 10466 break;
9696 10467
9697 case ParcelMediaCommandEnum.Type: 10468 case (uint)ParcelMediaCommandEnum.Type:
9698 if ((i + 1) < commandList.Length) 10469 if ((i + 1) < commandList.Length)
9699 { 10470 {
9700 if (commandList.Data[i + 1] is LSL_String) 10471 if (commandList.Data[i + 1] is LSL_String)
@@ -9707,7 +10478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9707 } 10478 }
9708 break; 10479 break;
9709 10480
9710 case ParcelMediaCommandEnum.Desc: 10481 case (uint)ParcelMediaCommandEnum.Desc:
9711 if ((i + 1) < commandList.Length) 10482 if ((i + 1) < commandList.Length)
9712 { 10483 {
9713 if (commandList.Data[i + 1] is LSL_String) 10484 if (commandList.Data[i + 1] is LSL_String)
@@ -9720,7 +10491,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9720 } 10491 }
9721 break; 10492 break;
9722 10493
9723 case ParcelMediaCommandEnum.Size: 10494 case (uint)ParcelMediaCommandEnum.Size:
9724 if ((i + 2) < commandList.Length) 10495 if ((i + 2) < commandList.Length)
9725 { 10496 {
9726 if (commandList.Data[i + 1] is LSL_Integer) 10497 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9790,7 +10561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9790 } 10561 }
9791 } 10562 }
9792 10563
9793 if (commandToSend != null) 10564 if (commandToSend != 0)
9794 { 10565 {
9795 // the commandList contained a start/stop/... command, too 10566 // the commandList contained a start/stop/... command, too
9796 if (presence == null) 10567 if (presence == null)
@@ -9827,7 +10598,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9827 10598
9828 if (aList.Data[i] != null) 10599 if (aList.Data[i] != null)
9829 { 10600 {
9830 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10601 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9831 { 10602 {
9832 case ParcelMediaCommandEnum.Url: 10603 case ParcelMediaCommandEnum.Url:
9833 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10604 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9884,15 +10655,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9884 10655
9885 if (quick_pay_buttons.Data.Length < 4) 10656 if (quick_pay_buttons.Data.Length < 4)
9886 { 10657 {
9887 LSLError("List must have at least 4 elements"); 10658 int x;
9888 return; 10659 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10660 {
10661 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10662 }
9889 } 10663 }
9890 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10664 int[] nPrice = new int[5];
9891 10665 nPrice[0] = price;
9892 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10666 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9893 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10667 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9894 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10668 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9895 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10669 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10670 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9896 m_host.ParentGroup.HasGroupChanged = true; 10671 m_host.ParentGroup.HasGroupChanged = true;
9897 } 10672 }
9898 10673
@@ -9909,7 +10684,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9909 return new LSL_Vector(); 10684 return new LSL_Vector();
9910 } 10685 }
9911 10686
9912 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10687// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10688 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9913 if (presence != null) 10689 if (presence != null)
9914 { 10690 {
9915 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10691 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9931,7 +10707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9931 return new LSL_Rotation(); 10707 return new LSL_Rotation();
9932 } 10708 }
9933 10709
9934 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10710// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10711 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9935 if (presence != null) 10712 if (presence != null)
9936 { 10713 {
9937 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10714 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9991,14 +10768,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9991 { 10768 {
9992 m_host.AddScriptLPS(1); 10769 m_host.AddScriptLPS(1);
9993 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10770 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9994 if (detectedParams == null) return; // only works on the first detected avatar 10771 if (detectedParams == null)
9995 10772 {
10773 if (m_host.ParentGroup.IsAttachment == true)
10774 {
10775 detectedParams = new DetectParams();
10776 detectedParams.Key = m_host.OwnerID;
10777 }
10778 else
10779 {
10780 return;
10781 }
10782 }
10783
9996 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10784 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9997 if (avatar != null) 10785 if (avatar != null)
9998 { 10786 {
9999 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10787 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10000 simname, pos, lookAt); 10788 simname, pos, lookAt);
10001 } 10789 }
10790
10002 ScriptSleep(1000); 10791 ScriptSleep(1000);
10003 } 10792 }
10004 10793
@@ -10122,12 +10911,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10122 10911
10123 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10912 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10124 object[] data = rules.Data; 10913 object[] data = rules.Data;
10125 for (int i = 0; i < data.Length; ++i) { 10914 for (int i = 0; i < data.Length; ++i)
10915 {
10126 int type = Convert.ToInt32(data[i++].ToString()); 10916 int type = Convert.ToInt32(data[i++].ToString());
10127 if (i >= data.Length) break; // odd number of entries => ignore the last 10917 if (i >= data.Length) break; // odd number of entries => ignore the last
10128 10918
10129 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10919 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10130 switch (type) { 10920 switch (type)
10921 {
10131 case ScriptBaseClass.CAMERA_FOCUS: 10922 case ScriptBaseClass.CAMERA_FOCUS:
10132 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10923 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10133 case ScriptBaseClass.CAMERA_POSITION: 10924 case ScriptBaseClass.CAMERA_POSITION:
@@ -10232,19 +11023,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10232 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11023 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10233 { 11024 {
10234 m_host.AddScriptLPS(1); 11025 m_host.AddScriptLPS(1);
10235 string ret = String.Empty; 11026
10236 string src1 = llBase64ToString(str1); 11027 if (str1 == String.Empty)
10237 string src2 = llBase64ToString(str2); 11028 return String.Empty;
10238 int c = 0; 11029 if (str2 == String.Empty)
10239 for (int i = 0; i < src1.Length; i++) 11030 return str1;
11031
11032 int len = str2.Length;
11033 if ((len % 4) != 0) // LL is EVIL!!!!
11034 {
11035 while (str2.EndsWith("="))
11036 str2 = str2.Substring(0, str2.Length - 1);
11037
11038 len = str2.Length;
11039 int mod = len % 4;
11040
11041 if (mod == 1)
11042 str2 = str2.Substring(0, str2.Length - 1);
11043 else if (mod == 2)
11044 str2 += "==";
11045 else if (mod == 3)
11046 str2 += "=";
11047 }
11048
11049 byte[] data1;
11050 byte[] data2;
11051 try
11052 {
11053 data1 = Convert.FromBase64String(str1);
11054 data2 = Convert.FromBase64String(str2);
11055 }
11056 catch (Exception)
11057 {
11058 return new LSL_String(String.Empty);
11059 }
11060
11061 byte[] d2 = new Byte[data1.Length];
11062 int pos = 0;
11063
11064 if (data1.Length <= data2.Length)
11065 {
11066 Array.Copy(data2, 0, d2, 0, data1.Length);
11067 }
11068 else
10240 { 11069 {
10241 ret += (char) (src1[i] ^ src2[c]); 11070 while (pos < data1.Length)
11071 {
11072 len = data1.Length - pos;
11073 if (len > data2.Length)
11074 len = data2.Length;
10242 11075
10243 c++; 11076 Array.Copy(data2, 0, d2, pos, len);
10244 if (c >= src2.Length) 11077 pos += len;
10245 c = 0; 11078 }
10246 } 11079 }
10247 return llStringToBase64(ret); 11080
11081 for (pos = 0 ; pos < data1.Length ; pos++ )
11082 data1[pos] ^= d2[pos];
11083
11084 return Convert.ToBase64String(data1);
10248 } 11085 }
10249 11086
10250 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11087 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10297,16 +11134,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10297 if (userAgent != null) 11134 if (userAgent != null)
10298 httpHeaders["User-Agent"] = userAgent; 11135 httpHeaders["User-Agent"] = userAgent;
10299 11136
11137 // See if the URL contains any header hacks
11138 string[] urlParts = url.Split(new char[] {'\n'});
11139 if (urlParts.Length > 1)
11140 {
11141 // Iterate the passed headers and parse them
11142 for (int i = 1 ; i < urlParts.Length ; i++ )
11143 {
11144 // The rest of those would be added to the body in SL.
11145 // Let's not do that.
11146 if (urlParts[i] == String.Empty)
11147 break;
11148
11149 // See if this could be a valid header
11150 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11151 if (headerParts.Length != 2)
11152 continue;
11153
11154 string headerName = headerParts[0].Trim();
11155 string headerValue = headerParts[1].Trim();
11156
11157 // Filter out headers that could be used to abuse
11158 // another system or cloak the request
11159 if (headerName.ToLower() == "x-secondlife-shard" ||
11160 headerName.ToLower() == "x-secondlife-object-name" ||
11161 headerName.ToLower() == "x-secondlife-object-key" ||
11162 headerName.ToLower() == "x-secondlife-region" ||
11163 headerName.ToLower() == "x-secondlife-local-position" ||
11164 headerName.ToLower() == "x-secondlife-local-velocity" ||
11165 headerName.ToLower() == "x-secondlife-local-rotation" ||
11166 headerName.ToLower() == "x-secondlife-owner-name" ||
11167 headerName.ToLower() == "x-secondlife-owner-key" ||
11168 headerName.ToLower() == "connection" ||
11169 headerName.ToLower() == "content-length" ||
11170 headerName.ToLower() == "from" ||
11171 headerName.ToLower() == "host" ||
11172 headerName.ToLower() == "proxy-authorization" ||
11173 headerName.ToLower() == "referer" ||
11174 headerName.ToLower() == "trailer" ||
11175 headerName.ToLower() == "transfer-encoding" ||
11176 headerName.ToLower() == "via" ||
11177 headerName.ToLower() == "authorization")
11178 continue;
11179
11180 httpHeaders[headerName] = headerValue;
11181 }
11182
11183 // Finally, strip any protocol specifier from the URL
11184 url = urlParts[0].Trim();
11185 int idx = url.IndexOf(" HTTP/");
11186 if (idx != -1)
11187 url = url.Substring(0, idx);
11188 }
11189
10300 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11190 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10301 Regex r = new Regex(authregex); 11191 Regex r = new Regex(authregex);
10302 int[] gnums = r.GetGroupNumbers(); 11192 int[] gnums = r.GetGroupNumbers();
10303 Match m = r.Match(url); 11193 Match m = r.Match(url);
10304 if (m.Success) { 11194 if (m.Success)
10305 for (int i = 1; i < gnums.Length; i++) { 11195 {
11196 for (int i = 1; i < gnums.Length; i++)
11197 {
10306 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11198 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10307 //CaptureCollection cc = g.Captures; 11199 //CaptureCollection cc = g.Captures;
10308 } 11200 }
10309 if (m.Groups.Count == 5) { 11201 if (m.Groups.Count == 5)
11202 {
10310 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11203 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10311 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11204 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10312 } 11205 }
@@ -10509,6 +11402,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10509 11402
10510 LSL_List ret = new LSL_List(); 11403 LSL_List ret = new LSL_List();
10511 UUID key = new UUID(); 11404 UUID key = new UUID();
11405
11406
10512 if (UUID.TryParse(id, out key)) 11407 if (UUID.TryParse(id, out key))
10513 { 11408 {
10514 ScenePresence av = World.GetScenePresence(key); 11409 ScenePresence av = World.GetScenePresence(key);
@@ -10526,13 +11421,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10526 ret.Add(new LSL_String("")); 11421 ret.Add(new LSL_String(""));
10527 break; 11422 break;
10528 case ScriptBaseClass.OBJECT_POS: 11423 case ScriptBaseClass.OBJECT_POS:
10529 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11424 Vector3 avpos;
11425
11426 if (av.ParentID != 0 && av.ParentPart != null)
11427 {
11428 avpos = av.OffsetPosition;
11429
11430 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11431 avpos -= sitOffset;
11432
11433 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11434 }
11435 else
11436 avpos = av.AbsolutePosition;
11437
11438 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10530 break; 11439 break;
10531 case ScriptBaseClass.OBJECT_ROT: 11440 case ScriptBaseClass.OBJECT_ROT:
10532 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11441 Quaternion avrot = av.Rotation;
11442 if (av.ParentID != 0 && av.ParentPart != null)
11443 {
11444 avrot = av.ParentPart.GetWorldRotation() * avrot;
11445 }
11446 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10533 break; 11447 break;
10534 case ScriptBaseClass.OBJECT_VELOCITY: 11448 case ScriptBaseClass.OBJECT_VELOCITY:
10535 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11449 Vector3 avvel = av.Velocity;
11450 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10536 break; 11451 break;
10537 case ScriptBaseClass.OBJECT_OWNER: 11452 case ScriptBaseClass.OBJECT_OWNER:
10538 ret.Add(new LSL_String(id)); 11453 ret.Add(new LSL_String(id));
@@ -10588,11 +11503,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10588 case ScriptBaseClass.OBJECT_NAME: 11503 case ScriptBaseClass.OBJECT_NAME:
10589 ret.Add(new LSL_String(obj.Name)); 11504 ret.Add(new LSL_String(obj.Name));
10590 break; 11505 break;
10591 case ScriptBaseClass.OBJECT_DESC: 11506 case ScriptBaseClass.OBJECT_DESC:
10592 ret.Add(new LSL_String(obj.Description)); 11507 ret.Add(new LSL_String(obj.Description));
10593 break; 11508 break;
10594 case ScriptBaseClass.OBJECT_POS: 11509 case ScriptBaseClass.OBJECT_POS:
10595 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11510 Vector3 opos = obj.AbsolutePosition;
11511 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10596 break; 11512 break;
10597 case ScriptBaseClass.OBJECT_ROT: 11513 case ScriptBaseClass.OBJECT_ROT:
10598 { 11514 {
@@ -10642,9 +11558,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10642 // The value returned in SL for normal prims is prim count 11558 // The value returned in SL for normal prims is prim count
10643 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11559 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10644 break; 11560 break;
10645 // The following 3 costs I have intentionaly coded to return zero. They are part of 11561
10646 // "Land Impact" calculations. These calculations are probably not applicable 11562 // costs below may need to be diferent for root parts, need to check
10647 // to OpenSim and are not yet complete in SL
10648 case ScriptBaseClass.OBJECT_SERVER_COST: 11563 case ScriptBaseClass.OBJECT_SERVER_COST:
10649 // The linden calculation is here 11564 // The linden calculation is here
10650 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11565 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10652,16 +11567,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10652 ret.Add(new LSL_Float(0)); 11567 ret.Add(new LSL_Float(0));
10653 break; 11568 break;
10654 case ScriptBaseClass.OBJECT_STREAMING_COST: 11569 case ScriptBaseClass.OBJECT_STREAMING_COST:
10655 // The linden calculation is here 11570 // The value returned in SL for normal prims is prim count * 0.06
10656 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11571 ret.Add(new LSL_Float(obj.StreamingCost));
10657 // The value returned in SL for normal prims looks like the prim count * 0.06
10658 ret.Add(new LSL_Float(0));
10659 break; 11572 break;
10660 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11573 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10661 // The linden calculation is here 11574 // The value returned in SL for normal prims is prim count
10662 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11575 ret.Add(new LSL_Float(obj.PhysicsCost));
10663 // The value returned in SL for normal prims looks like the prim count
10664 ret.Add(new LSL_Float(0));
10665 break; 11576 break;
10666 default: 11577 default:
10667 // Invalid or unhandled constant. 11578 // Invalid or unhandled constant.
@@ -10872,15 +11783,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10872 return result; 11783 return result;
10873 } 11784 }
10874 11785
10875 public void print(string str) 11786 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10876 { 11787 {
10877 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11788 List<SceneObjectPart> parts = GetLinkParts(link);
10878 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11789 if (parts.Count < 1)
10879 if (ossl != null) 11790 return 0;
10880 { 11791
10881 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11792 return GetNumberOfSides(parts[0]);
10882 m_log.Info("LSL print():" + str);
10883 }
10884 } 11793 }
10885 11794
10886 private string Name2Username(string name) 11795 private string Name2Username(string name)
@@ -10925,7 +11834,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10925 11834
10926 return rq.ToString(); 11835 return rq.ToString();
10927 } 11836 }
10928 11837/*
11838 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11839 {
11840 m_SayShoutCount = 0;
11841 }
11842*/
10929 private struct Tri 11843 private struct Tri
10930 { 11844 {
10931 public Vector3 p1; 11845 public Vector3 p1;
@@ -11065,9 +11979,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11065 11979
11066 ContactResult result = new ContactResult (); 11980 ContactResult result = new ContactResult ();
11067 result.ConsumerID = group.LocalId; 11981 result.ConsumerID = group.LocalId;
11068 result.Depth = intersection.distance; 11982// result.Depth = intersection.distance;
11069 result.Normal = intersection.normal; 11983 result.Normal = intersection.normal;
11070 result.Pos = intersection.ipoint; 11984 result.Pos = intersection.ipoint;
11985 result.Depth = Vector3.Mag(rayStart - result.Pos);
11071 11986
11072 contacts.Add(result); 11987 contacts.Add(result);
11073 }); 11988 });
@@ -11200,6 +12115,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11200 12115
11201 return contacts[0]; 12116 return contacts[0];
11202 } 12117 }
12118/*
12119 // not done:
12120 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12121 {
12122 ContactResult[] contacts = null;
12123 World.ForEachSOG(delegate(SceneObjectGroup group)
12124 {
12125 if (m_host.ParentGroup == group)
12126 return;
12127
12128 if (group.IsAttachment)
12129 return;
12130
12131 if(group.RootPart.PhysActor != null)
12132 return;
12133
12134 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12135 });
12136 return contacts;
12137 }
12138*/
11203 12139
11204 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12140 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11205 { 12141 {
@@ -11241,32 +12177,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11241 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12177 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11242 12178
11243 12179
11244 if (checkTerrain) 12180 if (World.SuportsRayCastFiltered())
11245 { 12181 {
11246 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12182 if (dist == 0)
11247 if (groundContact != null) 12183 return list;
11248 results.Add((ContactResult)groundContact);
11249 }
11250 12184
11251 if (checkAgents) 12185 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11252 { 12186 if (checkTerrain)
11253 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12187 rayfilter |= RayFilterFlags.land;
11254 foreach (ContactResult r in agentHits) 12188// if (checkAgents)
11255 results.Add(r); 12189// rayfilter |= RayFilterFlags.agent;
11256 } 12190 if (checkPhysical)
12191 rayfilter |= RayFilterFlags.physical;
12192 if (checkNonPhysical)
12193 rayfilter |= RayFilterFlags.nonphysical;
12194 if (detectPhantom)
12195 rayfilter |= RayFilterFlags.LSLPhanton;
12196
12197 Vector3 direction = dir * ( 1/dist);
11257 12198
11258 if (checkPhysical || checkNonPhysical || detectPhantom) 12199 if(rayfilter == 0)
12200 {
12201 list.Add(new LSL_Integer(0));
12202 return list;
12203 }
12204
12205 // get some more contacts to sort ???
12206 int physcount = 4 * count;
12207 if (physcount > 20)
12208 physcount = 20;
12209
12210 object physresults;
12211 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12212
12213 if (physresults == null)
12214 {
12215 list.Add(new LSL_Integer(-3)); // timeout error
12216 return list;
12217 }
12218
12219 results = (List<ContactResult>)physresults;
12220
12221 // for now physics doesn't detect sitted avatars so do it outside physics
12222 if (checkAgents)
12223 {
12224 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12225 foreach (ContactResult r in agentHits)
12226 results.Add(r);
12227 }
12228
12229 // TODO: Replace this with a better solution. ObjectIntersection can only
12230 // detect nonphysical phantoms. They are detected by virtue of being
12231 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12232 // physicsl phantoms as done by the physics scene
12233 // We don't want anything else but phantoms here.
12234 if (detectPhantom)
12235 {
12236 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12237 foreach (ContactResult r in objectHits)
12238 results.Add(r);
12239 }
12240 }
12241 else
11259 { 12242 {
11260 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12243 if (checkTerrain)
11261 foreach (ContactResult r in objectHits) 12244 {
11262 results.Add(r); 12245 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12246 if (groundContact != null)
12247 results.Add((ContactResult)groundContact);
12248 }
12249
12250 if (checkAgents)
12251 {
12252 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12253 foreach (ContactResult r in agentHits)
12254 results.Add(r);
12255 }
12256
12257 if (checkPhysical || checkNonPhysical || detectPhantom)
12258 {
12259 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12260 foreach (ContactResult r in objectHits)
12261 results.Add(r);
12262 }
11263 } 12263 }
11264 12264
11265 results.Sort(delegate(ContactResult a, ContactResult b) 12265 results.Sort(delegate(ContactResult a, ContactResult b)
11266 { 12266 {
11267 return a.Depth.CompareTo(b.Depth); 12267 return a.Depth.CompareTo(b.Depth);
11268 }); 12268 });
11269 12269
11270 int values = 0; 12270 int values = 0;
11271 SceneObjectGroup thisgrp = m_host.ParentGroup; 12271 SceneObjectGroup thisgrp = m_host.ParentGroup;
11272 12272
@@ -11359,7 +12359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11359 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12359 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11360 if (!isAccount) return 0; 12360 if (!isAccount) return 0;
11361 if (estate.HasAccess(id)) return 1; 12361 if (estate.HasAccess(id)) return 1;
11362 if (estate.IsBanned(id)) 12362 if (estate.IsBanned(id, World.GetUserFlags(id)))
11363 estate.RemoveBan(id); 12363 estate.RemoveBan(id);
11364 estate.AddEstateUser(id); 12364 estate.AddEstateUser(id);
11365 break; 12365 break;
@@ -11378,14 +12378,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11378 break; 12378 break;
11379 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12379 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11380 if (!isAccount) return 0; 12380 if (!isAccount) return 0;
11381 if (estate.IsBanned(id)) return 1; 12381 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11382 EstateBan ban = new EstateBan(); 12382 EstateBan ban = new EstateBan();
11383 ban.EstateID = estate.EstateID; 12383 ban.EstateID = estate.EstateID;
11384 ban.BannedUserID = id; 12384 ban.BannedUserID = id;
11385 estate.AddBan(ban); 12385 estate.AddBan(ban);
11386 break; 12386 break;
11387 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12387 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11388 if (!isAccount || !estate.IsBanned(id)) return 0; 12388 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11389 estate.RemoveBan(id); 12389 estate.RemoveBan(id);
11390 break; 12390 break;
11391 default: return 0; 12391 default: return 0;
@@ -11414,7 +12414,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11414 return 16384; 12414 return 16384;
11415 } 12415 }
11416 12416
11417 public LSL_Integer llGetUsedMemory() 12417 public virtual LSL_Integer llGetUsedMemory()
11418 { 12418 {
11419 m_host.AddScriptLPS(1); 12419 m_host.AddScriptLPS(1);
11420 // The value returned for LSO scripts in SL 12420 // The value returned for LSO scripts in SL
@@ -11442,22 +12442,734 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11442 public void llSetSoundQueueing(int queue) 12442 public void llSetSoundQueueing(int queue)
11443 { 12443 {
11444 m_host.AddScriptLPS(1); 12444 m_host.AddScriptLPS(1);
11445 NotImplemented("llSetSoundQueueing");
11446 } 12445 }
11447 12446
11448 public void llCollisionSprite(string impact_sprite) 12447 public void llCollisionSprite(string impact_sprite)
11449 { 12448 {
11450 m_host.AddScriptLPS(1); 12449 m_host.AddScriptLPS(1);
11451 NotImplemented("llCollisionSprite"); 12450 // Viewer 2.0 broke this and it's likely LL has no intention
12451 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11452 } 12452 }
11453 12453
11454 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12454 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11455 { 12455 {
11456 m_host.AddScriptLPS(1); 12456 m_host.AddScriptLPS(1);
11457 NotImplemented("llGodLikeRezObject"); 12457
12458 if (!World.Permissions.IsGod(m_host.OwnerID))
12459 NotImplemented("llGodLikeRezObject");
12460
12461 AssetBase rezAsset = World.AssetService.Get(inventory);
12462 if (rezAsset == null)
12463 {
12464 llSay(0, "Asset not found");
12465 return;
12466 }
12467
12468 SceneObjectGroup group = null;
12469
12470 try
12471 {
12472 string xmlData = Utils.BytesToString(rezAsset.Data);
12473 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12474 }
12475 catch
12476 {
12477 llSay(0, "Asset not found");
12478 return;
12479 }
12480
12481 if (group == null)
12482 {
12483 llSay(0, "Asset not found");
12484 return;
12485 }
12486
12487 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12488 group.RootPart.AttachOffset = group.AbsolutePosition;
12489
12490 group.ResetIDs();
12491
12492 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12493 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12494 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12495 group.ScheduleGroupForFullUpdate();
12496
12497 // objects rezzed with this method are die_at_edge by default.
12498 group.RootPart.SetDieAtEdge(true);
12499
12500 group.ResumeScripts();
12501
12502 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12503 "object_rez", new Object[] {
12504 new LSL_String(
12505 group.RootPart.UUID.ToString()) },
12506 new DetectParams[0]));
12507 }
12508
12509 public LSL_String llTransferLindenDollars(string destination, int amount)
12510 {
12511 UUID txn = UUID.Random();
12512
12513 Util.FireAndForget(delegate(object x)
12514 {
12515 int replycode = 0;
12516 string replydata = destination + "," + amount.ToString();
12517
12518 try
12519 {
12520 TaskInventoryItem item = m_item;
12521 if (item == null)
12522 {
12523 replydata = "SERVICE_ERROR";
12524 return;
12525 }
12526
12527 m_host.AddScriptLPS(1);
12528
12529 if (item.PermsGranter == UUID.Zero)
12530 {
12531 replydata = "MISSING_PERMISSION_DEBIT";
12532 return;
12533 }
12534
12535 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12536 {
12537 replydata = "MISSING_PERMISSION_DEBIT";
12538 return;
12539 }
12540
12541 UUID toID = new UUID();
12542
12543 if (!UUID.TryParse(destination, out toID))
12544 {
12545 replydata = "INVALID_AGENT";
12546 return;
12547 }
12548
12549 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12550
12551 if (money == null)
12552 {
12553 replydata = "TRANSFERS_DISABLED";
12554 return;
12555 }
12556
12557 bool result = money.ObjectGiveMoney(
12558 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12559
12560 if (result)
12561 {
12562 replycode = 1;
12563 return;
12564 }
12565
12566 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12567 }
12568 finally
12569 {
12570 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12571 "transaction_result", new Object[] {
12572 new LSL_String(txn.ToString()),
12573 new LSL_Integer(replycode),
12574 new LSL_String(replydata) },
12575 new DetectParams[0]));
12576 }
12577 });
12578
12579 return txn.ToString();
11458 } 12580 }
11459 12581
11460 #endregion 12582 #endregion
12583
12584 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12585 {
12586 SceneObjectGroup group = m_host.ParentGroup;
12587
12588 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12589 return;
12590 if (group.IsAttachment)
12591 return;
12592
12593 if (frames.Data.Length > 0) // We are getting a new motion
12594 {
12595 if (group.RootPart.KeyframeMotion != null)
12596 group.RootPart.KeyframeMotion.Delete();
12597 group.RootPart.KeyframeMotion = null;
12598
12599 int idx = 0;
12600
12601 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12602 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12603
12604 while (idx < options.Data.Length)
12605 {
12606 int option = (int)options.GetLSLIntegerItem(idx++);
12607 int remain = options.Data.Length - idx;
12608
12609 switch (option)
12610 {
12611 case ScriptBaseClass.KFM_MODE:
12612 if (remain < 1)
12613 break;
12614 int modeval = (int)options.GetLSLIntegerItem(idx++);
12615 switch(modeval)
12616 {
12617 case ScriptBaseClass.KFM_FORWARD:
12618 mode = KeyframeMotion.PlayMode.Forward;
12619 break;
12620 case ScriptBaseClass.KFM_REVERSE:
12621 mode = KeyframeMotion.PlayMode.Reverse;
12622 break;
12623 case ScriptBaseClass.KFM_LOOP:
12624 mode = KeyframeMotion.PlayMode.Loop;
12625 break;
12626 case ScriptBaseClass.KFM_PING_PONG:
12627 mode = KeyframeMotion.PlayMode.PingPong;
12628 break;
12629 }
12630 break;
12631 case ScriptBaseClass.KFM_DATA:
12632 if (remain < 1)
12633 break;
12634 int dataval = (int)options.GetLSLIntegerItem(idx++);
12635 data = (KeyframeMotion.DataFormat)dataval;
12636 break;
12637 }
12638 }
12639
12640 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12641
12642 idx = 0;
12643
12644 int elemLength = 2;
12645 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12646 elemLength = 3;
12647
12648 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12649 while (idx < frames.Data.Length)
12650 {
12651 int remain = frames.Data.Length - idx;
12652
12653 if (remain < elemLength)
12654 break;
12655
12656 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12657 frame.Position = null;
12658 frame.Rotation = null;
12659
12660 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12661 {
12662 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12663 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12664 }
12665 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12666 {
12667 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12668 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12669 }
12670
12671 float tempf = (float)frames.GetLSLFloatItem(idx++);
12672 frame.TimeMS = (int)(tempf * 1000.0f);
12673
12674 keyframes.Add(frame);
12675 }
12676
12677 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12678 group.RootPart.KeyframeMotion.Start();
12679 }
12680 else
12681 {
12682 if (group.RootPart.KeyframeMotion == null)
12683 return;
12684
12685 if (options.Data.Length == 0)
12686 {
12687 group.RootPart.KeyframeMotion.Stop();
12688 return;
12689 }
12690
12691 int code = (int)options.GetLSLIntegerItem(0);
12692
12693 int idx = 0;
12694
12695 while (idx < options.Data.Length)
12696 {
12697 int option = (int)options.GetLSLIntegerItem(idx++);
12698 int remain = options.Data.Length - idx;
12699
12700 switch (option)
12701 {
12702 case ScriptBaseClass.KFM_COMMAND:
12703 int cmd = (int)options.GetLSLIntegerItem(idx++);
12704 switch (cmd)
12705 {
12706 case ScriptBaseClass.KFM_CMD_PLAY:
12707 group.RootPart.KeyframeMotion.Start();
12708 break;
12709 case ScriptBaseClass.KFM_CMD_STOP:
12710 group.RootPart.KeyframeMotion.Stop();
12711 break;
12712 case ScriptBaseClass.KFM_CMD_PAUSE:
12713 group.RootPart.KeyframeMotion.Pause();
12714 break;
12715 }
12716 break;
12717 }
12718 }
12719 }
12720 }
12721
12722 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12723 {
12724 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12725
12726 int idx = 0;
12727 int idxStart = 0;
12728
12729 bool positionChanged = false;
12730 Vector3 finalPos = Vector3.Zero;
12731
12732 try
12733 {
12734 while (idx < rules.Length)
12735 {
12736 ++rulesParsed;
12737 int code = rules.GetLSLIntegerItem(idx++);
12738
12739 int remain = rules.Length - idx;
12740 idxStart = idx;
12741
12742 switch (code)
12743 {
12744 case (int)ScriptBaseClass.PRIM_POSITION:
12745 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12746 {
12747 if (remain < 1)
12748 return null;
12749
12750 LSL_Vector v;
12751 v = rules.GetVector3Item(idx++);
12752
12753 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12754 if (part == null)
12755 break;
12756
12757 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12758 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12759 if (part.LinkNum > 1)
12760 {
12761 localRot = GetPartLocalRot(part);
12762 localPos = GetPartLocalPos(part);
12763 }
12764
12765 v -= localPos;
12766 v /= localRot;
12767
12768 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12769
12770 v = v + 2 * sitOffset;
12771
12772 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12773 av.SendAvatarDataToAllAgents();
12774
12775 }
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12779 case (int)ScriptBaseClass.PRIM_ROTATION:
12780 {
12781 if (remain < 1)
12782 return null;
12783
12784 LSL_Rotation r;
12785 r = rules.GetQuaternionItem(idx++);
12786
12787 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12788 if (part == null)
12789 break;
12790
12791 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12792 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12793
12794 if (part.LinkNum > 1)
12795 localRot = GetPartLocalRot(part);
12796
12797 r = r * llGetRootRotation() / localRot;
12798 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12799 av.SendAvatarDataToAllAgents();
12800 }
12801 break;
12802
12803 // parse rest doing nothing but number of parameters error check
12804 case (int)ScriptBaseClass.PRIM_SIZE:
12805 case (int)ScriptBaseClass.PRIM_MATERIAL:
12806 case (int)ScriptBaseClass.PRIM_PHANTOM:
12807 case (int)ScriptBaseClass.PRIM_PHYSICS:
12808 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12809 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12810 case (int)ScriptBaseClass.PRIM_NAME:
12811 case (int)ScriptBaseClass.PRIM_DESC:
12812 if (remain < 1)
12813 return null;
12814 idx++;
12815 break;
12816
12817 case (int)ScriptBaseClass.PRIM_GLOW:
12818 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12819 case (int)ScriptBaseClass.PRIM_TEXGEN:
12820 if (remain < 2)
12821 return null;
12822 idx += 2;
12823 break;
12824
12825 case (int)ScriptBaseClass.PRIM_TYPE:
12826 if (remain < 3)
12827 return null;
12828 code = (int)rules.GetLSLIntegerItem(idx++);
12829 remain = rules.Length - idx;
12830 switch (code)
12831 {
12832 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12833 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12834 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12835 if (remain < 6)
12836 return null;
12837 idx += 6;
12838 break;
12839
12840 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12841 if (remain < 5)
12842 return null;
12843 idx += 5;
12844 break;
12845
12846 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12847 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12848 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12849 if (remain < 11)
12850 return null;
12851 idx += 11;
12852 break;
12853
12854 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12855 if (remain < 2)
12856 return null;
12857 idx += 2;
12858 break;
12859 }
12860 break;
12861
12862 case (int)ScriptBaseClass.PRIM_COLOR:
12863 case (int)ScriptBaseClass.PRIM_TEXT:
12864 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12865 case (int)ScriptBaseClass.PRIM_OMEGA:
12866 if (remain < 3)
12867 return null;
12868 idx += 3;
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_TEXTURE:
12872 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12873 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12874 if (remain < 5)
12875 return null;
12876 idx += 5;
12877 break;
12878
12879 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12880 if (remain < 7)
12881 return null;
12882
12883 idx += 7;
12884 break;
12885
12886 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12887 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12888 return null;
12889
12890 return rules.GetSublist(idx, -1);
12891 }
12892 }
12893 }
12894 catch (InvalidCastException e)
12895 {
12896 ShoutError(string.Format(
12897 "{0} error running rule #{1}: arg #{2} ",
12898 originFunc, rulesParsed, idx - idxStart) + e.Message);
12899 }
12900 finally
12901 {
12902 if (positionChanged)
12903 {
12904 av.OffsetPosition = finalPos;
12905// av.SendAvatarDataToAllAgents();
12906 av.SendTerseUpdateToAllClients();
12907 positionChanged = false;
12908 }
12909 }
12910 return null;
12911 }
12912
12913 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12914 {
12915 // avatars case
12916 // replies as SL wiki
12917
12918// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12919 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12920
12921 int idx = 0;
12922 while (idx < rules.Length)
12923 {
12924 int code = (int)rules.GetLSLIntegerItem(idx++);
12925 int remain = rules.Length - idx;
12926
12927 switch (code)
12928 {
12929 case (int)ScriptBaseClass.PRIM_MATERIAL:
12930 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12931 break;
12932
12933 case (int)ScriptBaseClass.PRIM_PHYSICS:
12934 res.Add(new LSL_Integer(0));
12935 break;
12936
12937 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12938 res.Add(new LSL_Integer(0));
12939 break;
12940
12941 case (int)ScriptBaseClass.PRIM_PHANTOM:
12942 res.Add(new LSL_Integer(0));
12943 break;
12944
12945 case (int)ScriptBaseClass.PRIM_POSITION:
12946
12947 Vector3 pos = avatar.OffsetPosition;
12948
12949 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12950 pos -= sitOffset;
12951
12952 if( sitPart != null)
12953 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12954
12955 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12956 break;
12957
12958 case (int)ScriptBaseClass.PRIM_SIZE:
12959 // as in llGetAgentSize above
12960// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12961 Vector3 s = avatar.Appearance.AvatarSize;
12962 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
12963
12964 break;
12965
12966 case (int)ScriptBaseClass.PRIM_ROTATION:
12967 Quaternion rot = avatar.Rotation;
12968 if (sitPart != null)
12969 {
12970 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12971 }
12972
12973 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12974 break;
12975
12976 case (int)ScriptBaseClass.PRIM_TYPE:
12977 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12979 res.Add(new LSL_Vector(0f,1.0f,0f));
12980 res.Add(new LSL_Float(0.0f));
12981 res.Add(new LSL_Vector(0, 0, 0));
12982 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12983 res.Add(new LSL_Vector(0, 0, 0));
12984 break;
12985
12986 case (int)ScriptBaseClass.PRIM_TEXTURE:
12987 if (remain < 1)
12988 return null;
12989
12990 int face = (int)rules.GetLSLIntegerItem(idx++);
12991 if (face == ScriptBaseClass.ALL_SIDES)
12992 {
12993 for (face = 0; face < 21; face++)
12994 {
12995 res.Add(new LSL_String(""));
12996 res.Add(new LSL_Vector(0,0,0));
12997 res.Add(new LSL_Vector(0,0,0));
12998 res.Add(new LSL_Float(0.0));
12999 }
13000 }
13001 else
13002 {
13003 if (face >= 0 && face < 21)
13004 {
13005 res.Add(new LSL_String(""));
13006 res.Add(new LSL_Vector(0,0,0));
13007 res.Add(new LSL_Vector(0,0,0));
13008 res.Add(new LSL_Float(0.0));
13009 }
13010 }
13011 break;
13012
13013 case (int)ScriptBaseClass.PRIM_COLOR:
13014 if (remain < 1)
13015 return null;
13016
13017 face = (int)rules.GetLSLIntegerItem(idx++);
13018
13019 if (face == ScriptBaseClass.ALL_SIDES)
13020 {
13021 for (face = 0; face < 21; face++)
13022 {
13023 res.Add(new LSL_Vector(0,0,0));
13024 res.Add(new LSL_Float(0));
13025 }
13026 }
13027 else
13028 {
13029 res.Add(new LSL_Vector(0,0,0));
13030 res.Add(new LSL_Float(0));
13031 }
13032 break;
13033
13034 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13035 if (remain < 1)
13036 return null;
13037 face = (int)rules.GetLSLIntegerItem(idx++);
13038
13039 if (face == ScriptBaseClass.ALL_SIDES)
13040 {
13041 for (face = 0; face < 21; face++)
13042 {
13043 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13044 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13045 }
13046 }
13047 else
13048 {
13049 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13050 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13051 }
13052 break;
13053
13054 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13055 if (remain < 1)
13056 return null;
13057 face = (int)rules.GetLSLIntegerItem(idx++);
13058
13059 if (face == ScriptBaseClass.ALL_SIDES)
13060 {
13061 for (face = 0; face < 21; face++)
13062 {
13063 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13064 }
13065 }
13066 else
13067 {
13068 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13069 }
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13073 res.Add(new LSL_Integer(0));
13074 res.Add(new LSL_Integer(0));// softness
13075 res.Add(new LSL_Float(0.0f)); // gravity
13076 res.Add(new LSL_Float(0.0f)); // friction
13077 res.Add(new LSL_Float(0.0f)); // wind
13078 res.Add(new LSL_Float(0.0f)); // tension
13079 res.Add(new LSL_Vector(0f,0f,0f));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_TEXGEN:
13083 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13084 if (remain < 1)
13085 return null;
13086 face = (int)rules.GetLSLIntegerItem(idx++);
13087
13088 if (face == ScriptBaseClass.ALL_SIDES)
13089 {
13090 for (face = 0; face < 21; face++)
13091 {
13092 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13093 }
13094 }
13095 else
13096 {
13097 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13098 }
13099 break;
13100
13101 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13102 res.Add(new LSL_Integer(0));
13103 res.Add(new LSL_Vector(0f,0f,0f));
13104 res.Add(new LSL_Float(0f)); // intensity
13105 res.Add(new LSL_Float(0f)); // radius
13106 res.Add(new LSL_Float(0f)); // falloff
13107 break;
13108
13109 case (int)ScriptBaseClass.PRIM_GLOW:
13110 if (remain < 1)
13111 return null;
13112 face = (int)rules.GetLSLIntegerItem(idx++);
13113
13114 if (face == ScriptBaseClass.ALL_SIDES)
13115 {
13116 for (face = 0; face < 21; face++)
13117 {
13118 res.Add(new LSL_Float(0f));
13119 }
13120 }
13121 else
13122 {
13123 res.Add(new LSL_Float(0f));
13124 }
13125 break;
13126
13127 case (int)ScriptBaseClass.PRIM_TEXT:
13128 res.Add(new LSL_String(""));
13129 res.Add(new LSL_Vector(0f,0f,0f));
13130 res.Add(new LSL_Float(1.0f));
13131 break;
13132
13133 case (int)ScriptBaseClass.PRIM_NAME:
13134 res.Add(new LSL_String(avatar.Name));
13135 break;
13136
13137 case (int)ScriptBaseClass.PRIM_DESC:
13138 res.Add(new LSL_String(""));
13139 break;
13140
13141 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13142 Quaternion lrot = avatar.Rotation;
13143
13144 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13145 {
13146 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13147 }
13148 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13149 break;
13150
13151 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13152 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13153 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13154 lpos -= lsitOffset;
13155
13156 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13157 {
13158 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13159 }
13160 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13161 break;
13162
13163 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13164 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13165 return null;
13166
13167 return rules.GetSublist(idx, -1);
13168 }
13169 }
13170
13171 return null;
13172 }
11461 } 13173 }
11462 13174
11463 public class NotecardCache 13175 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 }