aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3153
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-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.cs28
-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.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs360
19 files changed, 3168 insertions, 1001 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 5b22860..693992a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -304,6 +304,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 return null; 304 return null;
305 } 305 }
306 306
307 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
308 {
309 // Remove a specific script
310
311 // Remove dataserver events
312 m_Dataserver[engine].RemoveEvents(localID, itemID);
313
314 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
315 if (comms != null)
316 comms.DeleteListener(itemID);
317
318 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
319 xmlrpc.DeleteChannels(itemID);
320 xmlrpc.CancelSRDRequests(itemID);
321
322 // Remove Sensors
323 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
324
325 }
326
307 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 327 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
308 { 328 {
309 List<Object> data = new List<Object>(); 329 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 f88338d..6ec3081 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
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;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -236,9 +279,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 279 }
237 } 280 }
238 281
282 public List<ScenePresence> GetLinkAvatars(int linkType)
283 {
284 List<ScenePresence> ret = new List<ScenePresence>();
285 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
286 return ret;
287
288 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
289
290 switch (linkType)
291 {
292 case ScriptBaseClass.LINK_SET:
293 return avs;
294
295 case ScriptBaseClass.LINK_ROOT:
296 return ret;
297
298 case ScriptBaseClass.LINK_ALL_OTHERS:
299 return avs;
300
301 case ScriptBaseClass.LINK_ALL_CHILDREN:
302 return avs;
303
304 case ScriptBaseClass.LINK_THIS:
305 return ret;
306
307 default:
308 if (linkType < 0)
309 return ret;
310
311 int partCount = m_host.ParentGroup.GetPartCount();
312
313 if (linkType <= partCount)
314 {
315 return ret;
316 }
317 else
318 {
319 linkType = linkType - partCount;
320 if (linkType > avs.Count)
321 {
322 return ret;
323 }
324 else
325 {
326 ret.Add(avs[linkType-1]);
327 return ret;
328 }
329 }
330 }
331 }
332
239 public List<SceneObjectPart> GetLinkParts(int linkType) 333 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 334 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 335 List<SceneObjectPart> ret = new List<SceneObjectPart>();
336 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
337 return ret;
242 ret.Add(m_host); 338 ret.Add(m_host);
243 339
244 switch (linkType) 340 switch (linkType)
@@ -437,31 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
437 533
438 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
439 535
440 /// <summary> 536 // Utility function for llRot2Euler
441 /// Convert an LSL rotation to a Euler vector. 537
442 /// </summary> 538 // normalize an angle between -PI and PI (-180 to +180 degrees)
443 /// <remarks> 539 protected double NormalizeAngle(double angle)
444 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
445 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
446 /// </remarks>
447 /// <param name="r"></param>
448 /// <returns></returns>
449 public LSL_Vector llRot2Euler(LSL_Rotation r)
450 { 540 {
451 m_host.AddScriptLPS(1); 541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
452 543
453 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 544 int numPis = (int)(Math.PI / angle);
454 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 545 double remainder = angle - Math.PI * numPis;
455 if (m == 0.0) return new LSL_Vector(); 546 if (numPis % 2 == 1)
456 double x = Math.Atan2(-v.y, v.z); 547 return Math.PI - angle;
457 double sin = v.x / m; 548 return remainder;
458 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 549 }
459 double y = Math.Asin(sin);
460 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
461 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)));
462 double z = Math.Atan2(v.y, v.x);
463 550
464 return new LSL_Vector(x, y, z); 551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
552 {
553 m_host.AddScriptLPS(1);
554 LSL_Vector eul = new LSL_Vector();
555
556 double sqw = q1.s*q1.s;
557 double sqx = q1.x*q1.x;
558 double sqy = q1.z*q1.z;
559 double sqz = q1.y*q1.y;
560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
561 double test = q1.x*q1.z + q1.y*q1.s;
562 if (test > 0.4999*unit) { // singularity at north pole
563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
564 eul.y = Math.PI/2;
565 eul.x = 0;
566 return eul;
567 }
568 if (test < -0.4999*unit) { // singularity at south pole
569 eul.z = -2 * Math.Atan2(q1.x,q1.s);
570 eul.y = -Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
465 } 578 }
466 579
467 /* From wiki: 580 /* From wiki:
@@ -514,18 +627,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
514 m_host.AddScriptLPS(1); 627 m_host.AddScriptLPS(1);
515 628
516 double x,y,z,s; 629 double x,y,z,s;
517 630 v.x *= 0.5;
518 double c1 = Math.Cos(v.x * 0.5); 631 v.y *= 0.5;
519 double c2 = Math.Cos(v.y * 0.5); 632 v.z *= 0.5;
520 double c3 = Math.Cos(v.z * 0.5); 633 double c1 = Math.Cos(v.x);
521 double s1 = Math.Sin(v.x * 0.5); 634 double c2 = Math.Cos(v.y);
522 double s2 = Math.Sin(v.y * 0.5); 635 double c1c2 = c1 * c2;
523 double s3 = Math.Sin(v.z * 0.5); 636 double s1 = Math.Sin(v.x);
524 637 double s2 = Math.Sin(v.y);
525 x = s1 * c2 * c3 + c1 * s2 * s3; 638 double s1s2 = s1 * s2;
526 y = c1 * s2 * c3 - s1 * c2 * s3; 639 double c1s2 = c1 * s2;
527 z = s1 * s2 * c3 + c1 * c2 * s3; 640 double s1c2 = s1 * c2;
528 s = c1 * c2 * c3 - s1 * s2 * s3; 641 double c3 = Math.Cos(v.z);
642 double s3 = Math.Sin(v.z);
643
644 x = s1c2 * c3 + c1s2 * s3;
645 y = c1s2 * c3 - s1c2 * s3;
646 z = s1s2 * c3 + c1c2 * s3;
647 s = c1c2 * c3 - s1s2 * s3;
529 648
530 return new LSL_Rotation(x, y, z, s); 649 return new LSL_Rotation(x, y, z, s);
531 } 650 }
@@ -663,77 +782,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
663 { 782 {
664 //A and B should both be normalized 783 //A and B should both be normalized
665 m_host.AddScriptLPS(1); 784 m_host.AddScriptLPS(1);
666 LSL_Rotation rotBetween; 785 /* This method is more accurate than the SL one, and thus causes problems
667 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 786 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
668 // continue calculation. 787
669 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 788 double dotProduct = LSL_Vector.Dot(a, b);
789 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
790 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
791 double angle = Math.Acos(dotProduct / magProduct);
792 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
793 double s = Math.Sin(angle / 2);
794
795 double x = axis.x * s;
796 double y = axis.y * s;
797 double z = axis.z * s;
798 double w = Math.Cos(angle / 2);
799
800 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
801 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
802
803 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
804 */
805
806 // This method mimics the 180 errors found in SL
807 // See www.euclideanspace.com... angleBetween
808 LSL_Vector vec_a = a;
809 LSL_Vector vec_b = b;
810
811 // Eliminate zero length
812 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
813 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
814 if (vec_a_mag < 0.00001 ||
815 vec_b_mag < 0.00001)
670 { 816 {
671 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 817 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
672 } 818 }
673 else 819
820 // Normalize
821 vec_a = llVecNorm(vec_a);
822 vec_b = llVecNorm(vec_b);
823
824 // Calculate axis and rotation angle
825 LSL_Vector axis = vec_a % vec_b;
826 LSL_Float cos_theta = vec_a * vec_b;
827
828 // Check if parallel
829 if (cos_theta > 0.99999)
674 { 830 {
675 a = LSL_Vector.Norm(a); 831 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
676 b = LSL_Vector.Norm(b); 832 }
677 double dotProduct = LSL_Vector.Dot(a, b); 833
678 // There are two degenerate cases possible. These are for vectors 180 or 834 // Check if anti-parallel
679 // 0 degrees apart. These have to be detected and handled individually. 835 else if (cos_theta < -0.99999)
680 // 836 {
681 // Check for vectors 180 degrees apart. 837 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
682 // A dot product of -1 would mean the angle between vectors is 180 degrees. 838 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
683 if (dotProduct < -0.9999999f) 839 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
684 { 840 }
685 // First assume X axis is orthogonal to the vectors. 841 else // other rotation
686 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 842 {
687 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 843 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
688 // Check for near zero vector. A very small non-zero number here will create 844 axis = llVecNorm(axis);
689 // a rotation in an undesired direction. 845 double x, y, z, s, t;
690 if (LSL_Vector.Mag(orthoVector) > 0.0001) 846 s = Math.Cos(theta);
691 { 847 t = Math.Sin(theta);
692 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 848 x = axis.x * t;
693 } 849 y = axis.y * t;
694 // If the magnitude of the vector was near zero, then assume the X axis is not 850 z = axis.z * t;
695 // orthogonal and use the Z axis instead. 851 return new LSL_Rotation(x,y,z,s);
696 else
697 {
698 // Set 180 z rotation.
699 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
700 }
701 }
702 // Check for parallel vectors.
703 // A dot product of 1 would mean the angle between vectors is 0 degrees.
704 else if (dotProduct > 0.9999999f)
705 {
706 // Set zero rotation.
707 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
708 }
709 else
710 {
711 // All special checks have been performed so get the axis of rotation.
712 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
713 // Quarternion s value is the length of the unit vector + dot product.
714 double qs = 1.0 + dotProduct;
715 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
716 // Normalize the rotation.
717 double mag = LSL_Rotation.Mag(rotBetween);
718 // We shouldn't have to worry about a divide by zero here. The qs value will be
719 // non-zero because we already know if we're here, then the dotProduct is not -1 so
720 // qs will not be zero. Also, we've already handled the input vectors being zero so the
721 // crossProduct vector should also not be zero.
722 rotBetween.x = rotBetween.x / mag;
723 rotBetween.y = rotBetween.y / mag;
724 rotBetween.z = rotBetween.z / mag;
725 rotBetween.s = rotBetween.s / mag;
726 // Check for undefined values and set zero rotation if any found. This code might not actually be required
727 // any longer since zero vectors are checked for at the top.
728 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
729 {
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 }
733 } 852 }
734 return rotBetween;
735 } 853 }
736 854
737 public void llWhisper(int channelID, string text) 855 public void llWhisper(int channelID, string text)
738 { 856 {
739 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
@@ -749,10 +867,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
749 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 867 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
750 } 868 }
751 869
870 private void CheckSayShoutTime()
871 {
872 DateTime now = DateTime.UtcNow;
873 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
874 {
875 m_lastSayShoutCheck = now;
876 m_SayShoutCount = 0;
877 }
878 else
879 m_SayShoutCount++;
880 }
881
752 public void llSay(int channelID, string text) 882 public void llSay(int channelID, string text)
753 { 883 {
754 m_host.AddScriptLPS(1); 884 m_host.AddScriptLPS(1);
755 885
886 if (channelID == 0)
887// m_SayShoutCount++;
888 CheckSayShoutTime();
889
890 if (m_SayShoutCount >= 11)
891 ScriptSleep(2000);
892
756 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 893 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
757 { 894 {
758 Console.WriteLine(text); 895 Console.WriteLine(text);
@@ -775,6 +912,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
775 { 912 {
776 m_host.AddScriptLPS(1); 913 m_host.AddScriptLPS(1);
777 914
915 if (channelID == 0)
916// m_SayShoutCount++;
917 CheckSayShoutTime();
918
919 if (m_SayShoutCount >= 11)
920 ScriptSleep(2000);
921
778 if (text.Length > 1023) 922 if (text.Length > 1023)
779 text = text.Substring(0, 1023); 923 text = text.Substring(0, 1023);
780 924
@@ -806,22 +950,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
806 950
807 public void llRegionSayTo(string target, int channel, string msg) 951 public void llRegionSayTo(string target, int channel, string msg)
808 { 952 {
953 string error = String.Empty;
954
809 if (msg.Length > 1023) 955 if (msg.Length > 1023)
810 msg = msg.Substring(0, 1023); 956 msg = msg.Substring(0, 1023);
811 957
812 m_host.AddScriptLPS(1); 958 m_host.AddScriptLPS(1);
813 959
814 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
815 {
816 return;
817 }
818
819 UUID TargetID; 960 UUID TargetID;
820 UUID.TryParse(target, out TargetID); 961 UUID.TryParse(target, out TargetID);
821 962
822 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 963 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
823 if (wComm != null) 964 if (wComm != null)
824 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 965 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
966 LSLError(error);
825 } 967 }
826 968
827 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 969 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1077,10 +1219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1077 return detectedParams.TouchUV; 1219 return detectedParams.TouchUV;
1078 } 1220 }
1079 1221
1222 [DebuggerNonUserCode]
1080 public virtual void llDie() 1223 public virtual void llDie()
1081 { 1224 {
1082 m_host.AddScriptLPS(1); 1225 m_host.AddScriptLPS(1);
1083 throw new SelfDeleteException(); 1226 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1084 } 1227 }
1085 1228
1086 public LSL_Float llGround(LSL_Vector offset) 1229 public LSL_Float llGround(LSL_Vector offset)
@@ -1153,6 +1296,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1153 1296
1154 public void llSetStatus(int status, int value) 1297 public void llSetStatus(int status, int value)
1155 { 1298 {
1299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1300 return;
1156 m_host.AddScriptLPS(1); 1301 m_host.AddScriptLPS(1);
1157 1302
1158 int statusrotationaxis = 0; 1303 int statusrotationaxis = 0;
@@ -1176,6 +1321,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1176 if (!allow) 1321 if (!allow)
1177 return; 1322 return;
1178 1323
1324 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1325 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1326 return;
1327
1179 m_host.ScriptSetPhysicsStatus(true); 1328 m_host.ScriptSetPhysicsStatus(true);
1180 } 1329 }
1181 else 1330 else
@@ -1385,6 +1534,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1534 {
1386 m_host.AddScriptLPS(1); 1535 m_host.AddScriptLPS(1);
1387 1536
1537 SetColor(m_host, color, face);
1538 }
1539
1540 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1541 {
1542 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1543 return;
1544
1545 Primitive.TextureEntry tex = part.Shape.Textures;
1546 Color4 texcolor;
1547 if (face >= 0 && face < GetNumberOfSides(part))
1548 {
1549 texcolor = tex.CreateFace((uint)face).RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[face].RGBA = texcolor;
1554 part.UpdateTextureEntry(tex.GetBytes());
1555 return;
1556 }
1557 else if (face == ScriptBaseClass.ALL_SIDES)
1558 {
1559 for (uint i = 0; i < GetNumberOfSides(part); i++)
1560 {
1561 if (tex.FaceTextures[i] != null)
1562 {
1563 texcolor = tex.FaceTextures[i].RGBA;
1564 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1565 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1566 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1567 tex.FaceTextures[i].RGBA = texcolor;
1568 }
1569 texcolor = tex.DefaultTexture.RGBA;
1570 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1571 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1572 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1573 tex.DefaultTexture.RGBA = texcolor;
1574 }
1575 part.UpdateTextureEntry(tex.GetBytes());
1576 return;
1577 }
1578
1388 if (face == ScriptBaseClass.ALL_SIDES) 1579 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1580 face = SceneObjectPart.ALL_SIDES;
1390 1581
@@ -1393,6 +1584,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1584
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1585 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1586 {
1587 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1588 return;
1589
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1590 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1591 MappingType textype;
1398 textype = MappingType.Default; 1592 textype = MappingType.Default;
@@ -1423,6 +1617,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1617
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1618 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1619 {
1620 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return;
1622
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1623 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1624 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1625 {
@@ -1448,6 +1645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1645
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1646 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1647 {
1648 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return;
1451 1650
1452 Shininess sval = new Shininess(); 1651 Shininess sval = new Shininess();
1453 1652
@@ -1498,6 +1697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1697
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1698 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1699 {
1700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1701 return;
1702
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1703 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1704 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1705 {
@@ -1558,13 +1760,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1760 m_host.AddScriptLPS(1);
1559 1761
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1762 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1763 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1764 {
1563 SetAlpha(part, alpha, face); 1765 try
1766 {
1767 parts[0].ParentGroup.areUpdatesSuspended = true;
1768 foreach (SceneObjectPart part in parts)
1769 SetAlpha(part, alpha, face);
1770 }
1771 finally
1772 {
1773 parts[0].ParentGroup.areUpdatesSuspended = false;
1774 }
1775 }
1564 } 1776 }
1565 1777
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1778 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1779 {
1780 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1781 return;
1782
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1783 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1784 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1785 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1617,7 +1832,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1617 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1832 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1618 float wind, float tension, LSL_Vector Force) 1833 float wind, float tension, LSL_Vector Force)
1619 { 1834 {
1620 if (part == null) 1835 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return; 1836 return;
1622 1837
1623 if (flexi) 1838 if (flexi)
@@ -1651,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1651 /// <param name="falloff"></param> 1866 /// <param name="falloff"></param>
1652 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1867 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1653 { 1868 {
1654 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1655 return; 1870 return;
1656 1871
1657 if (light) 1872 if (light)
@@ -1684,11 +1899,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1684 Primitive.TextureEntry tex = part.Shape.Textures; 1899 Primitive.TextureEntry tex = part.Shape.Textures;
1685 Color4 texcolor; 1900 Color4 texcolor;
1686 LSL_Vector rgb = new LSL_Vector(); 1901 LSL_Vector rgb = new LSL_Vector();
1902 int nsides = GetNumberOfSides(part);
1903
1687 if (face == ScriptBaseClass.ALL_SIDES) 1904 if (face == ScriptBaseClass.ALL_SIDES)
1688 { 1905 {
1689 int i; 1906 int i;
1690 1907 for (i = 0; i < nsides; i++)
1691 for (i = 0 ; i < GetNumberOfSides(part); i++)
1692 { 1908 {
1693 texcolor = tex.GetFace((uint)i).RGBA; 1909 texcolor = tex.GetFace((uint)i).RGBA;
1694 rgb.x += texcolor.R; 1910 rgb.x += texcolor.R;
@@ -1696,14 +1912,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1696 rgb.z += texcolor.B; 1912 rgb.z += texcolor.B;
1697 } 1913 }
1698 1914
1699 rgb.x /= (float)GetNumberOfSides(part); 1915 float invnsides = 1.0f / (float)nsides;
1700 rgb.y /= (float)GetNumberOfSides(part); 1916
1701 rgb.z /= (float)GetNumberOfSides(part); 1917 rgb.x *= invnsides;
1918 rgb.y *= invnsides;
1919 rgb.z *= invnsides;
1702 1920
1703 return rgb; 1921 return rgb;
1704 } 1922 }
1705 1923 if (face >= 0 && face < nsides)
1706 if (face >= 0 && face < GetNumberOfSides(part))
1707 { 1924 {
1708 texcolor = tex.GetFace((uint)face).RGBA; 1925 texcolor = tex.GetFace((uint)face).RGBA;
1709 rgb.x = texcolor.R; 1926 rgb.x = texcolor.R;
@@ -1730,15 +1947,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1730 m_host.AddScriptLPS(1); 1947 m_host.AddScriptLPS(1);
1731 1948
1732 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1949 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1733 1950 if (parts.Count > 0)
1734 foreach (SceneObjectPart part in parts) 1951 {
1735 SetTexture(part, texture, face); 1952 try
1736 1953 {
1954 parts[0].ParentGroup.areUpdatesSuspended = true;
1955 foreach (SceneObjectPart part in parts)
1956 SetTexture(part, texture, face);
1957 }
1958 finally
1959 {
1960 parts[0].ParentGroup.areUpdatesSuspended = false;
1961 }
1962 }
1737 ScriptSleep(200); 1963 ScriptSleep(200);
1738 } 1964 }
1739 1965
1740 protected void SetTexture(SceneObjectPart part, string texture, int face) 1966 protected void SetTexture(SceneObjectPart part, string texture, int face)
1741 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1742 UUID textureID = new UUID(); 1971 UUID textureID = new UUID();
1743 1972
1744 textureID = InventoryKey(texture, (int)AssetType.Texture); 1973 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1783,6 +2012,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1783 2012
1784 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2013 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1785 { 2014 {
2015 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2016 return;
2017
1786 Primitive.TextureEntry tex = part.Shape.Textures; 2018 Primitive.TextureEntry tex = part.Shape.Textures;
1787 if (face >= 0 && face < GetNumberOfSides(part)) 2019 if (face >= 0 && face < GetNumberOfSides(part))
1788 { 2020 {
@@ -1819,6 +2051,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2051
1820 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2052 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2053 {
2054 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2055 return;
2056
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2057 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2058 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2059 {
@@ -1855,6 +2090,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2090
1856 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2091 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1857 { 2092 {
2093 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2094 return;
2095
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2096 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2097 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2098 {
@@ -1975,7 +2213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1975 2213
1976 bool sameParcel = here.GlobalID == there.GlobalID; 2214 bool sameParcel = here.GlobalID == there.GlobalID;
1977 2215
1978 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2216 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1979 { 2217 {
1980 return 0; 2218 return 0;
1981 } 2219 }
@@ -2024,24 +2262,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2262 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2025 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2263 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2026 { 2264 {
2027 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2266 return;
2267
2028 LSL_Vector currentPos = GetPartLocalPos(part); 2268 LSL_Vector currentPos = GetPartLocalPos(part);
2269 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2029 2270
2030 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2031 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2032 2271
2033 if (part.ParentGroup.RootPart == part) 2272 if (part.ParentGroup.RootPart == part)
2034 { 2273 {
2035 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2036 targetPos.z = ground;
2037 SceneObjectGroup parent = part.ParentGroup; 2274 SceneObjectGroup parent = part.ParentGroup;
2038 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2275 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2039 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2276 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2277 return;
2278 Util.FireAndForget(delegate(object x) {
2279 parent.UpdateGroupPosition(dest);
2280 });
2040 } 2281 }
2041 else 2282 else
2042 { 2283 {
2043 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2284 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2044 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2045 SceneObjectGroup parent = part.ParentGroup; 2285 SceneObjectGroup parent = part.ParentGroup;
2046 parent.HasGroupChanged = true; 2286 parent.HasGroupChanged = true;
2047 parent.ScheduleGroupForTerseUpdate(); 2287 parent.ScheduleGroupForTerseUpdate();
@@ -2074,17 +2314,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2074 else 2314 else
2075 { 2315 {
2076 if (part.ParentGroup.IsAttachment) 2316 if (part.ParentGroup.IsAttachment)
2077 {
2078 pos = part.AttachedPos; 2317 pos = part.AttachedPos;
2079 }
2080 else 2318 else
2081 {
2082 pos = part.AbsolutePosition; 2319 pos = part.AbsolutePosition;
2083 }
2084 } 2320 }
2085 2321
2086// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2087
2088 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2322 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2089 } 2323 }
2090 2324
@@ -2093,18 +2327,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2093 m_host.AddScriptLPS(1); 2327 m_host.AddScriptLPS(1);
2094 2328
2095 // try to let this work as in SL... 2329 // try to let this work as in SL...
2096 if (m_host.ParentID == 0) 2330 if (m_host.LinkNum < 2)
2097 { 2331 {
2098 // special case: If we are root, rotate complete SOG to new rotation 2332 // Special case: If we are root, rotate complete SOG to new
2333 // rotation.
2334 // We are root if the link number is 0 (single prim) or 1
2335 // (root prim). ParentID may be nonzero in attachments and
2336 // using it would cause attachments and HUDs to rotate
2337 // to the wrong positions.
2338
2099 SetRot(m_host, Rot2Quaternion(rot)); 2339 SetRot(m_host, Rot2Quaternion(rot));
2100 } 2340 }
2101 else 2341 else
2102 { 2342 {
2103 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2343 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2104 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2344 SceneObjectPart rootPart;
2105 if (rootPart != null) // better safe than sorry 2345 if (m_host.ParentGroup != null) // better safe than sorry
2106 { 2346 {
2107 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2347 rootPart = m_host.ParentGroup.RootPart;
2348 if (rootPart != null)
2349 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2108 } 2350 }
2109 } 2351 }
2110 2352
@@ -2114,31 +2356,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2114 public void llSetLocalRot(LSL_Rotation rot) 2356 public void llSetLocalRot(LSL_Rotation rot)
2115 { 2357 {
2116 m_host.AddScriptLPS(1); 2358 m_host.AddScriptLPS(1);
2359
2117 SetRot(m_host, Rot2Quaternion(rot)); 2360 SetRot(m_host, Rot2Quaternion(rot));
2118 ScriptSleep(200); 2361 ScriptSleep(200);
2119 } 2362 }
2120 2363
2121 protected void SetRot(SceneObjectPart part, Quaternion rot) 2364 protected void SetRot(SceneObjectPart part, Quaternion rot)
2122 { 2365 {
2123 part.UpdateRotation(rot); 2366 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2124 // Update rotation does not move the object in the physics scene if it's a linkset. 2367 return;
2125 2368
2126//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2369 bool isroot = (part == part.ParentGroup.RootPart);
2127// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2370 bool isphys;
2128 2371
2129 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2130 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2131 // It's perfectly okay when the object is not an active physical body though.
2132 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2133 // but only if the object is not physial and active. This is important for rotating doors.
2134 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2135 // scene
2136 PhysicsActor pa = part.PhysActor; 2372 PhysicsActor pa = part.PhysActor;
2137 2373
2138 if (pa != null && !pa.IsPhysical) 2374 // keep using physactor ideia of isphysical
2375 // it should be SOP ideia of that
2376 // not much of a issue with ubitODE
2377 if (pa != null && pa.IsPhysical)
2378 isphys = true;
2379 else
2380 isphys = false;
2381
2382 // SL doesn't let scripts rotate root of physical linksets
2383 if (isroot && isphys)
2384 return;
2385
2386 part.UpdateRotation(rot);
2387
2388 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2389 // so do a nasty update of parts positions if is a root part rotation
2390 if (isroot && pa != null) // with if above implies non physical root part
2139 { 2391 {
2140 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2392 part.ParentGroup.ResetChildPrimPhysicsPositions();
2141 } 2393 }
2394 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2395 {
2396 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2397 if (sittingavas.Count > 0)
2398 {
2399 foreach (ScenePresence av in sittingavas)
2400 {
2401 if (isroot || part.LocalId == av.ParentID)
2402 av.SendTerseUpdateToAllClients();
2403 }
2404 }
2405 }
2142 } 2406 }
2143 2407
2144 /// <summary> 2408 /// <summary>
@@ -2186,8 +2450,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2186 2450
2187 public LSL_Rotation llGetLocalRot() 2451 public LSL_Rotation llGetLocalRot()
2188 { 2452 {
2453 return GetPartLocalRot(m_host);
2454 }
2455
2456 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2457 {
2189 m_host.AddScriptLPS(1); 2458 m_host.AddScriptLPS(1);
2190 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2459 Quaternion rot = part.RotationOffset;
2460 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2191 } 2461 }
2192 2462
2193 public void llSetForce(LSL_Vector force, int local) 2463 public void llSetForce(LSL_Vector force, int local)
@@ -2271,16 +2541,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 m_host.ApplyImpulse(v, local != 0); 2541 m_host.ApplyImpulse(v, local != 0);
2272 } 2542 }
2273 2543
2544
2274 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2545 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2275 { 2546 {
2276 m_host.AddScriptLPS(1); 2547 m_host.AddScriptLPS(1);
2277 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2548 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2278 } 2549 }
2279 2550
2280 public void llSetTorque(LSL_Vector torque, int local) 2551 public void llSetTorque(LSL_Vector torque, int local)
2281 { 2552 {
2282 m_host.AddScriptLPS(1); 2553 m_host.AddScriptLPS(1);
2283 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2554 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2284 } 2555 }
2285 2556
2286 public LSL_Vector llGetTorque() 2557 public LSL_Vector llGetTorque()
@@ -2297,20 +2568,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 llSetTorque(torque, local); 2568 llSetTorque(torque, local);
2298 } 2569 }
2299 2570
2571 public void llSetVelocity(LSL_Vector vel, int local)
2572 {
2573 m_host.AddScriptLPS(1);
2574 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2575 }
2576
2300 public LSL_Vector llGetVel() 2577 public LSL_Vector llGetVel()
2301 { 2578 {
2302 m_host.AddScriptLPS(1); 2579 m_host.AddScriptLPS(1);
2303 2580
2304 Vector3 vel; 2581 Vector3 vel = Vector3.Zero;
2305 2582
2306 if (m_host.ParentGroup.IsAttachment) 2583 if (m_host.ParentGroup.IsAttachment)
2307 { 2584 {
2308 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2585 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2309 vel = avatar.Velocity; 2586 if (avatar != null)
2587 vel = avatar.Velocity;
2310 } 2588 }
2311 else 2589 else
2312 { 2590 {
2313 vel = m_host.Velocity; 2591 vel = m_host.ParentGroup.RootPart.Velocity;
2314 } 2592 }
2315 2593
2316 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2594 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2322,10 +2600,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2600 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2323 } 2601 }
2324 2602
2603 public void llSetAngularVelocity(LSL_Vector avel, int local)
2604 {
2605 m_host.AddScriptLPS(1);
2606 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2607 }
2608
2325 public LSL_Vector llGetOmega() 2609 public LSL_Vector llGetOmega()
2326 { 2610 {
2327 m_host.AddScriptLPS(1); 2611 m_host.AddScriptLPS(1);
2328 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2612 Vector3 avel = m_host.AngularVelocity;
2613 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2329 } 2614 }
2330 2615
2331 public LSL_Float llGetTimeOfDay() 2616 public LSL_Float llGetTimeOfDay()
@@ -2854,16 +3139,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2854 new_group.RootPart.UUID.ToString()) }, 3139 new_group.RootPart.UUID.ToString()) },
2855 new DetectParams[0])); 3140 new DetectParams[0]));
2856 3141
2857 float groupmass = new_group.GetMass(); 3142 // do recoil
3143 SceneObjectGroup hostgrp = m_host.ParentGroup;
3144 if (hostgrp == null)
3145 return;
3146
3147 if (hostgrp.IsAttachment) // don't recoil avatars
3148 return;
2858 3149
2859 PhysicsActor pa = new_group.RootPart.PhysActor; 3150 PhysicsActor pa = new_group.RootPart.PhysActor;
2860 3151
2861 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3152 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2862 { 3153 {
2863 //Recoil. 3154 float groupmass = new_group.GetMass();
2864 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3155 llvel *= -groupmass;
3156 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2865 } 3157 }
2866 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3158 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3159 return;
3160
2867 }); 3161 });
2868 3162
2869 //ScriptSleep((int)((groupmass * velmag) / 10)); 3163 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2878,35 +3172,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 public void llLookAt(LSL_Vector target, double strength, double damping) 3172 public void llLookAt(LSL_Vector target, double strength, double damping)
2879 { 3173 {
2880 m_host.AddScriptLPS(1); 3174 m_host.AddScriptLPS(1);
2881 // Determine where we are looking from
2882 LSL_Vector from = llGetPos();
2883 3175
2884 // Work out the normalised vector from the source to the target 3176 // Get the normalized vector to the target
2885 LSL_Vector delta = llVecNorm(target - from); 3177 LSL_Vector d1 = llVecNorm(target - llGetPos());
2886 LSL_Vector angle = new LSL_Vector(0,0,0);
2887 3178
2888 // Calculate the yaw 3179 // Get the bearing (yaw)
2889 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3180 LSL_Vector a1 = new LSL_Vector(0,0,0);
2890 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3181 a1.z = llAtan2(d1.y, d1.x);
2891 3182
2892 // Calculate pitch 3183 // Get the elevation (pitch)
2893 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3184 LSL_Vector a2 = new LSL_Vector(0,0,0);
3185 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2894 3186
2895 // we need to convert from a vector describing 3187 LSL_Rotation r1 = llEuler2Rot(a1);
2896 // the angles of rotation in radians into rotation value 3188 LSL_Rotation r2 = llEuler2Rot(a2);
2897 LSL_Rotation rot = llEuler2Rot(angle); 3189 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2898
2899 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2900 // set the rotation of the object, copy that behavior
2901 PhysicsActor pa = m_host.PhysActor;
2902 3190
2903 if (strength == 0 || pa == null || !pa.IsPhysical) 3191 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2904 { 3192 {
2905 llSetRot(rot); 3193 // Do nothing if either value is 0 (this has been checked in SL)
3194 if (strength <= 0.0 || damping <= 0.0)
3195 return;
3196
3197 llSetRot(r3 * r2 * r1);
2906 } 3198 }
2907 else 3199 else
2908 { 3200 {
2909 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3201 if (strength == 0)
3202 {
3203 llSetRot(r3 * r2 * r1);
3204 return;
3205 }
3206
3207 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2910 } 3208 }
2911 } 3209 }
2912 3210
@@ -2952,17 +3250,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2952 } 3250 }
2953 else 3251 else
2954 { 3252 {
2955 if (m_host.IsRoot) 3253 // new SL always returns object mass
2956 { 3254// if (m_host.IsRoot)
3255// {
2957 return m_host.ParentGroup.GetMass(); 3256 return m_host.ParentGroup.GetMass();
2958 } 3257// }
2959 else 3258// else
2960 { 3259// {
2961 return m_host.GetMass(); 3260// return m_host.GetMass();
2962 } 3261// }
2963 } 3262 }
2964 } 3263 }
2965 3264
3265
3266 public LSL_Float llGetMassMKS()
3267 {
3268 return 100f * llGetMass();
3269 }
3270
2966 public void llCollisionFilter(string name, string id, int accept) 3271 public void llCollisionFilter(string name, string id, int accept)
2967 { 3272 {
2968 m_host.AddScriptLPS(1); 3273 m_host.AddScriptLPS(1);
@@ -3037,7 +3342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3342 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3038 3343
3039 if (attachmentsModule != null) 3344 if (attachmentsModule != null)
3040 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3345 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
3041 else 3346 else
3042 return false; 3347 return false;
3043 } 3348 }
@@ -3067,9 +3372,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3067 { 3372 {
3068 m_host.AddScriptLPS(1); 3373 m_host.AddScriptLPS(1);
3069 3374
3070// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3071// return;
3072
3073 if (m_item.PermsGranter != m_host.OwnerID) 3375 if (m_item.PermsGranter != m_host.OwnerID)
3074 return; 3376 return;
3075 3377
@@ -3112,6 +3414,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 3414
3113 public void llInstantMessage(string user, string message) 3415 public void llInstantMessage(string user, string message)
3114 { 3416 {
3417 UUID result;
3418 if (!UUID.TryParse(user, out result))
3419 {
3420 ShoutError("An invalid key was passed to llInstantMessage");
3421 ScriptSleep(2000);
3422 return;
3423 }
3424
3425
3115 m_host.AddScriptLPS(1); 3426 m_host.AddScriptLPS(1);
3116 3427
3117 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3428 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3126,14 +3437,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3126 UUID friendTransactionID = UUID.Random(); 3437 UUID friendTransactionID = UUID.Random();
3127 3438
3128 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3439 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3129 3440
3130 GridInstantMessage msg = new GridInstantMessage(); 3441 GridInstantMessage msg = new GridInstantMessage();
3131 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3442 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3132 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3443 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3133 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3444 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3134// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3445// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3135// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3446// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3136 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3447// DateTime dt = DateTime.UtcNow;
3448//
3449// // Ticks from UtcNow, but make it look like local. Evil, huh?
3450// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3451//
3452// try
3453// {
3454// // Convert that to the PST timezone
3455// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3456// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3457// }
3458// catch
3459// {
3460// // No logging here, as it could be VERY spammy
3461// }
3462//
3463// // And make it look local again to fool the unix time util
3464// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3465
3466 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3467
3137 //if (client != null) 3468 //if (client != null)
3138 //{ 3469 //{
3139 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3470 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3147,12 +3478,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3147 msg.message = message.Substring(0, 1024); 3478 msg.message = message.Substring(0, 1024);
3148 else 3479 else
3149 msg.message = message; 3480 msg.message = message;
3150 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3481 msg.dialog = (byte)19; // MessageFromObject
3151 msg.fromGroup = false;// fromGroup; 3482 msg.fromGroup = false;// fromGroup;
3152 msg.offline = (byte)0; //offline; 3483 msg.offline = (byte)0; //offline;
3153 msg.ParentEstateID = 0; //ParentEstateID; 3484 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3154 msg.Position = new Vector3(m_host.AbsolutePosition); 3485 msg.Position = new Vector3(m_host.AbsolutePosition);
3155 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3486 msg.RegionID = World.RegionInfo.RegionID.Guid;
3156 msg.binaryBucket 3487 msg.binaryBucket
3157 = Util.StringToBytes256( 3488 = Util.StringToBytes256(
3158 "{0}/{1}/{2}/{3}", 3489 "{0}/{1}/{2}/{3}",
@@ -3180,7 +3511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 } 3511 }
3181 3512
3182 emailModule.SendEmail(m_host.UUID, address, subject, message); 3513 emailModule.SendEmail(m_host.UUID, address, subject, message);
3183 llSleep(EMAIL_PAUSE_TIME); 3514 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3184 } 3515 }
3185 3516
3186 public void llGetNextEmail(string address, string subject) 3517 public void llGetNextEmail(string address, string subject)
@@ -3424,15 +3755,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3424 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3755 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3425 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3756 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3426 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3757 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3758 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3427 ScriptBaseClass.PERMISSION_ATTACH; 3759 ScriptBaseClass.PERMISSION_ATTACH;
3428 3760
3429 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3761 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3430 { 3762 {
3431 lock (m_host.TaskInventory) 3763 m_host.TaskInventory.LockItemsForWrite(true);
3432 { 3764 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3433 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3765 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3434 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3766 m_host.TaskInventory.LockItemsForWrite(false);
3435 }
3436 3767
3437 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3768 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3769 "run_time_permissions", new Object[] {
@@ -3442,28 +3773,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3442 return; 3773 return;
3443 } 3774 }
3444 } 3775 }
3445 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3776 else
3446 { 3777 {
3447 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3778 bool sitting = false;
3448 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3779 if (m_host.SitTargetAvatar == agentID)
3449 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3780 {
3450 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3781 sitting = true;
3451 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3782 }
3783 else
3784 {
3785 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3786 {
3787 if (p.SitTargetAvatar == agentID)
3788 sitting = true;
3789 }
3790 }
3452 3791
3453 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3792 if (sitting)
3454 { 3793 {
3455 lock (m_host.TaskInventory) 3794 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3795 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3796 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3797 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3798 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3799
3800 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3456 { 3801 {
3802 m_host.TaskInventory.LockItemsForWrite(true);
3457 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3803 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3458 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3804 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3459 } 3805 m_host.TaskInventory.LockItemsForWrite(false);
3460 3806
3461 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3807 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3808 "run_time_permissions", new Object[] {
3463 new LSL_Integer(perm) }, 3809 new LSL_Integer(perm) },
3464 new DetectParams[0])); 3810 new DetectParams[0]));
3465 3811
3466 return; 3812 return;
3813 }
3467 } 3814 }
3468 } 3815 }
3469 3816
@@ -3500,11 +3847,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3500 3847
3501 if (!m_waitingForScriptAnswer) 3848 if (!m_waitingForScriptAnswer)
3502 { 3849 {
3503 lock (m_host.TaskInventory) 3850 m_host.TaskInventory.LockItemsForWrite(true);
3504 { 3851 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3505 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3852 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3506 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3507 }
3508 3854
3509 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3855 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3510 m_waitingForScriptAnswer=true; 3856 m_waitingForScriptAnswer=true;
@@ -3533,14 +3879,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3879 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3534 llReleaseControls(); 3880 llReleaseControls();
3535 3881
3536 lock (m_host.TaskInventory) 3882 m_host.TaskInventory.LockItemsForWrite(true);
3537 { 3883 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3538 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3884 m_host.TaskInventory.LockItemsForWrite(false);
3539 } 3885
3540 3886 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3541 m_ScriptEngine.PostScriptEvent( 3887 "run_time_permissions", new Object[] {
3542 m_item.ItemID, 3888 new LSL_Integer(answer) },
3543 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3889 new DetectParams[0]));
3544 } 3890 }
3545 3891
3546 public LSL_String llGetPermissionsKey() 3892 public LSL_String llGetPermissionsKey()
@@ -3579,14 +3925,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3925 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3926 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3927 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3928 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3929 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3930 try
3931 {
3932 parts[0].ParentGroup.areUpdatesSuspended = true;
3933 foreach (SceneObjectPart part in parts)
3934 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3935 }
3936 finally
3937 {
3938 parts[0].ParentGroup.areUpdatesSuspended = false;
3939 }
3940 }
3585 } 3941 }
3586 3942
3587 public void llCreateLink(string target, int parent) 3943 public void llCreateLink(string target, int parent)
3588 { 3944 {
3589 m_host.AddScriptLPS(1); 3945 m_host.AddScriptLPS(1);
3946
3590 UUID targetID; 3947 UUID targetID;
3591 3948
3592 if (!UUID.TryParse(target, out targetID)) 3949 if (!UUID.TryParse(target, out targetID))
@@ -3692,10 +4049,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 // Restructuring Multiple Prims. 4049 // Restructuring Multiple Prims.
3693 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4050 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3694 parts.Remove(parentPrim.RootPart); 4051 parts.Remove(parentPrim.RootPart);
3695 foreach (SceneObjectPart part in parts) 4052 if (parts.Count > 0)
3696 { 4053 {
3697 parentPrim.DelinkFromGroup(part.LocalId, true); 4054 try
4055 {
4056 parts[0].ParentGroup.areUpdatesSuspended = true;
4057 foreach (SceneObjectPart part in parts)
4058 {
4059 parentPrim.DelinkFromGroup(part.LocalId, true);
4060 }
4061 }
4062 finally
4063 {
4064 parts[0].ParentGroup.areUpdatesSuspended = false;
4065 }
3698 } 4066 }
4067
3699 parentPrim.HasGroupChanged = true; 4068 parentPrim.HasGroupChanged = true;
3700 parentPrim.ScheduleGroupForFullUpdate(); 4069 parentPrim.ScheduleGroupForFullUpdate();
3701 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4070 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3704,12 +4073,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3704 { 4073 {
3705 SceneObjectPart newRoot = parts[0]; 4074 SceneObjectPart newRoot = parts[0];
3706 parts.Remove(newRoot); 4075 parts.Remove(newRoot);
3707 foreach (SceneObjectPart part in parts) 4076
4077 try
3708 { 4078 {
3709 // Required for linking 4079 parts[0].ParentGroup.areUpdatesSuspended = true;
3710 part.ClearUpdateSchedule(); 4080 foreach (SceneObjectPart part in parts)
3711 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4081 {
4082 part.ClearUpdateSchedule();
4083 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4084 }
3712 } 4085 }
4086 finally
4087 {
4088 parts[0].ParentGroup.areUpdatesSuspended = false;
4089 }
4090
4091
3713 newRoot.ParentGroup.HasGroupChanged = true; 4092 newRoot.ParentGroup.HasGroupChanged = true;
3714 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4093 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3715 } 4094 }
@@ -3729,6 +4108,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3729 public void llBreakAllLinks() 4108 public void llBreakAllLinks()
3730 { 4109 {
3731 m_host.AddScriptLPS(1); 4110 m_host.AddScriptLPS(1);
4111
4112 TaskInventoryItem item = m_item;
4113
4114 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4115 && !m_automaticLinkPermission)
4116 {
4117 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4118 return;
4119 }
4120
3732 SceneObjectGroup parentPrim = m_host.ParentGroup; 4121 SceneObjectGroup parentPrim = m_host.ParentGroup;
3733 if (parentPrim.AttachmentPoint != 0) 4122 if (parentPrim.AttachmentPoint != 0)
3734 return; // Fail silently if attached 4123 return; // Fail silently if attached
@@ -3748,25 +4137,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 public LSL_String llGetLinkKey(int linknum) 4137 public LSL_String llGetLinkKey(int linknum)
3749 { 4138 {
3750 m_host.AddScriptLPS(1); 4139 m_host.AddScriptLPS(1);
3751 List<UUID> keytable = new List<UUID>();
3752 // parse for sitting avatare-uuids
3753 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3754 {
3755 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3756 keytable.Add(presence.UUID);
3757 });
3758
3759 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3760 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3761 {
3762 return keytable[totalprims - linknum].ToString();
3763 }
3764
3765 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3766 {
3767 return m_host.UUID.ToString();
3768 }
3769
3770 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4140 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3771 if (part != null) 4141 if (part != null)
3772 { 4142 {
@@ -3774,6 +4144,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 } 4144 }
3775 else 4145 else
3776 { 4146 {
4147 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4148 {
4149 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4150
4151 if (linknum < 0)
4152 return UUID.Zero.ToString();
4153
4154 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4155 if (avatars.Count > linknum)
4156 {
4157 return avatars[linknum].UUID.ToString();
4158 }
4159 }
3777 return UUID.Zero.ToString(); 4160 return UUID.Zero.ToString();
3778 } 4161 }
3779 } 4162 }
@@ -3873,17 +4256,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3873 m_host.AddScriptLPS(1); 4256 m_host.AddScriptLPS(1);
3874 int count = 0; 4257 int count = 0;
3875 4258
3876 lock (m_host.TaskInventory) 4259 m_host.TaskInventory.LockItemsForRead(true);
4260 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3877 { 4261 {
3878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4262 if (inv.Value.Type == type || type == -1)
3879 { 4263 {
3880 if (inv.Value.Type == type || type == -1) 4264 count = count + 1;
3881 {
3882 count = count + 1;
3883 }
3884 } 4265 }
3885 } 4266 }
3886 4267
4268 m_host.TaskInventory.LockItemsForRead(false);
3887 return count; 4269 return count;
3888 } 4270 }
3889 4271
@@ -3892,16 +4274,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3892 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
3893 ArrayList keys = new ArrayList(); 4275 ArrayList keys = new ArrayList();
3894 4276
3895 lock (m_host.TaskInventory) 4277 m_host.TaskInventory.LockItemsForRead(true);
4278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3896 { 4279 {
3897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4280 if (inv.Value.Type == type || type == -1)
3898 { 4281 {
3899 if (inv.Value.Type == type || type == -1) 4282 keys.Add(inv.Value.Name);
3900 {
3901 keys.Add(inv.Value.Name);
3902 }
3903 } 4283 }
3904 } 4284 }
4285 m_host.TaskInventory.LockItemsForRead(false);
3905 4286
3906 if (keys.Count == 0) 4287 if (keys.Count == 0)
3907 { 4288 {
@@ -3939,7 +4320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3939 if (item == null) 4320 if (item == null)
3940 { 4321 {
3941 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4322 llSay(0, String.Format("Could not find object '{0}'", inventory));
3942 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4323 return;
4324// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3943 } 4325 }
3944 4326
3945 UUID objId = item.ItemID; 4327 UUID objId = item.ItemID;
@@ -3967,34 +4349,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 return; 4349 return;
3968 } 4350 }
3969 } 4351 }
4352
3970 // destination is an avatar 4353 // destination is an avatar
3971 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4354 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3972 4355
3973 if (agentItem == null) 4356 if (agentItem == null)
3974 return; 4357 return;
3975 4358
3976 byte[] bucket = new byte[17]; 4359 byte[] bucket = new byte[1];
3977 bucket[0] = (byte)item.Type; 4360 bucket[0] = (byte)item.Type;
3978 byte[] objBytes = agentItem.ID.GetBytes(); 4361 //byte[] objBytes = agentItem.ID.GetBytes();
3979 Array.Copy(objBytes, 0, bucket, 1, 16); 4362 //Array.Copy(objBytes, 0, bucket, 1, 16);
3980 4363
3981 GridInstantMessage msg = new GridInstantMessage(World, 4364 GridInstantMessage msg = new GridInstantMessage(World,
3982 m_host.UUID, m_host.Name + ", an object owned by " + 4365 m_host.OwnerID, m_host.Name, destId,
3983 resolveName(m_host.OwnerID) + ",", destId,
3984 (byte)InstantMessageDialog.TaskInventoryOffered, 4366 (byte)InstantMessageDialog.TaskInventoryOffered,
3985 false, item.Name + "\n" + m_host.Name + " is located at " + 4367 false, item.Name+". "+m_host.Name+" is located at "+
3986 World.RegionInfo.RegionName+" "+ 4368 World.RegionInfo.RegionName+" "+
3987 m_host.AbsolutePosition.ToString(), 4369 m_host.AbsolutePosition.ToString(),
3988 agentItem.ID, true, m_host.AbsolutePosition, 4370 agentItem.ID, true, m_host.AbsolutePosition,
3989 bucket); 4371 bucket);
3990 4372
3991 if (m_TransferModule != null) 4373 ScenePresence sp;
3992 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3993 4374
4375 if (World.TryGetScenePresence(destId, out sp))
4376 {
4377 sp.ControllingClient.SendInstantMessage(msg);
4378 }
4379 else
4380 {
4381 if (m_TransferModule != null)
4382 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4383 }
4384
4385 //This delay should only occur when giving inventory to avatars.
3994 ScriptSleep(3000); 4386 ScriptSleep(3000);
3995 } 4387 }
3996 } 4388 }
3997 4389
4390 [DebuggerNonUserCode]
3998 public void llRemoveInventory(string name) 4391 public void llRemoveInventory(string name)
3999 { 4392 {
4000 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
@@ -4040,109 +4433,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4040 { 4433 {
4041 m_host.AddScriptLPS(1); 4434 m_host.AddScriptLPS(1);
4042 4435
4043 UUID uuid = (UUID)id; 4436 UUID uuid;
4044 PresenceInfo pinfo = null; 4437 if (UUID.TryParse(id, out uuid))
4045 UserAccount account;
4046
4047 UserInfoCacheEntry ce;
4048 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4049 { 4438 {
4050 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4439 PresenceInfo pinfo = null;
4051 if (account == null) 4440 UserAccount account;
4441
4442 UserInfoCacheEntry ce;
4443 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4052 { 4444 {
4053 m_userInfoCache[uuid] = null; // Cache negative 4445 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4054 return UUID.Zero.ToString(); 4446 if (account == null)
4055 } 4447 {
4448 m_userInfoCache[uuid] = null; // Cache negative
4449 return UUID.Zero.ToString();
4450 }
4056 4451
4057 4452
4058 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4453 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4059 if (pinfos != null && pinfos.Length > 0) 4454 if (pinfos != null && pinfos.Length > 0)
4060 {
4061 foreach (PresenceInfo p in pinfos)
4062 { 4455 {
4063 if (p.RegionID != UUID.Zero) 4456 foreach (PresenceInfo p in pinfos)
4064 { 4457 {
4065 pinfo = p; 4458 if (p.RegionID != UUID.Zero)
4459 {
4460 pinfo = p;
4461 }
4066 } 4462 }
4067 } 4463 }
4068 }
4069 4464
4070 ce = new UserInfoCacheEntry(); 4465 ce = new UserInfoCacheEntry();
4071 ce.time = Util.EnvironmentTickCount(); 4466 ce.time = Util.EnvironmentTickCount();
4072 ce.account = account; 4467 ce.account = account;
4073 ce.pinfo = pinfo; 4468 ce.pinfo = pinfo;
4074 } 4469 m_userInfoCache[uuid] = ce;
4075 else 4470 }
4076 { 4471 else
4077 if (ce == null) 4472 {
4078 return UUID.Zero.ToString(); 4473 if (ce == null)
4474 return UUID.Zero.ToString();
4079 4475
4080 account = ce.account; 4476 account = ce.account;
4081 pinfo = ce.pinfo; 4477 pinfo = ce.pinfo;
4082 } 4478 }
4083 4479
4084 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4480 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4085 {
4086 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4087 if (pinfos != null && pinfos.Length > 0)
4088 { 4481 {
4089 foreach (PresenceInfo p in pinfos) 4482 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4483 if (pinfos != null && pinfos.Length > 0)
4090 { 4484 {
4091 if (p.RegionID != UUID.Zero) 4485 foreach (PresenceInfo p in pinfos)
4092 { 4486 {
4093 pinfo = p; 4487 if (p.RegionID != UUID.Zero)
4488 {
4489 pinfo = p;
4490 }
4094 } 4491 }
4095 } 4492 }
4096 } 4493 else
4097 else 4494 pinfo = null;
4098 pinfo = null;
4099 4495
4100 ce.time = Util.EnvironmentTickCount(); 4496 ce.time = Util.EnvironmentTickCount();
4101 ce.pinfo = pinfo; 4497 ce.pinfo = pinfo;
4102 } 4498 }
4103 4499
4104 string reply = String.Empty; 4500 string reply = String.Empty;
4105 4501
4106 switch (data) 4502 switch (data)
4107 { 4503 {
4108 case 1: // DATA_ONLINE (0|1) 4504 case 1: // DATA_ONLINE (0|1)
4109 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4505 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4110 reply = "1"; 4506 reply = "1";
4111 else 4507 else
4112 reply = "0"; 4508 reply = "0";
4113 break; 4509 break;
4114 case 2: // DATA_NAME (First Last) 4510 case 2: // DATA_NAME (First Last)
4115 reply = account.FirstName + " " + account.LastName; 4511 reply = account.FirstName + " " + account.LastName;
4116 break; 4512 break;
4117 case 3: // DATA_BORN (YYYY-MM-DD) 4513 case 3: // DATA_BORN (YYYY-MM-DD)
4118 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4514 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4119 born = born.AddSeconds(account.Created); 4515 born = born.AddSeconds(account.Created);
4120 reply = born.ToString("yyyy-MM-dd"); 4516 reply = born.ToString("yyyy-MM-dd");
4121 break; 4517 break;
4122 case 4: // DATA_RATING (0,0,0,0,0,0) 4518 case 4: // DATA_RATING (0,0,0,0,0,0)
4123 reply = "0,0,0,0,0,0"; 4519 reply = "0,0,0,0,0,0";
4124 break; 4520 break;
4125 case 7: // DATA_USERLEVEL (integer) 4521 case 8: // DATA_PAYINFO (0|1|2|3)
4126 reply = account.UserLevel.ToString(); 4522 reply = "0";
4127 break; 4523 break;
4128 case 8: // DATA_PAYINFO (0|1|2|3) 4524 default:
4129 reply = "0"; 4525 return UUID.Zero.ToString(); // Raise no event
4130 break; 4526 }
4131 default:
4132 return UUID.Zero.ToString(); // Raise no event
4133 }
4134 4527
4135 UUID rq = UUID.Random(); 4528 UUID rq = UUID.Random();
4136 4529
4137 UUID tid = AsyncCommands. 4530 UUID tid = AsyncCommands.
4138 DataserverPlugin.RegisterRequest(m_host.LocalId, 4531 DataserverPlugin.RegisterRequest(m_host.LocalId,
4139 m_item.ItemID, rq.ToString()); 4532 m_item.ItemID, rq.ToString());
4140 4533
4141 AsyncCommands. 4534 AsyncCommands.
4142 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4535 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4143 4536
4144 ScriptSleep(100); 4537 ScriptSleep(100);
4145 return tid.ToString(); 4538 return tid.ToString();
4539 }
4540 else
4541 {
4542 ShoutError("Invalid UUID passed to llRequestAgentData.");
4543 }
4544 return "";
4146 } 4545 }
4147 4546
4148 public LSL_String llRequestInventoryData(string name) 4547 public LSL_String llRequestInventoryData(string name)
@@ -4199,13 +4598,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4199 if (UUID.TryParse(agent, out agentId)) 4598 if (UUID.TryParse(agent, out agentId))
4200 { 4599 {
4201 ScenePresence presence = World.GetScenePresence(agentId); 4600 ScenePresence presence = World.GetScenePresence(agentId);
4202 if (presence != null) 4601 if (presence != null && presence.PresenceType != PresenceType.Npc)
4203 { 4602 {
4603 // agent must not be a god
4604 if (presence.UserLevel >= 200) return;
4605
4204 // agent must be over the owners land 4606 // agent must be over the owners land
4205 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4607 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4206 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4608 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4207 { 4609 {
4208 World.TeleportClientHome(agentId, presence.ControllingClient); 4610 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4611 {
4612 // They can't be teleported home for some reason
4613 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4614 if (regionInfo != null)
4615 {
4616 World.RequestTeleportLocation(
4617 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4618 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4619 }
4620 }
4209 } 4621 }
4210 } 4622 }
4211 } 4623 }
@@ -4317,7 +4729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4317 UUID av = new UUID(); 4729 UUID av = new UUID();
4318 if (!UUID.TryParse(agent,out av)) 4730 if (!UUID.TryParse(agent,out av))
4319 { 4731 {
4320 LSLError("First parameter to llDialog needs to be a key"); 4732 //LSLError("First parameter to llDialog needs to be a key");
4321 return; 4733 return;
4322 } 4734 }
4323 4735
@@ -4349,7 +4761,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4349 public void llCollisionSound(string impact_sound, double impact_volume) 4761 public void llCollisionSound(string impact_sound, double impact_volume)
4350 { 4762 {
4351 m_host.AddScriptLPS(1); 4763 m_host.AddScriptLPS(1);
4352 4764
4765 if(impact_sound == "")
4766 {
4767 m_host.CollisionSoundVolume = (float)impact_volume;
4768 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4769 m_host.CollisionSoundType = 0;
4770 return;
4771 }
4353 // TODO: Parameter check logic required. 4772 // TODO: Parameter check logic required.
4354 UUID soundId = UUID.Zero; 4773 UUID soundId = UUID.Zero;
4355 if (!UUID.TryParse(impact_sound, out soundId)) 4774 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4362,6 +4781,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4362 4781
4363 m_host.CollisionSound = soundId; 4782 m_host.CollisionSound = soundId;
4364 m_host.CollisionSoundVolume = (float)impact_volume; 4783 m_host.CollisionSoundVolume = (float)impact_volume;
4784 m_host.CollisionSoundType = 1;
4365 } 4785 }
4366 4786
4367 public LSL_String llGetAnimation(string id) 4787 public LSL_String llGetAnimation(string id)
@@ -4375,14 +4795,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4375 4795
4376 if (m_host.RegionHandle == presence.RegionHandle) 4796 if (m_host.RegionHandle == presence.RegionHandle)
4377 { 4797 {
4378 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4379
4380 if (presence != null) 4798 if (presence != null)
4381 { 4799 {
4382 AnimationSet currentAnims = presence.Animator.Animations; 4800 if (presence.SitGround)
4383 string currentAnimationState = String.Empty; 4801 return "Sitting on Ground";
4384 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4802 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4385 return currentAnimationState; 4803 return "Sitting";
4804
4805 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4806 string lslMovementAnimation;
4807
4808 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4809 return lslMovementAnimation;
4386 } 4810 }
4387 } 4811 }
4388 4812
@@ -4529,7 +4953,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4529 { 4953 {
4530 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4954 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4531 float distance_term = distance * distance * distance; // Script Energy 4955 float distance_term = distance * distance * distance; // Script Energy
4532 float pusher_mass = m_host.GetMass(); 4956 // use total object mass and not part
4957 float pusher_mass = m_host.ParentGroup.GetMass();
4533 4958
4534 float PUSH_ATTENUATION_DISTANCE = 17f; 4959 float PUSH_ATTENUATION_DISTANCE = 17f;
4535 float PUSH_ATTENUATION_SCALE = 5f; 4960 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4779,6 +5204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4779 { 5204 {
4780 return item.AssetID.ToString(); 5205 return item.AssetID.ToString();
4781 } 5206 }
5207 m_host.TaskInventory.LockItemsForRead(false);
4782 5208
4783 return UUID.Zero.ToString(); 5209 return UUID.Zero.ToString();
4784 } 5210 }
@@ -4912,7 +5338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4912 public LSL_Vector llGetCenterOfMass() 5338 public LSL_Vector llGetCenterOfMass()
4913 { 5339 {
4914 m_host.AddScriptLPS(1); 5340 m_host.AddScriptLPS(1);
4915 Vector3 center = m_host.GetGeometricCenter(); 5341 Vector3 center = m_host.GetCenterOfMass();
4916 return new LSL_Vector(center.X,center.Y,center.Z); 5342 return new LSL_Vector(center.X,center.Y,center.Z);
4917 } 5343 }
4918 5344
@@ -4931,14 +5357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4931 { 5357 {
4932 m_host.AddScriptLPS(1); 5358 m_host.AddScriptLPS(1);
4933 5359
4934 if (src == null) 5360 return src.Length;
4935 {
4936 return 0;
4937 }
4938 else
4939 {
4940 return src.Length;
4941 }
4942 } 5361 }
4943 5362
4944 public LSL_Integer llList2Integer(LSL_List src, int index) 5363 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4984,7 +5403,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4984 else if (src.Data[index] is LSL_Float) 5403 else if (src.Data[index] is LSL_Float)
4985 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5404 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4986 else if (src.Data[index] is LSL_String) 5405 else if (src.Data[index] is LSL_String)
4987 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5406 {
5407 string str = ((LSL_String) src.Data[index]).m_string;
5408 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5409 if (m != Match.Empty)
5410 {
5411 str = m.Value;
5412 double d = 0.0;
5413 if (!Double.TryParse(str, out d))
5414 return 0.0;
5415
5416 return d;
5417 }
5418 return 0.0;
5419 }
4988 return Convert.ToDouble(src.Data[index]); 5420 return Convert.ToDouble(src.Data[index]);
4989 } 5421 }
4990 catch (FormatException) 5422 catch (FormatException)
@@ -5257,7 +5689,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5257 } 5689 }
5258 } 5690 }
5259 } 5691 }
5260 else { 5692 else
5693 {
5261 object[] array = new object[src.Length]; 5694 object[] array = new object[src.Length];
5262 Array.Copy(src.Data, 0, array, 0, src.Length); 5695 Array.Copy(src.Data, 0, array, 0, src.Length);
5263 result = new LSL_List(array); 5696 result = new LSL_List(array);
@@ -5364,7 +5797,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5364 public LSL_Integer llGetRegionAgentCount() 5797 public LSL_Integer llGetRegionAgentCount()
5365 { 5798 {
5366 m_host.AddScriptLPS(1); 5799 m_host.AddScriptLPS(1);
5367 return new LSL_Integer(World.GetRootAgentCount()); 5800
5801 int count = 0;
5802 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5803 count++;
5804 });
5805
5806 return new LSL_Integer(count);
5368 } 5807 }
5369 5808
5370 public LSL_Vector llGetRegionCorner() 5809 public LSL_Vector llGetRegionCorner()
@@ -5644,6 +6083,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5644 flags |= ScriptBaseClass.AGENT_SITTING; 6083 flags |= ScriptBaseClass.AGENT_SITTING;
5645 } 6084 }
5646 6085
6086 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6087 {
6088 flags |= ScriptBaseClass.AGENT_MALE;
6089 }
6090
5647 return flags; 6091 return flags;
5648 } 6092 }
5649 6093
@@ -5790,10 +6234,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5790 m_host.AddScriptLPS(1); 6234 m_host.AddScriptLPS(1);
5791 6235
5792 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6236 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5793 6237 if (parts.Count > 0)
5794 foreach (var part in parts)
5795 { 6238 {
5796 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6239 try
6240 {
6241 parts[0].ParentGroup.areUpdatesSuspended = true;
6242 foreach (var part in parts)
6243 {
6244 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6245 }
6246 }
6247 finally
6248 {
6249 parts[0].ParentGroup.areUpdatesSuspended = false;
6250 }
5797 } 6251 }
5798 } 6252 }
5799 6253
@@ -5845,13 +6299,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5845 6299
5846 if (m_host.OwnerID == land.LandData.OwnerID) 6300 if (m_host.OwnerID == land.LandData.OwnerID)
5847 { 6301 {
5848 World.TeleportClientHome(agentID, presence.ControllingClient); 6302 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6303 presence.TeleportWithMomentum(pos, null);
6304 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5849 } 6305 }
5850 } 6306 }
5851 } 6307 }
5852 ScriptSleep(5000); 6308 ScriptSleep(5000);
5853 } 6309 }
5854 6310
6311 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6312 {
6313 return ParseString2List(str, separators, in_spacers, false);
6314 }
6315
5855 public LSL_Integer llOverMyLand(string id) 6316 public LSL_Integer llOverMyLand(string id)
5856 { 6317 {
5857 m_host.AddScriptLPS(1); 6318 m_host.AddScriptLPS(1);
@@ -5916,8 +6377,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5916 UUID agentId = new UUID(); 6377 UUID agentId = new UUID();
5917 if (!UUID.TryParse(agent, out agentId)) 6378 if (!UUID.TryParse(agent, out agentId))
5918 return new LSL_Integer(0); 6379 return new LSL_Integer(0);
6380 if (agentId == m_host.GroupID)
6381 return new LSL_Integer(1);
5919 ScenePresence presence = World.GetScenePresence(agentId); 6382 ScenePresence presence = World.GetScenePresence(agentId);
5920 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6383 if (presence == null || presence.IsChildAgent) // Return false for child agents
5921 return new LSL_Integer(0); 6384 return new LSL_Integer(0);
5922 IClientAPI client = presence.ControllingClient; 6385 IClientAPI client = presence.ControllingClient;
5923 if (m_host.GroupID == client.ActiveGroupId) 6386 if (m_host.GroupID == client.ActiveGroupId)
@@ -6052,7 +6515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6052 return m_host.ParentGroup.AttachmentPoint; 6515 return m_host.ParentGroup.AttachmentPoint;
6053 } 6516 }
6054 6517
6055 public LSL_Integer llGetFreeMemory() 6518 public virtual LSL_Integer llGetFreeMemory()
6056 { 6519 {
6057 m_host.AddScriptLPS(1); 6520 m_host.AddScriptLPS(1);
6058 // Make scripts designed for LSO happy 6521 // Make scripts designed for LSO happy
@@ -6169,7 +6632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6169 SetParticleSystem(m_host, rules); 6632 SetParticleSystem(m_host, rules);
6170 } 6633 }
6171 6634
6172 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6635 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6636 {
6173 6637
6174 6638
6175 if (rules.Length == 0) 6639 if (rules.Length == 0)
@@ -6397,17 +6861,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6397 if (folderID == UUID.Zero) 6861 if (folderID == UUID.Zero)
6398 return; 6862 return;
6399 6863
6400 byte[] bucket = new byte[17]; 6864 byte[] bucket = new byte[1];
6401 bucket[0] = (byte)AssetType.Folder; 6865 bucket[0] = (byte)AssetType.Folder;
6402 byte[] objBytes = folderID.GetBytes(); 6866 //byte[] objBytes = folderID.GetBytes();
6403 Array.Copy(objBytes, 0, bucket, 1, 16); 6867 //Array.Copy(objBytes, 0, bucket, 1, 16);
6404 6868
6405 GridInstantMessage msg = new GridInstantMessage(World, 6869 GridInstantMessage msg = new GridInstantMessage(World,
6406 m_host.UUID, m_host.Name + ", an object owned by " + 6870 m_host.OwnerID, m_host.Name, destID,
6407 resolveName(m_host.OwnerID) + ",", destID, 6871 (byte)InstantMessageDialog.TaskInventoryOffered,
6408 (byte)InstantMessageDialog.InventoryOffered, 6872 false, category+". "+m_host.Name+" is located at "+
6409 false, category + "\n" + m_host.Name + " is located at " + 6873 World.RegionInfo.RegionName+" "+
6410 World.RegionInfo.RegionName + " " +
6411 m_host.AbsolutePosition.ToString(), 6874 m_host.AbsolutePosition.ToString(),
6412 folderID, true, m_host.AbsolutePosition, 6875 folderID, true, m_host.AbsolutePosition,
6413 bucket); 6876 bucket);
@@ -6487,7 +6950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6487 { 6950 {
6488 // LSL quaternions can normalize to 0, normal Quaternions can't. 6951 // LSL quaternions can normalize to 0, normal Quaternions can't.
6489 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6952 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6490 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6953 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6491 6954
6492 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6955 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6493 part.SitTargetOrientation = Rot2Quaternion(rot); 6956 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6644,13 +7107,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6644 UUID av = new UUID(); 7107 UUID av = new UUID();
6645 if (!UUID.TryParse(avatar,out av)) 7108 if (!UUID.TryParse(avatar,out av))
6646 { 7109 {
6647 LSLError("First parameter to llDialog needs to be a key"); 7110 //LSLError("First parameter to llDialog needs to be a key");
6648 return; 7111 return;
6649 } 7112 }
6650 if (buttons.Length < 1) 7113 if (buttons.Length < 1)
6651 { 7114 {
6652 LSLError("No less than 1 button can be shown"); 7115 buttons.Add("OK");
6653 return;
6654 } 7116 }
6655 if (buttons.Length > 12) 7117 if (buttons.Length > 12)
6656 { 7118 {
@@ -6667,7 +7129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6667 } 7129 }
6668 if (buttons.Data[i].ToString().Length > 24) 7130 if (buttons.Data[i].ToString().Length > 24)
6669 { 7131 {
6670 LSLError("button label cannot be longer than 24 characters"); 7132 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6671 return; 7133 return;
6672 } 7134 }
6673 buts[i] = buttons.Data[i].ToString(); 7135 buts[i] = buttons.Data[i].ToString();
@@ -6734,9 +7196,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6734 return; 7196 return;
6735 } 7197 }
6736 7198
6737 // the rest of the permission checks are done in RezScript, so check the pin there as well 7199 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6738 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7200 if (dest != null)
7201 {
7202 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7203 {
7204 // the rest of the permission checks are done in RezScript, so check the pin there as well
7205 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6739 7206
7207 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7208 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7209 }
7210 }
6740 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7211 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6741 ScriptSleep(3000); 7212 ScriptSleep(3000);
6742 } 7213 }
@@ -6799,19 +7270,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 public LSL_String llMD5String(string src, int nonce) 7270 public LSL_String llMD5String(string src, int nonce)
6800 { 7271 {
6801 m_host.AddScriptLPS(1); 7272 m_host.AddScriptLPS(1);
6802 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7273 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6803 } 7274 }
6804 7275
6805 public LSL_String llSHA1String(string src) 7276 public LSL_String llSHA1String(string src)
6806 { 7277 {
6807 m_host.AddScriptLPS(1); 7278 m_host.AddScriptLPS(1);
6808 return Util.SHA1Hash(src).ToLower(); 7279 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6809 } 7280 }
6810 7281
6811 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7282 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6812 { 7283 {
6813 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7284 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6814 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7285 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7286 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7287 return shapeBlock;
6815 7288
6816 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7289 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6817 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7290 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6916,6 +7389,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6916 // Prim type box, cylinder and prism. 7389 // Prim type box, cylinder and prism.
6917 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) 7390 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)
6918 { 7391 {
7392 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7393 return;
7394
6919 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7395 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6920 ObjectShapePacket.ObjectDataBlock shapeBlock; 7396 ObjectShapePacket.ObjectDataBlock shapeBlock;
6921 7397
@@ -6969,6 +7445,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6969 // Prim type sphere. 7445 // Prim type sphere.
6970 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7446 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6971 { 7447 {
7448 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7449 return;
7450
6972 ObjectShapePacket.ObjectDataBlock shapeBlock; 7451 ObjectShapePacket.ObjectDataBlock shapeBlock;
6973 7452
6974 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7453 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7010,6 +7489,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7010 // Prim type torus, tube and ring. 7489 // Prim type torus, tube and ring.
7011 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) 7490 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)
7012 { 7491 {
7492 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7493 return;
7494
7013 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7495 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7014 ObjectShapePacket.ObjectDataBlock shapeBlock; 7496 ObjectShapePacket.ObjectDataBlock shapeBlock;
7015 7497
@@ -7145,6 +7627,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7145 // Prim type sculpt. 7627 // Prim type sculpt.
7146 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7628 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7147 { 7629 {
7630 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7631 return;
7632
7148 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7633 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7149 UUID sculptId; 7634 UUID sculptId;
7150 7635
@@ -7169,7 +7654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7169 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7654 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7170 { 7655 {
7171 // default 7656 // default
7172 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7657 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7173 } 7658 }
7174 7659
7175 part.Shape.SetSculptProperties((byte)type, sculptId); 7660 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7185,34 +7670,298 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7185 ScriptSleep(200); 7670 ScriptSleep(200);
7186 } 7671 }
7187 7672
7188 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7673 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7189 { 7674 {
7190 m_host.AddScriptLPS(1); 7675 m_host.AddScriptLPS(1);
7191 7676
7192 setLinkPrimParams(linknumber, rules); 7677 setLinkPrimParams(linknumber, rules);
7678 }
7679
7680 private void setLinkPrimParams(int linknumber, LSL_List rules)
7681 {
7682 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7683 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7684 if (parts.Count>0)
7685 {
7686 try
7687 {
7688 parts[0].ParentGroup.areUpdatesSuspended = true;
7689 foreach (SceneObjectPart part in parts)
7690 SetPrimParams(part, rules);
7691 }
7692 finally
7693 {
7694 parts[0].ParentGroup.areUpdatesSuspended = false;
7695 }
7696 }
7697 if (avatars.Count > 0)
7698 {
7699 foreach (ScenePresence avatar in avatars)
7700 SetPrimParams(avatar, rules);
7701 }
7702 }
7703
7704 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7705 float material_density, float material_friction,
7706 float material_restitution, float material_gravity_modifier)
7707 {
7708 ExtraPhysicsData physdata = new ExtraPhysicsData();
7709 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7710 physdata.Density = part.Density;
7711 physdata.Friction = part.Friction;
7712 physdata.Bounce = part.Bounciness;
7713 physdata.GravitationModifier = part.GravityModifier;
7193 7714
7715 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7716 physdata.Density = material_density;
7717 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7718 physdata.Friction = material_friction;
7719 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7720 physdata.Bounce = material_restitution;
7721 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7722 physdata.GravitationModifier = material_gravity_modifier;
7723
7724 part.UpdateExtraPhysics(physdata);
7725 }
7726
7727 public void llSetPhysicsMaterial(int material_bits,
7728 float material_gravity_modifier, float material_restitution,
7729 float material_friction, float material_density)
7730 {
7731 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7732 }
7733
7734 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7735 {
7736 llSetLinkPrimitiveParamsFast(linknumber, rules);
7194 ScriptSleep(200); 7737 ScriptSleep(200);
7195 } 7738 }
7196 7739
7197 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7740 // vector up using libomv (c&p from sop )
7741 // vector up rotated by r
7742 private Vector3 Zrot(Quaternion r)
7198 { 7743 {
7199 m_host.AddScriptLPS(1); 7744 double x, y, z, m;
7200 7745
7201 setLinkPrimParams(linknumber, rules); 7746 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7747 if (Math.Abs(1.0 - m) > 0.000001)
7748 {
7749 m = 1.0 / Math.Sqrt(m);
7750 r.X *= (float)m;
7751 r.Y *= (float)m;
7752 r.Z *= (float)m;
7753 r.W *= (float)m;
7754 }
7755
7756 x = 2 * (r.X * r.Z + r.Y * r.W);
7757 y = 2 * (-r.X * r.W + r.Y * r.Z);
7758 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7759
7760 return new Vector3((float)x, (float)y, (float)z);
7202 } 7761 }
7203 7762
7204 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7763 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7205 { 7764 {
7206 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7765 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7207 7766
7208 foreach (SceneObjectPart part in parts) 7767 int idx = 0;
7209 SetPrimParams(part, rules); 7768
7769 bool positionChanged = false;
7770 Vector3 finalPos = Vector3.Zero;
7771
7772 try
7773 {
7774 while (idx < rules.Length)
7775 {
7776 int code = rules.GetLSLIntegerItem(idx++);
7777
7778 int remain = rules.Length - idx;
7779
7780 switch (code)
7781 {
7782 case (int)ScriptBaseClass.PRIM_POSITION:
7783 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7784 {
7785 if (remain < 1)
7786 return;
7787
7788 LSL_Vector v;
7789 v = rules.GetVector3Item(idx++);
7790
7791 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7792 if (part == null)
7793 break;
7794
7795 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7796 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7797 if (part.LinkNum > 1)
7798 {
7799 localRot = GetPartLocalRot(part);
7800 localPos = GetPartLocalPos(part);
7801 }
7802
7803 v -= localPos;
7804 v /= localRot;
7805
7806 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7807
7808 v = v + 2 * sitOffset;
7809
7810 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7811 av.SendAvatarDataToAllAgents();
7812
7813 }
7814 break;
7815
7816 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7817 case (int)ScriptBaseClass.PRIM_ROTATION:
7818 {
7819 if (remain < 1)
7820 return;
7821
7822 LSL_Rotation r;
7823 r = rules.GetQuaternionItem(idx++);
7824
7825 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7826 if (part == null)
7827 break;
7828
7829 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7830 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7831
7832 if (part.LinkNum > 1)
7833 localRot = GetPartLocalRot(part);
7834
7835 r = r * llGetRootRotation() / localRot;
7836 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7837 av.SendAvatarDataToAllAgents();
7838 }
7839 break;
7840
7841 // parse rest doing nothing but number of parameters error check
7842 case (int)ScriptBaseClass.PRIM_SIZE:
7843 case (int)ScriptBaseClass.PRIM_MATERIAL:
7844 case (int)ScriptBaseClass.PRIM_PHANTOM:
7845 case (int)ScriptBaseClass.PRIM_PHYSICS:
7846 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7847 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7848 case (int)ScriptBaseClass.PRIM_NAME:
7849 case (int)ScriptBaseClass.PRIM_DESC:
7850 if (remain < 1)
7851 return;
7852 idx++;
7853 break;
7854
7855 case (int)ScriptBaseClass.PRIM_GLOW:
7856 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7857 case (int)ScriptBaseClass.PRIM_TEXGEN:
7858 if (remain < 2)
7859 return;
7860 idx += 2;
7861 break;
7862
7863 case (int)ScriptBaseClass.PRIM_TYPE:
7864 if (remain < 3)
7865 return;
7866 code = (int)rules.GetLSLIntegerItem(idx++);
7867 remain = rules.Length - idx;
7868 switch (code)
7869 {
7870 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7871 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7872 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7873 if (remain < 6)
7874 return;
7875 idx += 6;
7876 break;
7877
7878 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7879 if (remain < 5)
7880 return;
7881 idx += 5;
7882 break;
7883
7884 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7885 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7886 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7887 if (remain < 11)
7888 return;
7889 idx += 11;
7890 break;
7891
7892 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7893 if (remain < 2)
7894 return;
7895 idx += 2;
7896 break;
7897 }
7898 break;
7899
7900 case (int)ScriptBaseClass.PRIM_COLOR:
7901 case (int)ScriptBaseClass.PRIM_TEXT:
7902 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7903 case (int)ScriptBaseClass.PRIM_OMEGA:
7904 if (remain < 3)
7905 return;
7906 idx += 3;
7907 break;
7908
7909 case (int)ScriptBaseClass.PRIM_TEXTURE:
7910 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7911 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7912 if (remain < 5)
7913 return;
7914 idx += 5;
7915 break;
7916
7917 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7918 if (remain < 7)
7919 return;
7920
7921 idx += 7;
7922 break;
7923
7924 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7925 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7926 return;
7927
7928 if (positionChanged)
7929 {
7930 positionChanged = false;
7931 av.OffsetPosition = finalPos;
7932// av.SendAvatarDataToAllAgents();
7933 av.SendTerseUpdateToAllClients();
7934 }
7935
7936 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7937 LSL_List new_rules = rules.GetSublist(idx, -1);
7938 setLinkPrimParams((int)new_linknumber, new_rules);
7939 return;
7940 }
7941 }
7942 }
7943
7944 finally
7945 {
7946 if (positionChanged)
7947 {
7948 av.OffsetPosition = finalPos;
7949// av.SendAvatarDataToAllAgents();
7950 av.SendTerseUpdateToAllClients();
7951 positionChanged = false;
7952 }
7953 }
7210 } 7954 }
7211 7955
7212 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7956 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7213 { 7957 {
7958 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7959 return;
7960
7214 int idx = 0; 7961 int idx = 0;
7215 7962
7963 SceneObjectGroup parentgrp = part.ParentGroup;
7964
7216 bool positionChanged = false; 7965 bool positionChanged = false;
7217 LSL_Vector currentPosition = GetPartLocalPos(part); 7966 LSL_Vector currentPosition = GetPartLocalPos(part);
7218 7967
@@ -7235,8 +7984,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7235 return; 7984 return;
7236 7985
7237 v=rules.GetVector3Item(idx++); 7986 v=rules.GetVector3Item(idx++);
7238 positionChanged = true;
7239 currentPosition = GetSetPosTarget(part, v, currentPosition); 7987 currentPosition = GetSetPosTarget(part, v, currentPosition);
7988 positionChanged = true;
7240 7989
7241 break; 7990 break;
7242 case (int)ScriptBaseClass.PRIM_SIZE: 7991 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7252,8 +8001,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7252 return; 8001 return;
7253 8002
7254 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8003 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8004 SceneObjectPart rootPart = parentgrp.RootPart;
7255 // try to let this work as in SL... 8005 // try to let this work as in SL...
7256 if (part.ParentID == 0) 8006 if (rootPart == part)
7257 { 8007 {
7258 // special case: If we are root, rotate complete SOG to new rotation 8008 // special case: If we are root, rotate complete SOG to new rotation
7259 SetRot(part, Rot2Quaternion(q)); 8009 SetRot(part, Rot2Quaternion(q));
@@ -7261,7 +8011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7261 else 8011 else
7262 { 8012 {
7263 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8013 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7264 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8014 // sounds like sl bug that we need to replicate
7265 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8015 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7266 } 8016 }
7267 8017
@@ -7514,7 +8264,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7514 return; 8264 return;
7515 8265
7516 string ph = rules.Data[idx++].ToString(); 8266 string ph = rules.Data[idx++].ToString();
7517 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8267 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7518 8268
7519 break; 8269 break;
7520 8270
@@ -7532,12 +8282,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7532 part.ScriptSetPhysicsStatus(physics); 8282 part.ScriptSetPhysicsStatus(physics);
7533 break; 8283 break;
7534 8284
8285 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8286 if (remain < 1)
8287 return;
8288
8289 int shape_type = rules.GetLSLIntegerItem(idx++);
8290
8291 ExtraPhysicsData physdata = new ExtraPhysicsData();
8292 physdata.Density = part.Density;
8293 physdata.Bounce = part.Bounciness;
8294 physdata.GravitationModifier = part.GravityModifier;
8295 physdata.PhysShapeType = (PhysShapeType)shape_type;
8296
8297 part.UpdateExtraPhysics(physdata);
8298
8299 break;
8300
8301 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8302 if (remain < 5)
8303 return;
8304
8305 int material_bits = rules.GetLSLIntegerItem(idx++);
8306 float material_density = (float)rules.GetLSLFloatItem(idx++);
8307 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8308 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8309 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8310
8311 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8312
8313 break;
8314
7535 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8315 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7536 if (remain < 1) 8316 if (remain < 1)
7537 return; 8317 return;
7538 string temp = rules.Data[idx++].ToString(); 8318 string temp = rules.Data[idx++].ToString();
7539 8319
7540 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8320 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7541 8321
7542 break; 8322 break;
7543 8323
@@ -7576,6 +8356,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7576 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8356 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7577 if (remain < 1) 8357 if (remain < 1)
7578 return; 8358 return;
8359
7579 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8360 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7580 SetRot(part, Rot2Quaternion(lr)); 8361 SetRot(part, Rot2Quaternion(lr));
7581 break; 8362 break;
@@ -7587,13 +8368,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7587 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8368 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7588 TargetOmega(part, axis, (double)spinrate, (double)gain); 8369 TargetOmega(part, axis, (double)spinrate, (double)gain);
7589 break; 8370 break;
8371
7590 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8372 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7591 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8373 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7592 return; 8374 return;
8375
8376 // do a pending position change before jumping to other part/avatar
8377 if (positionChanged)
8378 {
8379 positionChanged = false;
8380 if (parentgrp == null)
8381 return;
8382
8383 if (parentgrp.RootPart == part)
8384 {
8385
8386 Util.FireAndForget(delegate(object x)
8387 {
8388 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8389 });
8390 }
8391 else
8392 {
8393 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8394 parentgrp.HasGroupChanged = true;
8395 parentgrp.ScheduleGroupForTerseUpdate();
8396 }
8397 }
8398
7593 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8399 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7594 LSL_List new_rules = rules.GetSublist(idx, -1); 8400 LSL_List new_rules = rules.GetSublist(idx, -1);
7595 setLinkPrimParams((int)new_linknumber, new_rules); 8401 setLinkPrimParams((int)new_linknumber, new_rules);
7596
7597 return; 8402 return;
7598 } 8403 }
7599 } 8404 }
@@ -7605,7 +8410,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7605 if (part.ParentGroup.RootPart == part) 8410 if (part.ParentGroup.RootPart == part)
7606 { 8411 {
7607 SceneObjectGroup parent = part.ParentGroup; 8412 SceneObjectGroup parent = part.ParentGroup;
7608 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8413 Util.FireAndForget(delegate(object x) {
8414 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8415 });
7609 } 8416 }
7610 else 8417 else
7611 { 8418 {
@@ -7649,10 +8456,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7649 8456
7650 public LSL_String llXorBase64Strings(string str1, string str2) 8457 public LSL_String llXorBase64Strings(string str1, string str2)
7651 { 8458 {
7652 m_host.AddScriptLPS(1); 8459 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7653 Deprecated("llXorBase64Strings"); 8460
7654 ScriptSleep(300); 8461 ScriptSleep(300);
7655 return String.Empty; 8462 m_host.AddScriptLPS(1);
8463
8464 if (str1 == String.Empty)
8465 return String.Empty;
8466 if (str2 == String.Empty)
8467 return str1;
8468
8469 int len = str2.Length;
8470 if ((len % 4) != 0) // LL is EVIL!!!!
8471 {
8472 while (str2.EndsWith("="))
8473 str2 = str2.Substring(0, str2.Length - 1);
8474
8475 len = str2.Length;
8476 int mod = len % 4;
8477
8478 if (mod == 1)
8479 str2 = str2.Substring(0, str2.Length - 1);
8480 else if (mod == 2)
8481 str2 += "==";
8482 else if (mod == 3)
8483 str2 += "=";
8484 }
8485
8486 byte[] data1;
8487 byte[] data2;
8488 try
8489 {
8490 data1 = Convert.FromBase64String(str1);
8491 data2 = Convert.FromBase64String(str2);
8492 }
8493 catch (Exception)
8494 {
8495 return new LSL_String(String.Empty);
8496 }
8497
8498 // For cases where the decoded length of s2 is greater
8499 // than the decoded length of s1, simply perform a normal
8500 // decode and XOR
8501 //
8502 if (data2.Length >= data1.Length)
8503 {
8504 for (int pos = 0 ; pos < data1.Length ; pos++ )
8505 data1[pos] ^= data2[pos];
8506
8507 return Convert.ToBase64String(data1);
8508 }
8509
8510 // Remove padding
8511 while (str1.EndsWith("="))
8512 str1 = str1.Substring(0, str1.Length - 1);
8513 while (str2.EndsWith("="))
8514 str2 = str2.Substring(0, str2.Length - 1);
8515
8516 byte[] d1 = new byte[str1.Length];
8517 byte[] d2 = new byte[str2.Length];
8518
8519 for (int i = 0 ; i < str1.Length ; i++)
8520 {
8521 int idx = b64.IndexOf(str1.Substring(i, 1));
8522 if (idx == -1)
8523 idx = 0;
8524 d1[i] = (byte)idx;
8525 }
8526
8527 for (int i = 0 ; i < str2.Length ; i++)
8528 {
8529 int idx = b64.IndexOf(str2.Substring(i, 1));
8530 if (idx == -1)
8531 idx = 0;
8532 d2[i] = (byte)idx;
8533 }
8534
8535 string output = String.Empty;
8536
8537 for (int pos = 0 ; pos < d1.Length ; pos++)
8538 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8539
8540 while (output.Length % 3 > 0)
8541 output += "=";
8542
8543 return output;
7656 } 8544 }
7657 8545
7658 public void llRemoteDataSetRegion() 8546 public void llRemoteDataSetRegion()
@@ -7776,13 +8664,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 public LSL_Integer llGetNumberOfPrims() 8664 public LSL_Integer llGetNumberOfPrims()
7777 { 8665 {
7778 m_host.AddScriptLPS(1); 8666 m_host.AddScriptLPS(1);
7779 int avatarCount = 0; 8667 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7780 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8668
7781 {
7782 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7783 avatarCount++;
7784 });
7785
7786 return m_host.ParentGroup.PrimCount + avatarCount; 8669 return m_host.ParentGroup.PrimCount + avatarCount;
7787 } 8670 }
7788 8671
@@ -7798,55 +8681,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7798 m_host.AddScriptLPS(1); 8681 m_host.AddScriptLPS(1);
7799 UUID objID = UUID.Zero; 8682 UUID objID = UUID.Zero;
7800 LSL_List result = new LSL_List(); 8683 LSL_List result = new LSL_List();
8684
8685 // If the ID is not valid, return null result
7801 if (!UUID.TryParse(obj, out objID)) 8686 if (!UUID.TryParse(obj, out objID))
7802 { 8687 {
7803 result.Add(new LSL_Vector()); 8688 result.Add(new LSL_Vector());
7804 result.Add(new LSL_Vector()); 8689 result.Add(new LSL_Vector());
7805 return result; 8690 return result;
7806 } 8691 }
8692
8693 // Check if this is an attached prim. If so, replace
8694 // the UUID with the avatar UUID and report it's bounding box
8695 SceneObjectPart part = World.GetSceneObjectPart(objID);
8696 if (part != null && part.ParentGroup.IsAttachment)
8697 objID = part.ParentGroup.AttachedAvatar;
8698
8699 // Find out if this is an avatar ID. If so, return it's box
7807 ScenePresence presence = World.GetScenePresence(objID); 8700 ScenePresence presence = World.GetScenePresence(objID);
7808 if (presence != null) 8701 if (presence != null)
7809 { 8702 {
7810 if (presence.ParentID == 0) // not sat on an object 8703 // As per LSL Wiki, there is no difference between sitting
8704 // and standing avatar since server 1.36
8705 LSL_Vector lower;
8706 LSL_Vector upper;
8707 if (presence.Animator.Animations.DefaultAnimation.AnimID
8708 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7811 { 8709 {
7812 LSL_Vector lower; 8710 // This is for ground sitting avatars
7813 LSL_Vector upper; 8711 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7814 if (presence.Animator.Animations.DefaultAnimation.AnimID 8712 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7815 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8713 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7816 {
7817 // This is for ground sitting avatars
7818 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7819 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7820 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7821 }
7822 else
7823 {
7824 // This is for standing/flying avatars
7825 float height = presence.Appearance.AvatarHeight / 2.0f;
7826 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7827 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7828 }
7829 result.Add(lower);
7830 result.Add(upper);
7831 return result;
7832 } 8714 }
7833 else 8715 else
7834 { 8716 {
7835 // sitting on an object so we need the bounding box of that 8717 // This is for standing/flying avatars
7836 // which should include the avatar so set the UUID to the 8718 float height = presence.Appearance.AvatarHeight / 2.0f;
7837 // UUID of the object the avatar is sat on and allow it to fall through 8719 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7838 // to processing an object 8720 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7839 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7840 objID = p.UUID;
7841 } 8721 }
8722
8723 // Adjust to the documented error offsets (see LSL Wiki)
8724 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8725 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8726
8727 if (lower.x > upper.x)
8728 lower.x = upper.x;
8729 if (lower.y > upper.y)
8730 lower.y = upper.y;
8731 if (lower.z > upper.z)
8732 lower.z = upper.z;
8733
8734 result.Add(lower);
8735 result.Add(upper);
8736 return result;
7842 } 8737 }
7843 SceneObjectPart part = World.GetSceneObjectPart(objID); 8738
8739 part = World.GetSceneObjectPart(objID);
7844 // Currently only works for single prims without a sitting avatar 8740 // Currently only works for single prims without a sitting avatar
7845 if (part != null) 8741 if (part != null)
7846 { 8742 {
7847 Vector3 halfSize = part.Scale / 2.0f; 8743 float minX;
7848 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8744 float maxX;
7849 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8745 float minY;
8746 float maxY;
8747 float minZ;
8748 float maxZ;
8749
8750 // This BBox is in sim coordinates, with the offset being
8751 // a contained point.
8752 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8753 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8754
8755 minX -= offsets[0].X;
8756 maxX -= offsets[0].X;
8757 minY -= offsets[0].Y;
8758 maxY -= offsets[0].Y;
8759 minZ -= offsets[0].Z;
8760 maxZ -= offsets[0].Z;
8761
8762 LSL_Vector lower;
8763 LSL_Vector upper;
8764
8765 // Adjust to the documented error offsets (see LSL Wiki)
8766 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8767 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8768
8769 if (lower.x > upper.x)
8770 lower.x = upper.x;
8771 if (lower.y > upper.y)
8772 lower.y = upper.y;
8773 if (lower.z > upper.z)
8774 lower.z = upper.z;
8775
7850 result.Add(lower); 8776 result.Add(lower);
7851 result.Add(upper); 8777 result.Add(upper);
7852 return result; 8778 return result;
@@ -7860,7 +8786,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7860 8786
7861 public LSL_Vector llGetGeometricCenter() 8787 public LSL_Vector llGetGeometricCenter()
7862 { 8788 {
7863 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8789 Vector3 tmp = m_host.GetGeometricCenter();
8790 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7864 } 8791 }
7865 8792
7866 public LSL_List llGetPrimitiveParams(LSL_List rules) 8793 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7873,16 +8800,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7873 { 8800 {
7874 m_host.AddScriptLPS(1); 8801 m_host.AddScriptLPS(1);
7875 8802
8803 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8804 // keep other options as before
8805
7876 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8806 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8807 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7877 8808
7878 LSL_List res = new LSL_List(); 8809 LSL_List res = new LSL_List();
7879 8810
7880 foreach (var part in parts) 8811 if (parts.Count > 0)
7881 { 8812 {
7882 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8813 foreach (var part in parts)
7883 res += partRes; 8814 {
8815 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8816 res += partRes;
8817 }
8818 }
8819 if (avatars.Count > 0)
8820 {
8821 foreach (ScenePresence avatar in avatars)
8822 {
8823 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8824 res += avaRes;
8825 }
7884 } 8826 }
8827 return res;
8828 }
8829
8830 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8831 {
8832 // avatars case
8833 // replies as SL wiki
7885 8834
8835 LSL_List res = new LSL_List();
8836// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8837 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8838
8839 int idx = 0;
8840 while (idx < rules.Length)
8841 {
8842 int code = (int)rules.GetLSLIntegerItem(idx++);
8843 int remain = rules.Length - idx;
8844
8845 switch (code)
8846 {
8847 case (int)ScriptBaseClass.PRIM_MATERIAL:
8848 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8849 break;
8850
8851 case (int)ScriptBaseClass.PRIM_PHYSICS:
8852 res.Add(new LSL_Integer(0));
8853 break;
8854
8855 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8856 res.Add(new LSL_Integer(0));
8857 break;
8858
8859 case (int)ScriptBaseClass.PRIM_PHANTOM:
8860 res.Add(new LSL_Integer(0));
8861 break;
8862
8863 case (int)ScriptBaseClass.PRIM_POSITION:
8864
8865 Vector3 pos = avatar.OffsetPosition;
8866
8867 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8868 pos -= sitOffset;
8869
8870 if( sitPart != null)
8871 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8872
8873 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8874 break;
8875
8876 case (int)ScriptBaseClass.PRIM_SIZE:
8877 // as in llGetAgentSize above
8878 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8879 break;
8880
8881 case (int)ScriptBaseClass.PRIM_ROTATION:
8882 Quaternion rot = avatar.Rotation;
8883 if (sitPart != null)
8884 {
8885 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8886 }
8887
8888 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8889 break;
8890
8891 case (int)ScriptBaseClass.PRIM_TYPE:
8892 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8893 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8894 res.Add(new LSL_Vector(0f,1.0f,0f));
8895 res.Add(new LSL_Float(0.0f));
8896 res.Add(new LSL_Vector(0, 0, 0));
8897 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8898 res.Add(new LSL_Vector(0, 0, 0));
8899 break;
8900
8901 case (int)ScriptBaseClass.PRIM_TEXTURE:
8902 if (remain < 1)
8903 return res;
8904
8905 int face = (int)rules.GetLSLIntegerItem(idx++);
8906 if (face == ScriptBaseClass.ALL_SIDES)
8907 {
8908 for (face = 0; face < 21; face++)
8909 {
8910 res.Add(new LSL_String(""));
8911 res.Add(new LSL_Vector(0,0,0));
8912 res.Add(new LSL_Vector(0,0,0));
8913 res.Add(new LSL_Float(0.0));
8914 }
8915 }
8916 else
8917 {
8918 if (face >= 0 && face < 21)
8919 {
8920 res.Add(new LSL_String(""));
8921 res.Add(new LSL_Vector(0,0,0));
8922 res.Add(new LSL_Vector(0,0,0));
8923 res.Add(new LSL_Float(0.0));
8924 }
8925 }
8926 break;
8927
8928 case (int)ScriptBaseClass.PRIM_COLOR:
8929 if (remain < 1)
8930 return res;
8931
8932 face = (int)rules.GetLSLIntegerItem(idx++);
8933
8934 if (face == ScriptBaseClass.ALL_SIDES)
8935 {
8936 for (face = 0; face < 21; face++)
8937 {
8938 res.Add(new LSL_Vector(0,0,0));
8939 res.Add(new LSL_Float(0));
8940 }
8941 }
8942 else
8943 {
8944 res.Add(new LSL_Vector(0,0,0));
8945 res.Add(new LSL_Float(0));
8946 }
8947 break;
8948
8949 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8950 if (remain < 1)
8951 return res;
8952 face = (int)rules.GetLSLIntegerItem(idx++);
8953
8954 if (face == ScriptBaseClass.ALL_SIDES)
8955 {
8956 for (face = 0; face < 21; face++)
8957 {
8958 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8959 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8960 }
8961 }
8962 else
8963 {
8964 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8965 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8966 }
8967 break;
8968
8969 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8970 if (remain < 1)
8971 return res;
8972 face = (int)rules.GetLSLIntegerItem(idx++);
8973
8974 if (face == ScriptBaseClass.ALL_SIDES)
8975 {
8976 for (face = 0; face < 21; face++)
8977 {
8978 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8979 }
8980 }
8981 else
8982 {
8983 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8984 }
8985 break;
8986
8987 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8988 res.Add(new LSL_Integer(0));
8989 res.Add(new LSL_Integer(0));// softness
8990 res.Add(new LSL_Float(0.0f)); // gravity
8991 res.Add(new LSL_Float(0.0f)); // friction
8992 res.Add(new LSL_Float(0.0f)); // wind
8993 res.Add(new LSL_Float(0.0f)); // tension
8994 res.Add(new LSL_Vector(0f,0f,0f));
8995 break;
8996
8997 case (int)ScriptBaseClass.PRIM_TEXGEN:
8998 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8999 if (remain < 1)
9000 return res;
9001 face = (int)rules.GetLSLIntegerItem(idx++);
9002
9003 if (face == ScriptBaseClass.ALL_SIDES)
9004 {
9005 for (face = 0; face < 21; face++)
9006 {
9007 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9008 }
9009 }
9010 else
9011 {
9012 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9013 }
9014 break;
9015
9016 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9017 res.Add(new LSL_Integer(0));
9018 res.Add(new LSL_Vector(0f,0f,0f));
9019 res.Add(new LSL_Float(0f)); // intensity
9020 res.Add(new LSL_Float(0f)); // radius
9021 res.Add(new LSL_Float(0f)); // falloff
9022 break;
9023
9024 case (int)ScriptBaseClass.PRIM_GLOW:
9025 if (remain < 1)
9026 return res;
9027 face = (int)rules.GetLSLIntegerItem(idx++);
9028
9029 if (face == ScriptBaseClass.ALL_SIDES)
9030 {
9031 for (face = 0; face < 21; face++)
9032 {
9033 res.Add(new LSL_Float(0f));
9034 }
9035 }
9036 else
9037 {
9038 res.Add(new LSL_Float(0f));
9039 }
9040 break;
9041
9042 case (int)ScriptBaseClass.PRIM_TEXT:
9043 res.Add(new LSL_String(""));
9044 res.Add(new LSL_Vector(0f,0f,0f));
9045 res.Add(new LSL_Float(1.0f));
9046 break;
9047
9048 case (int)ScriptBaseClass.PRIM_NAME:
9049 res.Add(new LSL_String(avatar.Name));
9050 break;
9051
9052 case (int)ScriptBaseClass.PRIM_DESC:
9053 res.Add(new LSL_String(""));
9054 break;
9055
9056 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9057 Quaternion lrot = avatar.Rotation;
9058
9059 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9060 {
9061 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9062 }
9063 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9064 break;
9065
9066 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9067 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9068 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9069 lpos -= lsitOffset;
9070
9071 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9072 {
9073 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9074 }
9075 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9076 break;
9077
9078 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9079 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9080 return res;
9081 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9082 LSL_List new_rules = rules.GetSublist(idx, -1);
9083
9084 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9085 return res;
9086 }
9087 }
7886 return res; 9088 return res;
7887 } 9089 }
7888 9090
@@ -7926,13 +9128,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7926 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9128 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7927 part.AbsolutePosition.Y, 9129 part.AbsolutePosition.Y,
7928 part.AbsolutePosition.Z); 9130 part.AbsolutePosition.Z);
7929 // For some reason, the part.AbsolutePosition.* values do not change if the
7930 // linkset is rotated; they always reflect the child prim's world position
7931 // as though the linkset is unrotated. This is incompatible behavior with SL's
7932 // implementation, so will break scripts imported from there (not to mention it
7933 // makes it more difficult to determine a child prim's actual inworld position).
7934 if (part.ParentID != 0)
7935 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7936 res.Add(v); 9131 res.Add(v);
7937 break; 9132 break;
7938 9133
@@ -8103,56 +9298,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8103 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9298 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8104 if (remain < 1) 9299 if (remain < 1)
8105 return res; 9300 return res;
8106 9301 face = (int)rules.GetLSLIntegerItem(idx++);
8107 face=(int)rules.GetLSLIntegerItem(idx++);
8108 9302
8109 tex = part.Shape.Textures; 9303 tex = part.Shape.Textures;
9304 int shiny;
8110 if (face == ScriptBaseClass.ALL_SIDES) 9305 if (face == ScriptBaseClass.ALL_SIDES)
8111 { 9306 {
8112 for (face = 0; face < GetNumberOfSides(part); face++) 9307 for (face = 0; face < GetNumberOfSides(part); face++)
8113 { 9308 {
8114 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9309 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8115 // Convert Shininess to PRIM_SHINY_* 9310 if (shinyness == Shininess.High)
8116 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9311 {
8117 // PRIM_BUMP_* 9312 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8118 res.Add(new LSL_Integer((int)texface.Bump)); 9313 }
9314 else if (shinyness == Shininess.Medium)
9315 {
9316 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9317 }
9318 else if (shinyness == Shininess.Low)
9319 {
9320 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9321 }
9322 else
9323 {
9324 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9325 }
9326 res.Add(new LSL_Integer(shiny));
9327 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8119 } 9328 }
8120 } 9329 }
8121 else 9330 else
8122 { 9331 {
8123 if (face >= 0 && face < GetNumberOfSides(part)) 9332 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9333 if (shinyness == Shininess.High)
8124 { 9334 {
8125 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9335 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8126 // Convert Shininess to PRIM_SHINY_* 9336 }
8127 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9337 else if (shinyness == Shininess.Medium)
8128 // PRIM_BUMP_* 9338 {
8129 res.Add(new LSL_Integer((int)texface.Bump)); 9339 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9340 }
9341 else if (shinyness == Shininess.Low)
9342 {
9343 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8130 } 9344 }
9345 else
9346 {
9347 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9348 }
9349 res.Add(new LSL_Integer(shiny));
9350 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8131 } 9351 }
8132 break; 9352 break;
8133 9353
8134 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9354 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8135 if (remain < 1) 9355 if (remain < 1)
8136 return res; 9356 return res;
8137 9357 face = (int)rules.GetLSLIntegerItem(idx++);
8138 face=(int)rules.GetLSLIntegerItem(idx++);
8139 9358
8140 tex = part.Shape.Textures; 9359 tex = part.Shape.Textures;
9360 int fullbright;
8141 if (face == ScriptBaseClass.ALL_SIDES) 9361 if (face == ScriptBaseClass.ALL_SIDES)
8142 { 9362 {
8143 for (face = 0; face < GetNumberOfSides(part); face++) 9363 for (face = 0; face < GetNumberOfSides(part); face++)
8144 { 9364 {
8145 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9365 if (tex.GetFace((uint)face).Fullbright == true)
8146 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9366 {
9367 fullbright = ScriptBaseClass.TRUE;
9368 }
9369 else
9370 {
9371 fullbright = ScriptBaseClass.FALSE;
9372 }
9373 res.Add(new LSL_Integer(fullbright));
8147 } 9374 }
8148 } 9375 }
8149 else 9376 else
8150 { 9377 {
8151 if (face >= 0 && face < GetNumberOfSides(part)) 9378 if (tex.GetFace((uint)face).Fullbright == true)
8152 { 9379 {
8153 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9380 fullbright = ScriptBaseClass.TRUE;
8154 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9381 }
9382 else
9383 {
9384 fullbright = ScriptBaseClass.FALSE;
8155 } 9385 }
9386 res.Add(new LSL_Integer(fullbright));
8156 } 9387 }
8157 break; 9388 break;
8158 9389
@@ -8174,27 +9405,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8174 break; 9405 break;
8175 9406
8176 case (int)ScriptBaseClass.PRIM_TEXGEN: 9407 case (int)ScriptBaseClass.PRIM_TEXGEN:
9408 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8177 if (remain < 1) 9409 if (remain < 1)
8178 return res; 9410 return res;
8179 9411 face = (int)rules.GetLSLIntegerItem(idx++);
8180 face=(int)rules.GetLSLIntegerItem(idx++);
8181 9412
8182 tex = part.Shape.Textures; 9413 tex = part.Shape.Textures;
8183 if (face == ScriptBaseClass.ALL_SIDES) 9414 if (face == ScriptBaseClass.ALL_SIDES)
8184 { 9415 {
8185 for (face = 0; face < GetNumberOfSides(part); face++) 9416 for (face = 0; face < GetNumberOfSides(part); face++)
8186 { 9417 {
8187 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9418 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8188 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9419 {
8189 res.Add(new LSL_Integer((uint)texgen >> 1)); 9420 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9421 }
9422 else
9423 {
9424 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9425 }
8190 } 9426 }
8191 } 9427 }
8192 else 9428 else
8193 { 9429 {
8194 if (face >= 0 && face < GetNumberOfSides(part)) 9430 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9431 {
9432 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9433 }
9434 else
8195 { 9435 {
8196 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9436 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8197 res.Add(new LSL_Integer((uint)texgen >> 1));
8198 } 9437 }
8199 } 9438 }
8200 break; 9439 break;
@@ -8217,25 +9456,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 case (int)ScriptBaseClass.PRIM_GLOW: 9456 case (int)ScriptBaseClass.PRIM_GLOW:
8218 if (remain < 1) 9457 if (remain < 1)
8219 return res; 9458 return res;
8220 9459 face = (int)rules.GetLSLIntegerItem(idx++);
8221 face=(int)rules.GetLSLIntegerItem(idx++);
8222 9460
8223 tex = part.Shape.Textures; 9461 tex = part.Shape.Textures;
9462 float primglow;
8224 if (face == ScriptBaseClass.ALL_SIDES) 9463 if (face == ScriptBaseClass.ALL_SIDES)
8225 { 9464 {
8226 for (face = 0; face < GetNumberOfSides(part); face++) 9465 for (face = 0; face < GetNumberOfSides(part); face++)
8227 { 9466 {
8228 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9467 primglow = tex.GetFace((uint)face).Glow;
8229 res.Add(new LSL_Float(texface.Glow)); 9468 res.Add(new LSL_Float(primglow));
8230 } 9469 }
8231 } 9470 }
8232 else 9471 else
8233 { 9472 {
8234 if (face >= 0 && face < GetNumberOfSides(part)) 9473 primglow = tex.GetFace((uint)face).Glow;
8235 { 9474 res.Add(new LSL_Float(primglow));
8236 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8237 res.Add(new LSL_Float(texface.Glow));
8238 }
8239 } 9475 }
8240 break; 9476 break;
8241 9477
@@ -8247,18 +9483,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8247 textColor.B)); 9483 textColor.B));
8248 res.Add(new LSL_Float(textColor.A)); 9484 res.Add(new LSL_Float(textColor.A));
8249 break; 9485 break;
9486
8250 case (int)ScriptBaseClass.PRIM_NAME: 9487 case (int)ScriptBaseClass.PRIM_NAME:
8251 res.Add(new LSL_String(part.Name)); 9488 res.Add(new LSL_String(part.Name));
8252 break; 9489 break;
9490
8253 case (int)ScriptBaseClass.PRIM_DESC: 9491 case (int)ScriptBaseClass.PRIM_DESC:
8254 res.Add(new LSL_String(part.Description)); 9492 res.Add(new LSL_String(part.Description));
8255 break; 9493 break;
9494
8256 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9495 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8257 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9496 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8258 break; 9497 break;
9498
8259 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9499 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8260 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9500 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8261 break; 9501 break;
9502
9503 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9504 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9505 return res;
9506 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9507 LSL_List new_rules = rules.GetSublist(idx, -1);
9508 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9509 res += tres;
9510 return res;
8262 } 9511 }
8263 } 9512 }
8264 return res; 9513 return res;
@@ -8851,8 +10100,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8851 // The function returns an ordered list 10100 // The function returns an ordered list
8852 // representing the tokens found in the supplied 10101 // representing the tokens found in the supplied
8853 // sources string. If two successive tokenizers 10102 // sources string. If two successive tokenizers
8854 // are encountered, then a NULL entry is added 10103 // are encountered, then a null-string entry is
8855 // to the list. 10104 // added to the list.
8856 // 10105 //
8857 // It is a precondition that the source and 10106 // It is a precondition that the source and
8858 // toekizer lisst are non-null. If they are null, 10107 // toekizer lisst are non-null. If they are null,
@@ -8860,7 +10109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8860 // while their lengths are being determined. 10109 // while their lengths are being determined.
8861 // 10110 //
8862 // A small amount of working memoryis required 10111 // A small amount of working memoryis required
8863 // of approximately 8*#tokenizers. 10112 // of approximately 8*#tokenizers + 8*srcstrlen.
8864 // 10113 //
8865 // There are many ways in which this function 10114 // There are many ways in which this function
8866 // can be implemented, this implementation is 10115 // can be implemented, this implementation is
@@ -8876,155 +10125,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8876 // and eliminates redundant tokenizers as soon 10125 // and eliminates redundant tokenizers as soon
8877 // as is possible. 10126 // as is possible.
8878 // 10127 //
8879 // The implementation tries to avoid any copying 10128 // The implementation tries to minimize temporary
8880 // of arrays or other objects. 10129 // garbage generation.
8881 // </remarks> 10130 // </remarks>
8882 10131
8883 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10132 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8884 { 10133 {
8885 int beginning = 0; 10134 return ParseString2List(src, separators, spacers, true);
8886 int srclen = src.Length; 10135 }
8887 int seplen = separators.Length;
8888 object[] separray = separators.Data;
8889 int spclen = spacers.Length;
8890 object[] spcarray = spacers.Data;
8891 int mlen = seplen+spclen;
8892
8893 int[] offset = new int[mlen+1];
8894 bool[] active = new bool[mlen];
8895
8896 int best;
8897 int j;
8898
8899 // Initial capacity reduces resize cost
8900 10136
8901 LSL_List tokens = new LSL_List(); 10137 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10138 {
10139 int srclen = src.Length;
10140 int seplen = separators.Length;
10141 object[] separray = separators.Data;
10142 int spclen = spacers.Length;
10143 object[] spcarray = spacers.Data;
10144 int dellen = 0;
10145 string[] delarray = new string[seplen+spclen];
8902 10146
8903 // All entries are initially valid 10147 int outlen = 0;
10148 string[] outarray = new string[srclen*2+1];
8904 10149
8905 for (int i = 0; i < mlen; i++) 10150 int i, j;
8906 active[i] = true; 10151 string d;
8907 10152
8908 offset[mlen] = srclen; 10153 m_host.AddScriptLPS(1);
8909 10154
8910 while (beginning < srclen) 10155 /*
10156 * Convert separator and spacer lists to C# strings.
10157 * Also filter out null strings so we don't hang.
10158 */
10159 for (i = 0; i < seplen; i ++)
8911 { 10160 {
10161 d = separray[i].ToString();
10162 if (d.Length > 0)
10163 {
10164 delarray[dellen++] = d;
10165 }
10166 }
10167 seplen = dellen;
8912 10168
8913 best = mlen; // as bad as it gets 10169 for (i = 0; i < spclen; i ++)
10170 {
10171 d = spcarray[i].ToString();
10172 if (d.Length > 0)
10173 {
10174 delarray[dellen++] = d;
10175 }
10176 }
8914 10177
8915 // Scan for separators 10178 /*
10179 * Scan through source string from beginning to end.
10180 */
10181 for (i = 0;;)
10182 {
8916 10183
8917 for (j = 0; j < seplen; j++) 10184 /*
10185 * Find earliest delimeter in src starting at i (if any).
10186 */
10187 int earliestDel = -1;
10188 int earliestSrc = srclen;
10189 string earliestStr = null;
10190 for (j = 0; j < dellen; j ++)
8918 { 10191 {
8919 if (separray[j].ToString() == String.Empty) 10192 d = delarray[j];
8920 active[j] = false; 10193 if (d != null)
8921
8922 if (active[j])
8923 { 10194 {
8924 // scan all of the markers 10195 int index = src.IndexOf(d, i);
8925 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10196 if (index < 0)
8926 { 10197 {
8927 // not present at all 10198 delarray[j] = null; // delim nowhere in src, don't check it anymore
8928 active[j] = false;
8929 } 10199 }
8930 else 10200 else if (index < earliestSrc)
8931 { 10201 {
8932 // present and correct 10202 earliestSrc = index; // where delimeter starts in source string
8933 if (offset[j] < offset[best]) 10203 earliestDel = j; // where delimeter is in delarray[]
8934 { 10204 earliestStr = d; // the delimeter string from delarray[]
8935 // closest so far 10205 if (index == i) break; // can't do any better than found at beg of string
8936 best = j;
8937 if (offset[best] == beginning)
8938 break;
8939 }
8940 } 10206 }
8941 } 10207 }
8942 } 10208 }
8943 10209
8944 // Scan for spacers 10210 /*
8945 10211 * Output source string starting at i through start of earliest delimeter.
8946 if (offset[best] != beginning) 10212 */
10213 if (keepNulls || (earliestSrc > i))
8947 { 10214 {
8948 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10215 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8949 {
8950 if (spcarray[j-seplen].ToString() == String.Empty)
8951 active[j] = false;
8952
8953 if (active[j])
8954 {
8955 // scan all of the markers
8956 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8957 {
8958 // not present at all
8959 active[j] = false;
8960 }
8961 else
8962 {
8963 // present and correct
8964 if (offset[j] < offset[best])
8965 {
8966 // closest so far
8967 best = j;
8968 }
8969 }
8970 }
8971 }
8972 } 10216 }
8973 10217
8974 // This is the normal exit from the scanning loop 10218 /*
10219 * If no delimeter found at or after i, we're done scanning.
10220 */
10221 if (earliestDel < 0) break;
8975 10222
8976 if (best == mlen) 10223 /*
10224 * If delimeter was a spacer, output the spacer.
10225 */
10226 if (earliestDel >= seplen)
8977 { 10227 {
8978 // no markers were found on this pass 10228 outarray[outlen++] = earliestStr;
8979 // so we're pretty much done
8980 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8981 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8982 break;
8983 } 10229 }
8984 10230
8985 // Otherwise we just add the newly delimited token 10231 /*
8986 // and recalculate where the search should continue. 10232 * Look at rest of src string following delimeter.
8987 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10233 */
8988 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10234 i = earliestSrc + earliestStr.Length;
8989
8990 if (best < seplen)
8991 {
8992 beginning = offset[best] + (separray[best].ToString()).Length;
8993 }
8994 else
8995 {
8996 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8997 string str = spcarray[best - seplen].ToString();
8998 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8999 tokens.Add(new LSL_String(str));
9000 }
9001 } 10235 }
9002 10236
9003 // This an awkward an not very intuitive boundary case. If the 10237 /*
9004 // last substring is a tokenizer, then there is an implied trailing 10238 * Make up an exact-sized output array suitable for an LSL_List object.
9005 // null list entry. Hopefully the single comparison will not be too 10239 */
9006 // arduous. Alternatively the 'break' could be replced with a return 10240 object[] outlist = new object[outlen];
9007 // but that's shabby programming. 10241 for (i = 0; i < outlen; i ++)
9008
9009 if ((beginning == srclen) && (keepNulls))
9010 { 10242 {
9011 if (srclen != 0) 10243 outlist[i] = new LSL_String(outarray[i]);
9012 tokens.Add(new LSL_String(""));
9013 } 10244 }
9014 10245 return new LSL_List(outlist);
9015 return tokens;
9016 }
9017
9018 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9019 {
9020 m_host.AddScriptLPS(1);
9021 return this.ParseString(src, separators, spacers, false);
9022 }
9023
9024 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9025 {
9026 m_host.AddScriptLPS(1);
9027 return this.ParseString(src, separators, spacers, true);
9028 } 10246 }
9029 10247
9030 public LSL_Integer llGetObjectPermMask(int mask) 10248 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9119,6 +10337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9119 case 4: 10337 case 4:
9120 return (int)item.NextPermissions; 10338 return (int)item.NextPermissions;
9121 } 10339 }
10340 m_host.TaskInventory.LockItemsForRead(false);
9122 10341
9123 return -1; 10342 return -1;
9124 } 10343 }
@@ -9309,9 +10528,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9309 { 10528 {
9310 try 10529 try
9311 { 10530 {
10531 /*
9312 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10532 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9313 if (obj != null) 10533 if (obj != null)
9314 return (double)obj.GetMass(); 10534 return (double)obj.GetMass();
10535 */
10536 // return total object mass
10537 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10538 if (obj != null)
10539 return obj.GetMass();
10540
9315 // the object is null so the key is for an avatar 10541 // the object is null so the key is for an avatar
9316 ScenePresence avatar = World.GetScenePresence(key); 10542 ScenePresence avatar = World.GetScenePresence(key);
9317 if (avatar != null) 10543 if (avatar != null)
@@ -9331,7 +10557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9331 } 10557 }
9332 10558
9333 /// <summary> 10559 /// <summary>
9334 /// illListReplaceList removes the sub-list defined by the inclusive indices 10560 /// llListReplaceList removes the sub-list defined by the inclusive indices
9335 /// start and end and inserts the src list in its place. The inclusive 10561 /// start and end and inserts the src list in its place. The inclusive
9336 /// nature of the indices means that at least one element must be deleted 10562 /// nature of the indices means that at least one element must be deleted
9337 /// if the indices are within the bounds of the existing list. I.e. 2,2 10563 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9388,16 +10614,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9388 // based upon end. Note that if end exceeds the upper 10614 // based upon end. Note that if end exceeds the upper
9389 // bound in this case, the entire destination list 10615 // bound in this case, the entire destination list
9390 // is removed. 10616 // is removed.
9391 else 10617 else if (start == 0)
9392 { 10618 {
9393 if (end + 1 < dest.Length) 10619 if (end + 1 < dest.Length)
9394 {
9395 return src + dest.GetSublist(end + 1, -1); 10620 return src + dest.GetSublist(end + 1, -1);
9396 }
9397 else 10621 else
9398 {
9399 return src; 10622 return src;
9400 } 10623 }
10624 else // Start < 0
10625 {
10626 if (end + 1 < dest.Length)
10627 return dest.GetSublist(end + 1, -1);
10628 else
10629 return new LSL_List();
9401 } 10630 }
9402 } 10631 }
9403 // Finally, if start > end, we strip away a prefix and 10632 // Finally, if start > end, we strip away a prefix and
@@ -9448,17 +10677,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9448 int width = 0; 10677 int width = 0;
9449 int height = 0; 10678 int height = 0;
9450 10679
9451 ParcelMediaCommandEnum? commandToSend = null; 10680 uint commandToSend = 0;
9452 float time = 0.0f; // default is from start 10681 float time = 0.0f; // default is from start
9453 10682
9454 ScenePresence presence = null; 10683 ScenePresence presence = null;
9455 10684
9456 for (int i = 0; i < commandList.Data.Length; i++) 10685 for (int i = 0; i < commandList.Data.Length; i++)
9457 { 10686 {
9458 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10687 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9459 switch (command) 10688 switch (command)
9460 { 10689 {
9461 case ParcelMediaCommandEnum.Agent: 10690 case (uint)ParcelMediaCommandEnum.Agent:
9462 // we send only to one agent 10691 // we send only to one agent
9463 if ((i + 1) < commandList.Length) 10692 if ((i + 1) < commandList.Length)
9464 { 10693 {
@@ -9475,25 +10704,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9475 } 10704 }
9476 break; 10705 break;
9477 10706
9478 case ParcelMediaCommandEnum.Loop: 10707 case (uint)ParcelMediaCommandEnum.Loop:
9479 loop = 1; 10708 loop = 1;
9480 commandToSend = command; 10709 commandToSend = command;
9481 update = true; //need to send the media update packet to set looping 10710 update = true; //need to send the media update packet to set looping
9482 break; 10711 break;
9483 10712
9484 case ParcelMediaCommandEnum.Play: 10713 case (uint)ParcelMediaCommandEnum.Play:
9485 loop = 0; 10714 loop = 0;
9486 commandToSend = command; 10715 commandToSend = command;
9487 update = true; //need to send the media update packet to make sure it doesn't loop 10716 update = true; //need to send the media update packet to make sure it doesn't loop
9488 break; 10717 break;
9489 10718
9490 case ParcelMediaCommandEnum.Pause: 10719 case (uint)ParcelMediaCommandEnum.Pause:
9491 case ParcelMediaCommandEnum.Stop: 10720 case (uint)ParcelMediaCommandEnum.Stop:
9492 case ParcelMediaCommandEnum.Unload: 10721 case (uint)ParcelMediaCommandEnum.Unload:
9493 commandToSend = command; 10722 commandToSend = command;
9494 break; 10723 break;
9495 10724
9496 case ParcelMediaCommandEnum.Url: 10725 case (uint)ParcelMediaCommandEnum.Url:
9497 if ((i + 1) < commandList.Length) 10726 if ((i + 1) < commandList.Length)
9498 { 10727 {
9499 if (commandList.Data[i + 1] is LSL_String) 10728 if (commandList.Data[i + 1] is LSL_String)
@@ -9506,7 +10735,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 } 10735 }
9507 break; 10736 break;
9508 10737
9509 case ParcelMediaCommandEnum.Texture: 10738 case (uint)ParcelMediaCommandEnum.Texture:
9510 if ((i + 1) < commandList.Length) 10739 if ((i + 1) < commandList.Length)
9511 { 10740 {
9512 if (commandList.Data[i + 1] is LSL_String) 10741 if (commandList.Data[i + 1] is LSL_String)
@@ -9519,7 +10748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9519 } 10748 }
9520 break; 10749 break;
9521 10750
9522 case ParcelMediaCommandEnum.Time: 10751 case (uint)ParcelMediaCommandEnum.Time:
9523 if ((i + 1) < commandList.Length) 10752 if ((i + 1) < commandList.Length)
9524 { 10753 {
9525 if (commandList.Data[i + 1] is LSL_Float) 10754 if (commandList.Data[i + 1] is LSL_Float)
@@ -9531,7 +10760,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9531 } 10760 }
9532 break; 10761 break;
9533 10762
9534 case ParcelMediaCommandEnum.AutoAlign: 10763 case (uint)ParcelMediaCommandEnum.AutoAlign:
9535 if ((i + 1) < commandList.Length) 10764 if ((i + 1) < commandList.Length)
9536 { 10765 {
9537 if (commandList.Data[i + 1] is LSL_Integer) 10766 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9545,7 +10774,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9545 } 10774 }
9546 break; 10775 break;
9547 10776
9548 case ParcelMediaCommandEnum.Type: 10777 case (uint)ParcelMediaCommandEnum.Type:
9549 if ((i + 1) < commandList.Length) 10778 if ((i + 1) < commandList.Length)
9550 { 10779 {
9551 if (commandList.Data[i + 1] is LSL_String) 10780 if (commandList.Data[i + 1] is LSL_String)
@@ -9558,7 +10787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 } 10787 }
9559 break; 10788 break;
9560 10789
9561 case ParcelMediaCommandEnum.Desc: 10790 case (uint)ParcelMediaCommandEnum.Desc:
9562 if ((i + 1) < commandList.Length) 10791 if ((i + 1) < commandList.Length)
9563 { 10792 {
9564 if (commandList.Data[i + 1] is LSL_String) 10793 if (commandList.Data[i + 1] is LSL_String)
@@ -9571,7 +10800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9571 } 10800 }
9572 break; 10801 break;
9573 10802
9574 case ParcelMediaCommandEnum.Size: 10803 case (uint)ParcelMediaCommandEnum.Size:
9575 if ((i + 2) < commandList.Length) 10804 if ((i + 2) < commandList.Length)
9576 { 10805 {
9577 if (commandList.Data[i + 1] is LSL_Integer) 10806 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9641,7 +10870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9641 } 10870 }
9642 } 10871 }
9643 10872
9644 if (commandToSend != null) 10873 if (commandToSend != 0)
9645 { 10874 {
9646 // the commandList contained a start/stop/... command, too 10875 // the commandList contained a start/stop/... command, too
9647 if (presence == null) 10876 if (presence == null)
@@ -9678,7 +10907,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 10907
9679 if (aList.Data[i] != null) 10908 if (aList.Data[i] != null)
9680 { 10909 {
9681 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10910 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9682 { 10911 {
9683 case ParcelMediaCommandEnum.Url: 10912 case ParcelMediaCommandEnum.Url:
9684 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10913 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9735,15 +10964,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9735 10964
9736 if (quick_pay_buttons.Data.Length < 4) 10965 if (quick_pay_buttons.Data.Length < 4)
9737 { 10966 {
9738 LSLError("List must have at least 4 elements"); 10967 int x;
9739 return; 10968 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10969 {
10970 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10971 }
9740 } 10972 }
9741 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10973 int[] nPrice = new int[5];
9742 10974 nPrice[0] = price;
9743 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10975 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9744 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10976 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9745 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10977 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9746 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10978 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10979 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9747 m_host.ParentGroup.HasGroupChanged = true; 10980 m_host.ParentGroup.HasGroupChanged = true;
9748 } 10981 }
9749 10982
@@ -9760,7 +10993,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9760 return new LSL_Vector(); 10993 return new LSL_Vector();
9761 } 10994 }
9762 10995
9763 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10996// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10997 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9764 if (presence != null) 10998 if (presence != null)
9765 { 10999 {
9766 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11000 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9782,7 +11016,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 return new LSL_Rotation(); 11016 return new LSL_Rotation();
9783 } 11017 }
9784 11018
9785 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11019// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11020 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9786 if (presence != null) 11021 if (presence != null)
9787 { 11022 {
9788 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11023 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9842,8 +11077,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9842 { 11077 {
9843 m_host.AddScriptLPS(1); 11078 m_host.AddScriptLPS(1);
9844 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11079 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9845 if (detectedParams == null) return; // only works on the first detected avatar 11080 if (detectedParams == null)
9846 11081 {
11082 if (m_host.ParentGroup.IsAttachment == true)
11083 {
11084 detectedParams = new DetectParams();
11085 detectedParams.Key = m_host.OwnerID;
11086 }
11087 else
11088 {
11089 return;
11090 }
11091 }
11092
9847 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11093 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9848 if (avatar != null) 11094 if (avatar != null)
9849 { 11095 {
@@ -9851,6 +11097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9851 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11097 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9852 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11098 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9853 } 11099 }
11100
9854 ScriptSleep(1000); 11101 ScriptSleep(1000);
9855 } 11102 }
9856 11103
@@ -9974,12 +11221,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9974 11221
9975 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11222 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9976 object[] data = rules.Data; 11223 object[] data = rules.Data;
9977 for (int i = 0; i < data.Length; ++i) { 11224 for (int i = 0; i < data.Length; ++i)
11225 {
9978 int type = Convert.ToInt32(data[i++].ToString()); 11226 int type = Convert.ToInt32(data[i++].ToString());
9979 if (i >= data.Length) break; // odd number of entries => ignore the last 11227 if (i >= data.Length) break; // odd number of entries => ignore the last
9980 11228
9981 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11229 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9982 switch (type) { 11230 switch (type)
11231 {
9983 case ScriptBaseClass.CAMERA_FOCUS: 11232 case ScriptBaseClass.CAMERA_FOCUS:
9984 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11233 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9985 case ScriptBaseClass.CAMERA_POSITION: 11234 case ScriptBaseClass.CAMERA_POSITION:
@@ -10085,19 +11334,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11334 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10086 { 11335 {
10087 m_host.AddScriptLPS(1); 11336 m_host.AddScriptLPS(1);
10088 string ret = String.Empty; 11337
10089 string src1 = llBase64ToString(str1); 11338 if (str1 == String.Empty)
10090 string src2 = llBase64ToString(str2); 11339 return String.Empty;
10091 int c = 0; 11340 if (str2 == String.Empty)
10092 for (int i = 0; i < src1.Length; i++) 11341 return str1;
11342
11343 int len = str2.Length;
11344 if ((len % 4) != 0) // LL is EVIL!!!!
10093 { 11345 {
10094 ret += (char) (src1[i] ^ src2[c]); 11346 while (str2.EndsWith("="))
11347 str2 = str2.Substring(0, str2.Length - 1);
11348
11349 len = str2.Length;
11350 int mod = len % 4;
10095 11351
10096 c++; 11352 if (mod == 1)
10097 if (c >= src2.Length) 11353 str2 = str2.Substring(0, str2.Length - 1);
10098 c = 0; 11354 else if (mod == 2)
11355 str2 += "==";
11356 else if (mod == 3)
11357 str2 += "=";
10099 } 11358 }
10100 return llStringToBase64(ret); 11359
11360 byte[] data1;
11361 byte[] data2;
11362 try
11363 {
11364 data1 = Convert.FromBase64String(str1);
11365 data2 = Convert.FromBase64String(str2);
11366 }
11367 catch (Exception)
11368 {
11369 return new LSL_String(String.Empty);
11370 }
11371
11372 byte[] d2 = new Byte[data1.Length];
11373 int pos = 0;
11374
11375 if (data1.Length <= data2.Length)
11376 {
11377 Array.Copy(data2, 0, d2, 0, data1.Length);
11378 }
11379 else
11380 {
11381 while (pos < data1.Length)
11382 {
11383 len = data1.Length - pos;
11384 if (len > data2.Length)
11385 len = data2.Length;
11386
11387 Array.Copy(data2, 0, d2, pos, len);
11388 pos += len;
11389 }
11390 }
11391
11392 for (pos = 0 ; pos < data1.Length ; pos++ )
11393 data1[pos] ^= d2[pos];
11394
11395 return Convert.ToBase64String(data1);
10101 } 11396 }
10102 11397
10103 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11398 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10154,12 +11449,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10154 Regex r = new Regex(authregex); 11449 Regex r = new Regex(authregex);
10155 int[] gnums = r.GetGroupNumbers(); 11450 int[] gnums = r.GetGroupNumbers();
10156 Match m = r.Match(url); 11451 Match m = r.Match(url);
10157 if (m.Success) { 11452 if (m.Success)
10158 for (int i = 1; i < gnums.Length; i++) { 11453 {
11454 for (int i = 1; i < gnums.Length; i++)
11455 {
10159 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11456 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10160 //CaptureCollection cc = g.Captures; 11457 //CaptureCollection cc = g.Captures;
10161 } 11458 }
10162 if (m.Groups.Count == 5) { 11459 if (m.Groups.Count == 5)
11460 {
10163 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11461 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10164 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11462 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10165 } 11463 }
@@ -10362,6 +11660,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10362 11660
10363 LSL_List ret = new LSL_List(); 11661 LSL_List ret = new LSL_List();
10364 UUID key = new UUID(); 11662 UUID key = new UUID();
11663
11664
10365 if (UUID.TryParse(id, out key)) 11665 if (UUID.TryParse(id, out key))
10366 { 11666 {
10367 ScenePresence av = World.GetScenePresence(key); 11667 ScenePresence av = World.GetScenePresence(key);
@@ -10379,13 +11679,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10379 ret.Add(new LSL_String("")); 11679 ret.Add(new LSL_String(""));
10380 break; 11680 break;
10381 case ScriptBaseClass.OBJECT_POS: 11681 case ScriptBaseClass.OBJECT_POS:
10382 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11682 Vector3 avpos;
11683
11684 if (av.ParentID != 0 && av.ParentPart != null)
11685 {
11686 avpos = av.OffsetPosition;
11687
11688 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11689 avpos -= sitOffset;
11690
11691 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11692 }
11693 else
11694 avpos = av.AbsolutePosition;
11695
11696 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10383 break; 11697 break;
10384 case ScriptBaseClass.OBJECT_ROT: 11698 case ScriptBaseClass.OBJECT_ROT:
10385 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11699 Quaternion avrot = av.Rotation;
11700 if (av.ParentID != 0 && av.ParentPart != null)
11701 {
11702 avrot = av.ParentPart.GetWorldRotation() * avrot;
11703 }
11704 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10386 break; 11705 break;
10387 case ScriptBaseClass.OBJECT_VELOCITY: 11706 case ScriptBaseClass.OBJECT_VELOCITY:
10388 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11707 Vector3 avvel = av.Velocity;
11708 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10389 break; 11709 break;
10390 case ScriptBaseClass.OBJECT_OWNER: 11710 case ScriptBaseClass.OBJECT_OWNER:
10391 ret.Add(new LSL_String(id)); 11711 ret.Add(new LSL_String(id));
@@ -10441,17 +11761,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10441 case ScriptBaseClass.OBJECT_NAME: 11761 case ScriptBaseClass.OBJECT_NAME:
10442 ret.Add(new LSL_String(obj.Name)); 11762 ret.Add(new LSL_String(obj.Name));
10443 break; 11763 break;
10444 case ScriptBaseClass.OBJECT_DESC: 11764 case ScriptBaseClass.OBJECT_DESC:
10445 ret.Add(new LSL_String(obj.Description)); 11765 ret.Add(new LSL_String(obj.Description));
10446 break; 11766 break;
10447 case ScriptBaseClass.OBJECT_POS: 11767 case ScriptBaseClass.OBJECT_POS:
10448 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11768 Vector3 opos = obj.AbsolutePosition;
11769 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10449 break; 11770 break;
10450 case ScriptBaseClass.OBJECT_ROT: 11771 case ScriptBaseClass.OBJECT_ROT:
10451 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11772// Quaternion orot = obj.RotationOffset;
11773// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11774
11775 LSL_Rotation objrot = GetPartRot(obj);
11776 ret.Add(objrot);
10452 break; 11777 break;
10453 case ScriptBaseClass.OBJECT_VELOCITY: 11778 case ScriptBaseClass.OBJECT_VELOCITY:
10454 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11779 Vector3 ovel = obj.Velocity;
11780 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10455 break; 11781 break;
10456 case ScriptBaseClass.OBJECT_OWNER: 11782 case ScriptBaseClass.OBJECT_OWNER:
10457 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11783 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10485,9 +11811,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10485 // The value returned in SL for normal prims is prim count 11811 // The value returned in SL for normal prims is prim count
10486 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11812 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10487 break; 11813 break;
10488 // The following 3 costs I have intentionaly coded to return zero. They are part of 11814
10489 // "Land Impact" calculations. These calculations are probably not applicable 11815 // costs below may need to be diferent for root parts, need to check
10490 // to OpenSim and are not yet complete in SL
10491 case ScriptBaseClass.OBJECT_SERVER_COST: 11816 case ScriptBaseClass.OBJECT_SERVER_COST:
10492 // The linden calculation is here 11817 // The linden calculation is here
10493 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11818 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10495,16 +11820,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10495 ret.Add(new LSL_Float(0)); 11820 ret.Add(new LSL_Float(0));
10496 break; 11821 break;
10497 case ScriptBaseClass.OBJECT_STREAMING_COST: 11822 case ScriptBaseClass.OBJECT_STREAMING_COST:
10498 // The linden calculation is here 11823 // The value returned in SL for normal prims is prim count * 0.06
10499 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11824 ret.Add(new LSL_Float(obj.StreamingCost));
10500 // The value returned in SL for normal prims looks like the prim count * 0.06
10501 ret.Add(new LSL_Float(0));
10502 break; 11825 break;
10503 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11826 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10504 // The linden calculation is here 11827 // The value returned in SL for normal prims is prim count
10505 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11828 ret.Add(new LSL_Float(obj.PhysicsCost));
10506 // The value returned in SL for normal prims looks like the prim count
10507 ret.Add(new LSL_Float(0));
10508 break; 11829 break;
10509 default: 11830 default:
10510 // Invalid or unhandled constant. 11831 // Invalid or unhandled constant.
@@ -10693,15 +12014,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10693 return GetLinkPrimitiveParams(obj, rules); 12014 return GetLinkPrimitiveParams(obj, rules);
10694 } 12015 }
10695 12016
10696 public void print(string str) 12017 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10697 { 12018 {
10698 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12019 List<SceneObjectPart> parts = GetLinkParts(link);
10699 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12020 if (parts.Count < 1)
10700 if (ossl != null) 12021 return 0;
10701 { 12022
10702 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12023 return GetNumberOfSides(parts[0]);
10703 m_log.Info("LSL print():" + str);
10704 }
10705 } 12024 }
10706 12025
10707 private string Name2Username(string name) 12026 private string Name2Username(string name)
@@ -10746,7 +12065,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10746 12065
10747 return rq.ToString(); 12066 return rq.ToString();
10748 } 12067 }
10749 12068/*
12069 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12070 {
12071 m_SayShoutCount = 0;
12072 }
12073*/
10750 private struct Tri 12074 private struct Tri
10751 { 12075 {
10752 public Vector3 p1; 12076 public Vector3 p1;
@@ -10886,9 +12210,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10886 12210
10887 ContactResult result = new ContactResult (); 12211 ContactResult result = new ContactResult ();
10888 result.ConsumerID = group.LocalId; 12212 result.ConsumerID = group.LocalId;
10889 result.Depth = intersection.distance; 12213// result.Depth = intersection.distance;
10890 result.Normal = intersection.normal; 12214 result.Normal = intersection.normal;
10891 result.Pos = intersection.ipoint; 12215 result.Pos = intersection.ipoint;
12216 result.Depth = Vector3.Mag(rayStart - result.Pos);
10892 12217
10893 contacts.Add(result); 12218 contacts.Add(result);
10894 }); 12219 });
@@ -11021,6 +12346,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11021 12346
11022 return contacts[0]; 12347 return contacts[0];
11023 } 12348 }
12349/*
12350 // not done:
12351 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12352 {
12353 ContactResult[] contacts = null;
12354 World.ForEachSOG(delegate(SceneObjectGroup group)
12355 {
12356 if (m_host.ParentGroup == group)
12357 return;
12358
12359 if (group.IsAttachment)
12360 return;
12361
12362 if(group.RootPart.PhysActor != null)
12363 return;
12364
12365 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12366 });
12367 return contacts;
12368 }
12369*/
11024 12370
11025 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12371 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11026 { 12372 {
@@ -11062,32 +12408,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11062 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12408 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11063 12409
11064 12410
11065 if (checkTerrain) 12411 if (World.SuportsRayCastFiltered())
11066 { 12412 {
11067 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12413 if (dist == 0)
11068 if (groundContact != null) 12414 return list;
11069 results.Add((ContactResult)groundContact);
11070 }
11071 12415
11072 if (checkAgents) 12416 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11073 { 12417 if (checkTerrain)
11074 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12418 rayfilter |= RayFilterFlags.land;
11075 foreach (ContactResult r in agentHits) 12419// if (checkAgents)
11076 results.Add(r); 12420// rayfilter |= RayFilterFlags.agent;
11077 } 12421 if (checkPhysical)
12422 rayfilter |= RayFilterFlags.physical;
12423 if (checkNonPhysical)
12424 rayfilter |= RayFilterFlags.nonphysical;
12425 if (detectPhantom)
12426 rayfilter |= RayFilterFlags.LSLPhanton;
12427
12428 Vector3 direction = dir * ( 1/dist);
12429
12430 if(rayfilter == 0)
12431 {
12432 list.Add(new LSL_Integer(0));
12433 return list;
12434 }
12435
12436 // get some more contacts to sort ???
12437 int physcount = 4 * count;
12438 if (physcount > 20)
12439 physcount = 20;
12440
12441 object physresults;
12442 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12443
12444 if (physresults == null)
12445 {
12446 list.Add(new LSL_Integer(-3)); // timeout error
12447 return list;
12448 }
11078 12449
11079 if (checkPhysical || checkNonPhysical || detectPhantom) 12450 results = (List<ContactResult>)physresults;
12451
12452 // for now physics doesn't detect sitted avatars so do it outside physics
12453 if (checkAgents)
12454 {
12455 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12456 foreach (ContactResult r in agentHits)
12457 results.Add(r);
12458 }
12459
12460 // TODO: Replace this with a better solution. ObjectIntersection can only
12461 // detect nonphysical phantoms. They are detected by virtue of being
12462 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12463 // physicsl phantoms as done by the physics scene
12464 // We don't want anything else but phantoms here.
12465 if (detectPhantom)
12466 {
12467 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12468 foreach (ContactResult r in objectHits)
12469 results.Add(r);
12470 }
12471 }
12472 else
11080 { 12473 {
11081 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12474 if (checkTerrain)
11082 foreach (ContactResult r in objectHits) 12475 {
11083 results.Add(r); 12476 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12477 if (groundContact != null)
12478 results.Add((ContactResult)groundContact);
12479 }
12480
12481 if (checkAgents)
12482 {
12483 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12484 foreach (ContactResult r in agentHits)
12485 results.Add(r);
12486 }
12487
12488 if (checkPhysical || checkNonPhysical || detectPhantom)
12489 {
12490 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12491 foreach (ContactResult r in objectHits)
12492 results.Add(r);
12493 }
11084 } 12494 }
11085 12495
11086 results.Sort(delegate(ContactResult a, ContactResult b) 12496 results.Sort(delegate(ContactResult a, ContactResult b)
11087 { 12497 {
11088 return a.Depth.CompareTo(b.Depth); 12498 return a.Depth.CompareTo(b.Depth);
11089 }); 12499 });
11090 12500
11091 int values = 0; 12501 int values = 0;
11092 SceneObjectGroup thisgrp = m_host.ParentGroup; 12502 SceneObjectGroup thisgrp = m_host.ParentGroup;
11093 12503
@@ -11180,7 +12590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11180 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12590 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11181 if (!isAccount) return 0; 12591 if (!isAccount) return 0;
11182 if (estate.HasAccess(id)) return 1; 12592 if (estate.HasAccess(id)) return 1;
11183 if (estate.IsBanned(id)) 12593 if (estate.IsBanned(id, World.GetUserFlags(id)))
11184 estate.RemoveBan(id); 12594 estate.RemoveBan(id);
11185 estate.AddEstateUser(id); 12595 estate.AddEstateUser(id);
11186 break; 12596 break;
@@ -11199,14 +12609,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11199 break; 12609 break;
11200 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12610 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11201 if (!isAccount) return 0; 12611 if (!isAccount) return 0;
11202 if (estate.IsBanned(id)) return 1; 12612 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11203 EstateBan ban = new EstateBan(); 12613 EstateBan ban = new EstateBan();
11204 ban.EstateID = estate.EstateID; 12614 ban.EstateID = estate.EstateID;
11205 ban.BannedUserID = id; 12615 ban.BannedUserID = id;
11206 estate.AddBan(ban); 12616 estate.AddBan(ban);
11207 break; 12617 break;
11208 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12618 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11209 if (!isAccount || !estate.IsBanned(id)) return 0; 12619 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11210 estate.RemoveBan(id); 12620 estate.RemoveBan(id);
11211 break; 12621 break;
11212 default: return 0; 12622 default: return 0;
@@ -11235,7 +12645,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11235 return 16384; 12645 return 16384;
11236 } 12646 }
11237 12647
11238 public LSL_Integer llGetUsedMemory() 12648 public virtual LSL_Integer llGetUsedMemory()
11239 { 12649 {
11240 m_host.AddScriptLPS(1); 12650 m_host.AddScriptLPS(1);
11241 // The value returned for LSO scripts in SL 12651 // The value returned for LSO scripts in SL
@@ -11263,7 +12673,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11263 public void llSetSoundQueueing(int queue) 12673 public void llSetSoundQueueing(int queue)
11264 { 12674 {
11265 m_host.AddScriptLPS(1); 12675 m_host.AddScriptLPS(1);
11266 NotImplemented("llSetSoundQueueing");
11267 } 12676 }
11268 12677
11269 public void llCollisionSprite(string impact_sprite) 12678 public void llCollisionSprite(string impact_sprite)
@@ -11275,10 +12684,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11275 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12684 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11276 { 12685 {
11277 m_host.AddScriptLPS(1); 12686 m_host.AddScriptLPS(1);
11278 NotImplemented("llGodLikeRezObject"); 12687
12688 if (!World.Permissions.IsGod(m_host.OwnerID))
12689 NotImplemented("llGodLikeRezObject");
12690
12691 AssetBase rezAsset = World.AssetService.Get(inventory);
12692 if (rezAsset == null)
12693 {
12694 llSay(0, "Asset not found");
12695 return;
12696 }
12697
12698 SceneObjectGroup group = null;
12699
12700 try
12701 {
12702 string xmlData = Utils.BytesToString(rezAsset.Data);
12703 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12704 }
12705 catch
12706 {
12707 llSay(0, "Asset not found");
12708 return;
12709 }
12710
12711 if (group == null)
12712 {
12713 llSay(0, "Asset not found");
12714 return;
12715 }
12716
12717 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12718 group.RootPart.AttachOffset = group.AbsolutePosition;
12719
12720 group.ResetIDs();
12721
12722 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12723 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12724 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12725 group.ScheduleGroupForFullUpdate();
12726
12727 // objects rezzed with this method are die_at_edge by default.
12728 group.RootPart.SetDieAtEdge(true);
12729
12730 group.ResumeScripts();
12731
12732 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12733 "object_rez", new Object[] {
12734 new LSL_String(
12735 group.RootPart.UUID.ToString()) },
12736 new DetectParams[0]));
12737 }
12738
12739 public LSL_String llTransferLindenDollars(string destination, int amount)
12740 {
12741 UUID txn = UUID.Random();
12742
12743 Util.FireAndForget(delegate(object x)
12744 {
12745 int replycode = 0;
12746 string replydata = destination + "," + amount.ToString();
12747
12748 try
12749 {
12750 TaskInventoryItem item = m_item;
12751 if (item == null)
12752 {
12753 replydata = "SERVICE_ERROR";
12754 return;
12755 }
12756
12757 m_host.AddScriptLPS(1);
12758
12759 if (item.PermsGranter == UUID.Zero)
12760 {
12761 replydata = "MISSING_PERMISSION_DEBIT";
12762 return;
12763 }
12764
12765 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12766 {
12767 replydata = "MISSING_PERMISSION_DEBIT";
12768 return;
12769 }
12770
12771 UUID toID = new UUID();
12772
12773 if (!UUID.TryParse(destination, out toID))
12774 {
12775 replydata = "INVALID_AGENT";
12776 return;
12777 }
12778
12779 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12780
12781 if (money == null)
12782 {
12783 replydata = "TRANSFERS_DISABLED";
12784 return;
12785 }
12786
12787 bool result = money.ObjectGiveMoney(
12788 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12789
12790 if (result)
12791 {
12792 replycode = 1;
12793 return;
12794 }
12795
12796 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12797 }
12798 finally
12799 {
12800 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12801 "transaction_result", new Object[] {
12802 new LSL_String(txn.ToString()),
12803 new LSL_Integer(replycode),
12804 new LSL_String(replydata) },
12805 new DetectParams[0]));
12806 }
12807 });
12808
12809 return txn.ToString();
11279 } 12810 }
11280 12811
11281 #endregion 12812 #endregion
12813
12814 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12815 {
12816 SceneObjectGroup group = m_host.ParentGroup;
12817
12818 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12819 return;
12820 if (group.IsAttachment)
12821 return;
12822
12823 if (frames.Data.Length > 0) // We are getting a new motion
12824 {
12825 if (group.RootPart.KeyframeMotion != null)
12826 group.RootPart.KeyframeMotion.Stop();
12827 group.RootPart.KeyframeMotion = null;
12828
12829 int idx = 0;
12830
12831 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12832 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12833
12834 while (idx < options.Data.Length)
12835 {
12836 int option = (int)options.GetLSLIntegerItem(idx++);
12837 int remain = options.Data.Length - idx;
12838
12839 switch (option)
12840 {
12841 case ScriptBaseClass.KFM_MODE:
12842 if (remain < 1)
12843 break;
12844 int modeval = (int)options.GetLSLIntegerItem(idx++);
12845 switch(modeval)
12846 {
12847 case ScriptBaseClass.KFM_FORWARD:
12848 mode = KeyframeMotion.PlayMode.Forward;
12849 break;
12850 case ScriptBaseClass.KFM_REVERSE:
12851 mode = KeyframeMotion.PlayMode.Reverse;
12852 break;
12853 case ScriptBaseClass.KFM_LOOP:
12854 mode = KeyframeMotion.PlayMode.Loop;
12855 break;
12856 case ScriptBaseClass.KFM_PING_PONG:
12857 mode = KeyframeMotion.PlayMode.PingPong;
12858 break;
12859 }
12860 break;
12861 case ScriptBaseClass.KFM_DATA:
12862 if (remain < 1)
12863 break;
12864 int dataval = (int)options.GetLSLIntegerItem(idx++);
12865 data = (KeyframeMotion.DataFormat)dataval;
12866 break;
12867 }
12868 }
12869
12870 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12871
12872 idx = 0;
12873
12874 int elemLength = 2;
12875 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12876 elemLength = 3;
12877
12878 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12879 while (idx < frames.Data.Length)
12880 {
12881 int remain = frames.Data.Length - idx;
12882
12883 if (remain < elemLength)
12884 break;
12885
12886 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12887 frame.Position = null;
12888 frame.Rotation = null;
12889
12890 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12891 {
12892 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12893 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12894 }
12895 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12896 {
12897 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12898 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12899 }
12900
12901 float tempf = (float)frames.GetLSLFloatItem(idx++);
12902 frame.TimeMS = (int)(tempf * 1000.0f);
12903
12904 keyframes.Add(frame);
12905 }
12906
12907 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12908 group.RootPart.KeyframeMotion.Start();
12909 }
12910 else
12911 {
12912 if (group.RootPart.KeyframeMotion == null)
12913 return;
12914
12915 if (options.Data.Length == 0)
12916 {
12917 group.RootPart.KeyframeMotion.Stop();
12918 return;
12919 }
12920
12921 int code = (int)options.GetLSLIntegerItem(0);
12922
12923 int idx = 0;
12924
12925 while (idx < options.Data.Length)
12926 {
12927 int option = (int)options.GetLSLIntegerItem(idx++);
12928 int remain = options.Data.Length - idx;
12929
12930 switch (option)
12931 {
12932 case ScriptBaseClass.KFM_COMMAND:
12933 int cmd = (int)options.GetLSLIntegerItem(idx++);
12934 switch (cmd)
12935 {
12936 case ScriptBaseClass.KFM_CMD_PLAY:
12937 group.RootPart.KeyframeMotion.Start();
12938 break;
12939 case ScriptBaseClass.KFM_CMD_STOP:
12940 group.RootPart.KeyframeMotion.Stop();
12941 break;
12942 case ScriptBaseClass.KFM_CMD_PAUSE:
12943 group.RootPart.KeyframeMotion.Pause();
12944 break;
12945 }
12946 break;
12947 }
12948 }
12949 }
12950 }
11282 } 12951 }
11283 12952
11284 public class NotecardCache 12953 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 4137397..29d0342 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 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -916,18 +925,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
916 if (target != null) 925 if (target != null)
917 { 926 {
918 UUID animID=UUID.Zero; 927 UUID animID=UUID.Zero;
919 lock (m_host.TaskInventory) 928 m_host.TaskInventory.LockItemsForRead(true);
929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
920 { 930 {
921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 931 if (inv.Value.Name == animation)
922 { 932 {
923 if (inv.Value.Name == animation) 933 if (inv.Value.Type == (int)AssetType.Animation)
924 { 934 animID = inv.Value.AssetID;
925 if (inv.Value.Type == (int)AssetType.Animation) 935 continue;
926 animID = inv.Value.AssetID;
927 continue;
928 }
929 } 936 }
930 } 937 }
938 m_host.TaskInventory.LockItemsForRead(false);
931 if (animID == UUID.Zero) 939 if (animID == UUID.Zero)
932 target.Animator.AddAnimation(animation, m_host.UUID); 940 target.Animator.AddAnimation(animation, m_host.UUID);
933 else 941 else
@@ -968,6 +976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
968 else 976 else
969 animID = UUID.Zero; 977 animID = UUID.Zero;
970 } 978 }
979 m_host.TaskInventory.LockItemsForRead(false);
971 980
972 if (animID == UUID.Zero) 981 if (animID == UUID.Zero)
973 target.Animator.RemoveAnimation(animation); 982 target.Animator.RemoveAnimation(animation);
@@ -1801,6 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1801 1810
1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1811 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1803 { 1812 {
1813 m_host.TaskInventory.LockItemsForRead(true);
1804 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1814 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1805 { 1815 {
1806 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1816 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1808,6 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 assetID = item.AssetID; 1818 assetID = item.AssetID;
1809 } 1819 }
1810 } 1820 }
1821 m_host.TaskInventory.LockItemsForRead(false);
1811 } 1822 }
1812 1823
1813 if (assetID == UUID.Zero) 1824 if (assetID == UUID.Zero)
@@ -2279,7 +2290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2290 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2280 m_host.AddScriptLPS(1); 2291 m_host.AddScriptLPS(1);
2281 2292
2282 return NpcCreate(firstname, lastname, position, notecard, false, false); 2293 return NpcCreate(firstname, lastname, position, notecard, true, false);
2283 } 2294 }
2284 2295
2285 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2296 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2290,24 +2301,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2290 return NpcCreate( 2301 return NpcCreate(
2291 firstname, lastname, position, notecard, 2302 firstname, lastname, position, notecard,
2292 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2303 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2293 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2304 false);
2305// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2294 } 2306 }
2295 2307
2296 private LSL_Key NpcCreate( 2308 private LSL_Key NpcCreate(
2297 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2309 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2298 { 2310 {
2311 if (!owned)
2312 OSSLError("Unowned NPCs are unsupported");
2313
2314 string groupTitle = String.Empty;
2315
2316 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2317 return new LSL_Key(UUID.Zero.ToString());
2318
2319 if (firstname != String.Empty || lastname != String.Empty)
2320 {
2321 if (firstname != "Shown outfit:")
2322 groupTitle = "- NPC -";
2323 }
2324
2299 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2325 INPCModule module = World.RequestModuleInterface<INPCModule>();
2300 if (module != null) 2326 if (module != null)
2301 { 2327 {
2302 AvatarAppearance appearance = null; 2328 AvatarAppearance appearance = null;
2303 2329
2304 UUID id; 2330// UUID id;
2305 if (UUID.TryParse(notecard, out id)) 2331// if (UUID.TryParse(notecard, out id))
2306 { 2332// {
2307 ScenePresence clonePresence = World.GetScenePresence(id); 2333// ScenePresence clonePresence = World.GetScenePresence(id);
2308 if (clonePresence != null) 2334// if (clonePresence != null)
2309 appearance = clonePresence.Appearance; 2335// appearance = clonePresence.Appearance;
2310 } 2336// }
2311 2337
2312 if (appearance == null) 2338 if (appearance == null)
2313 { 2339 {
@@ -2335,6 +2361,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2335 World, 2361 World,
2336 appearance); 2362 appearance);
2337 2363
2364 ScenePresence sp;
2365 if (World.TryGetScenePresence(x, out sp))
2366 {
2367 sp.Grouptitle = groupTitle;
2368 sp.SendAvatarDataToAllAgents();
2369 }
2338 return new LSL_Key(x.ToString()); 2370 return new LSL_Key(x.ToString());
2339 } 2371 }
2340 2372
@@ -2626,16 +2658,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2626 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2658 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2627 m_host.AddScriptLPS(1); 2659 m_host.AddScriptLPS(1);
2628 2660
2629 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2661 ManualResetEvent ev = new ManualResetEvent(false);
2630 if (module != null)
2631 {
2632 UUID npcId = new UUID(npc.m_string);
2633 2662
2634 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2663 Util.FireAndForget(delegate(object x) {
2635 return; 2664 try
2665 {
2666 INPCModule module = World.RequestModuleInterface<INPCModule>();
2667 if (module != null)
2668 {
2669 UUID npcId = new UUID(npc.m_string);
2636 2670
2637 module.DeleteNPC(npcId, World); 2671 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2638 } 2672 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2673 {
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2675 return;
2676 }
2677
2678 module.DeleteNPC(npcId, World);
2679 }
2680 }
2681 finally
2682 {
2683 ev.Set();
2684 }
2685 });
2686 ev.WaitOne();
2639 } 2687 }
2640 2688
2641 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2689 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3275,4 +3323,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3275 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3323 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3276 } 3324 }
3277 } 3325 }
3278} \ No newline at end of file 3326}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.GetWorldRotation(); 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
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 3fb463b..af35258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index b5416c8..1facc96 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 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 b6c21e6..a08cc42 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -586,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
586 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
587 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
588 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
589 602
590 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
591 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -658,6 +671,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
658 671
659 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
660 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
661 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
662 } 688 }
663} 689}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..5c9d30f 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;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
@@ -189,6 +197,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Velocity.Z); 197 presence.Velocity.Z);
190 198
191 Type = 0x01; // Avatar 199 Type = 0x01; // Avatar
200 if (presence.PresenceType == PresenceType.Npc)
201 Type = 0x20;
192 if (presence.Velocity != Vector3.Zero) 202 if (presence.Velocity != Vector3.Zero)
193 Type |= 0x02; // Active 203 Type |= 0x02; // Active
194 204
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index d570ef7..983eed2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -415,14 +415,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
415 { 415 {
416 int permsMask; 416 int permsMask;
417 UUID permsGranter; 417 UUID permsGranter;
418 lock (part.TaskInventory) 418 part.TaskInventory.LockItemsForRead(true);
419 if (!part.TaskInventory.ContainsKey(ItemID))
419 { 420 {
420 if (!part.TaskInventory.ContainsKey(ItemID)) 421 part.TaskInventory.LockItemsForRead(false);
421 return; 422 return;
422
423 permsGranter = part.TaskInventory[ItemID].PermsGranter;
424 permsMask = part.TaskInventory[ItemID].PermsMask;
425 } 423 }
424 permsGranter = part.TaskInventory[ItemID].PermsGranter;
425 permsMask = part.TaskInventory[ItemID].PermsMask;
426 part.TaskInventory.LockItemsForRead(false);
426 427
427 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 428 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
428 { 429 {
@@ -550,6 +551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 551 return true;
551 } 552 }
552 553
554 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 555 public void SetState(string state)
554 { 556 {
555 if (state == State) 557 if (state == State)
@@ -561,7 +563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 563 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 564 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 565 new DetectParams[0]));
564 566
565 throw new EventAbortException(); 567 throw new EventAbortException();
566 } 568 }
567 569
@@ -651,45 +653,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
651 /// <returns></returns> 653 /// <returns></returns>
652 public object EventProcessor() 654 public object EventProcessor()
653 { 655 {
656 EventParams data = null;
654 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 657 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
655 if (!Running) 658 if (!Running)
656 return 0; 659 return 0;
657 660
658 lock (m_Script)
659 {
660// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 661// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
661 662
662 if (Suspended) 663 if (Suspended)
663 return 0; 664 return 0;
664
665 EventParams data = null;
666 665
667 lock (EventQueue) 666 lock (EventQueue)
667 {
668 data = (EventParams) EventQueue.Dequeue();
669 if (data == null) // Shouldn't happen
668 { 670 {
669 data = (EventParams)EventQueue.Dequeue(); 671 if (EventQueue.Count > 0 && Running && !ShuttingDown)
670 if (data == null) // Shouldn't happen
671 { 672 {
672 if (EventQueue.Count > 0 && Running && !ShuttingDown) 673 m_CurrentWorkItem = Engine.QueueEventHandler(this);
673 {
674 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 }
676 else
677 {
678 m_CurrentWorkItem = null;
679 }
680 return 0;
681 } 674 }
682 675 else
683 if (data.EventName == "timer")
684 m_TimerQueued = false;
685 if (data.EventName == "control")
686 { 676 {
687 if (m_ControlEventsInQueue > 0) 677 m_CurrentWorkItem = null;
688 m_ControlEventsInQueue--;
689 } 678 }
690 if (data.EventName == "collision") 679 return 0;
691 m_CollisionInQueue = false;
692 } 680 }
681
682 if (data.EventName == "timer")
683 m_TimerQueued = false;
684 if (data.EventName == "control")
685 {
686 if (m_ControlEventsInQueue > 0)
687 m_ControlEventsInQueue--;
688 }
689 if (data.EventName == "collision")
690 m_CollisionInQueue = false;
691 }
692
693 lock(m_Script)
694 {
693 695
694// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
695 697
@@ -844,6 +846,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
844 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
845 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
846 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
849 part.CollisionSound = UUID.Zero;
847 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 850 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
848 EventQueue.Clear(); 851 EventQueue.Clear();
849 m_Script.ResetVars(); 852 m_Script.ResetVars();
@@ -858,6 +861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
858 new Object[0], new DetectParams[0])); 861 new Object[0], new DetectParams[0]));
859 } 862 }
860 863
864 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
861 public void ApiResetScript() 865 public void ApiResetScript()
862 { 866 {
863 // bool running = Running; 867 // bool running = Running;
@@ -869,6 +873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
869 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 873 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
870 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 874 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
871 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 875 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
876 part.CollisionSound = UUID.Zero;
872 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 877 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
873 878
874 EventQueue.Clear(); 879 EventQueue.Clear();
@@ -889,10 +894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
889 894
890 public Dictionary<string, object> GetVars() 895 public Dictionary<string, object> GetVars()
891 { 896 {
892 if (m_Script != null) 897 return m_Script.GetVars();
893 return m_Script.GetVars();
894 else
895 return new Dictionary<string, object>();
896 } 898 }
897 899
898 public void SetVars(Dictionary<string, object> vars) 900 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 d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 01aebb6..35a0200 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -126,6 +127,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
126 private Dictionary<UUID, IScriptInstance> m_Scripts = 127 private Dictionary<UUID, IScriptInstance> m_Scripts =
127 new Dictionary<UUID, IScriptInstance>(); 128 new Dictionary<UUID, IScriptInstance>();
128 129
130 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
131
129 // Maps the asset ID to the assembly 132 // Maps the asset ID to the assembly
130 133
131 private Dictionary<UUID, string> m_Assemblies = 134 private Dictionary<UUID, string> m_Assemblies =
@@ -148,6 +151,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
148 IWorkItemResult m_CurrentCompile = null; 151 IWorkItemResult m_CurrentCompile = null;
149 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 152 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
150 153
154 private void lockScriptsForRead(bool locked)
155 {
156 if (locked)
157 {
158 if (m_scriptsLock.RecursiveReadCount > 0)
159 {
160 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
161 m_scriptsLock.ExitReadLock();
162 }
163 if (m_scriptsLock.RecursiveWriteCount > 0)
164 {
165 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
166 m_scriptsLock.ExitWriteLock();
167 }
168
169 while (!m_scriptsLock.TryEnterReadLock(60000))
170 {
171 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
172 if (m_scriptsLock.IsWriteLockHeld)
173 {
174 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
175 }
176 }
177 }
178 else
179 {
180 if (m_scriptsLock.RecursiveReadCount > 0)
181 {
182 m_scriptsLock.ExitReadLock();
183 }
184 }
185 }
186 private void lockScriptsForWrite(bool locked)
187 {
188 if (locked)
189 {
190 if (m_scriptsLock.RecursiveReadCount > 0)
191 {
192 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
193 m_scriptsLock.ExitReadLock();
194 }
195 if (m_scriptsLock.RecursiveWriteCount > 0)
196 {
197 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
198 m_scriptsLock.ExitWriteLock();
199 }
200
201 while (!m_scriptsLock.TryEnterWriteLock(60000))
202 {
203 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
204 if (m_scriptsLock.IsWriteLockHeld)
205 {
206 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
207 }
208 }
209 }
210 else
211 {
212 if (m_scriptsLock.RecursiveWriteCount > 0)
213 {
214 m_scriptsLock.ExitWriteLock();
215 }
216 }
217 }
218
151 public string ScriptEngineName 219 public string ScriptEngineName
152 { 220 {
153 get { return "XEngine"; } 221 get { return "XEngine"; }
@@ -574,52 +642,57 @@ namespace OpenSim.Region.ScriptEngine.XEngine
574 { 642 {
575 if (!m_Enabled) 643 if (!m_Enabled)
576 return; 644 return;
645 lockScriptsForRead(true);
577 646
578 lock (m_Scripts) 647 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
579 {
580 m_log.InfoFormat(
581 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
582 648
583 foreach (IScriptInstance instance in m_Scripts.Values) 649// foreach (IScriptInstance instance in m_Scripts.Values)
650 foreach (IScriptInstance instance in instancesToDel)
651 {
652 // Force a final state save
653 //
654 if (m_Assemblies.ContainsKey(instance.AssetID))
584 { 655 {
585 // Force a final state save 656 string assembly = m_Assemblies[instance.AssetID];
586 // 657 instance.SaveState(assembly);
587 if (m_Assemblies.ContainsKey(instance.AssetID)) 658 }
588 {
589 string assembly = m_Assemblies[instance.AssetID];
590 instance.SaveState(assembly);
591 }
592 659
593 // Clear the event queue and abort the instance thread 660 // Clear the event queue and abort the instance thread
594 // 661 //
595 instance.ClearQueue(); 662 instance.ClearQueue();
596 instance.Stop(0); 663 instance.Stop(0);
597 664
598 // Release events, timer, etc 665 // Release events, timer, etc
599 // 666 //
600 instance.DestroyScriptInstance(); 667 instance.DestroyScriptInstance();
601 668
602 // Unload scripts and app domains. 669 // Unload scripts and app domains
603 // Must be done explicitly because they have infinite 670 // Must be done explicitly because they have infinite
604 // lifetime. 671 // lifetime
605 // However, don't bother to do this if the simulator is shutting 672 //
606 // down since it takes a long time with many scripts. 673// if (!m_SimulatorShuttingDown)
607 if (!m_SimulatorShuttingDown) 674 {
675 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
676 if (m_DomainScripts[instance.AppDomain].Count == 0)
608 { 677 {
609 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 678 m_DomainScripts.Remove(instance.AppDomain);
610 if (m_DomainScripts[instance.AppDomain].Count == 0) 679 UnloadAppDomain(instance.AppDomain);
611 {
612 m_DomainScripts.Remove(instance.AppDomain);
613 UnloadAppDomain(instance.AppDomain);
614 }
615 } 680 }
616 } 681 }
617 682
618 m_Scripts.Clear(); 683// m_Scripts.Clear();
619 m_PrimObjects.Clear(); 684// m_PrimObjects.Clear();
620 m_Assemblies.Clear(); 685// m_Assemblies.Clear();
621 m_DomainScripts.Clear(); 686// m_DomainScripts.Clear();
622 } 687 }
688 lockScriptsForRead(false);
689 lockScriptsForWrite(true);
690 m_Scripts.Clear();
691 lockScriptsForWrite(false);
692 m_PrimObjects.Clear();
693 m_Assemblies.Clear();
694 m_DomainScripts.Clear();
695
623 lock (m_ScriptEngines) 696 lock (m_ScriptEngines)
624 { 697 {
625 m_ScriptEngines.Remove(this); 698 m_ScriptEngines.Remove(this);
@@ -684,22 +757,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
684 757
685 List<IScriptInstance> instances = new List<IScriptInstance>(); 758 List<IScriptInstance> instances = new List<IScriptInstance>();
686 759
687 lock (m_Scripts) 760 lockScriptsForRead(true);
688 { 761 foreach (IScriptInstance instance in m_Scripts.Values)
689 foreach (IScriptInstance instance in m_Scripts.Values)
690 instances.Add(instance); 762 instances.Add(instance);
691 } 763 lockScriptsForRead(false);
692 764
693 foreach (IScriptInstance i in instances) 765 foreach (IScriptInstance i in instances)
694 { 766 {
695 string assembly = String.Empty; 767 string assembly = String.Empty;
696 768
697 lock (m_Scripts) 769
698 {
699 if (!m_Assemblies.ContainsKey(i.AssetID)) 770 if (!m_Assemblies.ContainsKey(i.AssetID))
700 continue; 771 continue;
701 assembly = m_Assemblies[i.AssetID]; 772 assembly = m_Assemblies[i.AssetID];
702 } 773
703 774
704 i.SaveState(assembly); 775 i.SaveState(assembly);
705 } 776 }
@@ -1086,96 +1157,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1086 } 1157 }
1087 1158
1088 ScriptInstance instance = null; 1159 ScriptInstance instance = null;
1089 lock (m_Scripts) 1160 // Create the object record
1161 lockScriptsForRead(true);
1162 if ((!m_Scripts.ContainsKey(itemID)) ||
1163 (m_Scripts[itemID].AssetID != assetID))
1090 { 1164 {
1091 // Create the object record 1165 lockScriptsForRead(false);
1092 if ((!m_Scripts.ContainsKey(itemID)) || 1166
1093 (m_Scripts[itemID].AssetID != assetID)) 1167 UUID appDomain = assetID;
1094 {
1095 UUID appDomain = assetID;
1096 1168
1097 if (part.ParentGroup.IsAttachment) 1169 if (part.ParentGroup.IsAttachment)
1098 appDomain = part.ParentGroup.RootPart.UUID; 1170 appDomain = part.ParentGroup.RootPart.UUID;
1099 1171
1100 if (!m_AppDomains.ContainsKey(appDomain)) 1172 if (!m_AppDomains.ContainsKey(appDomain))
1173 {
1174 try
1101 { 1175 {
1102 try 1176 AppDomainSetup appSetup = new AppDomainSetup();
1103 { 1177 appSetup.PrivateBinPath = Path.Combine(
1104 AppDomainSetup appSetup = new AppDomainSetup(); 1178 m_ScriptEnginesPath,
1105 appSetup.PrivateBinPath = Path.Combine( 1179 m_Scene.RegionInfo.RegionID.ToString());
1106 m_ScriptEnginesPath,
1107 m_Scene.RegionInfo.RegionID.ToString());
1108 1180
1109 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1181 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1110 Evidence evidence = new Evidence(baseEvidence); 1182 Evidence evidence = new Evidence(baseEvidence);
1111 1183
1112 AppDomain sandbox; 1184 AppDomain sandbox;
1113 if (m_AppDomainLoading) 1185 if (m_AppDomainLoading)
1114 { 1186 {
1115 sandbox = AppDomain.CreateDomain( 1187 sandbox = AppDomain.CreateDomain(
1116 m_Scene.RegionInfo.RegionID.ToString(), 1188 m_Scene.RegionInfo.RegionID.ToString(),
1117 evidence, appSetup); 1189 evidence, appSetup);
1118 sandbox.AssemblyResolve += 1190 m_AppDomains[appDomain].AssemblyResolve +=
1119 new ResolveEventHandler( 1191 new ResolveEventHandler(
1120 AssemblyResolver.OnAssemblyResolve); 1192 AssemblyResolver.OnAssemblyResolve);
1121 }
1122 else
1123 {
1124 sandbox = AppDomain.CurrentDomain;
1125 }
1126
1127 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1128 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1129 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1130 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1131 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1132 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1133 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1134
1135 m_AppDomains[appDomain] = sandbox;
1136
1137 m_DomainScripts[appDomain] = new List<UUID>();
1138 } 1193 }
1139 catch (Exception e) 1194 else
1140 { 1195 {
1141 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1196 sandbox = AppDomain.CurrentDomain;
1142 m_ScriptErrorMessage += "Exception creating app domain:\n";
1143 m_ScriptFailCount++;
1144 lock (m_AddingAssemblies)
1145 {
1146 m_AddingAssemblies[assembly]--;
1147 }
1148 return false;
1149 } 1197 }
1150 }
1151 m_DomainScripts[appDomain].Add(itemID);
1152
1153 instance = new ScriptInstance(this, part,
1154 itemID, assetID, assembly,
1155 m_AppDomains[appDomain],
1156 part.ParentGroup.RootPart.Name,
1157 item.Name, startParam, postOnRez,
1158 stateSource, m_MaxScriptQueue);
1159
1160// if (DebugLevel >= 1)
1161 m_log.DebugFormat(
1162 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1163 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1164 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1165 1198
1166 if (presence != null) 1199 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1200 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1201 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1202 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1203 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1204 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1205 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1206
1207 m_AppDomains[appDomain] = sandbox;
1208
1209 m_DomainScripts[appDomain] = new List<UUID>();
1210 }
1211 catch (Exception e)
1167 { 1212 {
1168 ShowScriptSaveResponse(item.OwnerID, 1213 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1169 assetID, "Compile successful", true); 1214 m_ScriptErrorMessage += "Exception creating app domain:\n";
1215 m_ScriptFailCount++;
1216 lock (m_AddingAssemblies)
1217 {
1218 m_AddingAssemblies[assembly]--;
1219 }
1220 return false;
1170 } 1221 }
1222 }
1223 m_DomainScripts[appDomain].Add(itemID);
1224
1225 instance = new ScriptInstance(this, part,
1226 itemID, assetID, assembly,
1227 m_AppDomains[appDomain],
1228 part.ParentGroup.RootPart.Name,
1229 item.Name, startParam, postOnRez,
1230 stateSource, m_MaxScriptQueue);
1231
1232 m_log.DebugFormat(
1233 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1234 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1235 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1171 1236
1172 instance.AppDomain = appDomain; 1237 if (presence != null)
1173 instance.LineMap = linemap; 1238 {
1174 1239 ShowScriptSaveResponse(item.OwnerID,
1175 m_Scripts[itemID] = instance; 1240 assetID, "Compile successful", true);
1176 } 1241 }
1177 }
1178 1242
1243 instance.AppDomain = appDomain;
1244 instance.LineMap = linemap;
1245 lockScriptsForWrite(true);
1246 m_Scripts[itemID] = instance;
1247 lockScriptsForWrite(false);
1248 }
1249 else
1250 {
1251 lockScriptsForRead(false);
1252 }
1179 lock (m_PrimObjects) 1253 lock (m_PrimObjects)
1180 { 1254 {
1181 if (!m_PrimObjects.ContainsKey(localID)) 1255 if (!m_PrimObjects.ContainsKey(localID))
@@ -1193,9 +1267,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1193 m_AddingAssemblies[assembly]--; 1267 m_AddingAssemblies[assembly]--;
1194 } 1268 }
1195 1269
1196 if (instance != null) 1270 if (instance!=null)
1197 instance.Init(); 1271 instance.Init();
1198 1272
1199 return true; 1273 return true;
1200 } 1274 }
1201 1275
@@ -1208,18 +1282,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1208 m_CompileDict.Remove(itemID); 1282 m_CompileDict.Remove(itemID);
1209 } 1283 }
1210 1284
1211 IScriptInstance instance = null; 1285 lockScriptsForRead(true);
1212 1286 // Do we even have it?
1213 lock (m_Scripts) 1287 if (!m_Scripts.ContainsKey(itemID))
1214 { 1288 {
1215 // Do we even have it? 1289 // Do we even have it?
1216 if (!m_Scripts.ContainsKey(itemID)) 1290 if (!m_Scripts.ContainsKey(itemID))
1217 return; 1291 return;
1218 1292
1219 instance = m_Scripts[itemID]; 1293 lockScriptsForRead(false);
1294 lockScriptsForWrite(true);
1220 m_Scripts.Remove(itemID); 1295 m_Scripts.Remove(itemID);
1296 lockScriptsForWrite(false);
1297
1298 return;
1221 } 1299 }
1300
1222 1301
1302 IScriptInstance instance=m_Scripts[itemID];
1303 lockScriptsForRead(false);
1304 lockScriptsForWrite(true);
1305 m_Scripts.Remove(itemID);
1306 lockScriptsForWrite(false);
1223 instance.ClearQueue(); 1307 instance.ClearQueue();
1224 1308
1225 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1309 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1258,8 +1342,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1258 1342
1259 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1343 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1260 if (handlerObjectRemoved != null) 1344 if (handlerObjectRemoved != null)
1261 handlerObjectRemoved(instance.ObjectID); 1345 {
1346 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1347 handlerObjectRemoved(part.UUID);
1348 }
1262 1349
1350 CleanAssemblies();
1351
1263 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1352 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1264 if (handlerScriptRemoved != null) 1353 if (handlerScriptRemoved != null)
1265 handlerScriptRemoved(itemID); 1354 handlerScriptRemoved(itemID);
@@ -1520,12 +1609,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1520 private IScriptInstance GetInstance(UUID itemID) 1609 private IScriptInstance GetInstance(UUID itemID)
1521 { 1610 {
1522 IScriptInstance instance; 1611 IScriptInstance instance;
1523 lock (m_Scripts) 1612 lockScriptsForRead(true);
1613 if (!m_Scripts.ContainsKey(itemID))
1524 { 1614 {
1525 if (!m_Scripts.ContainsKey(itemID)) 1615 lockScriptsForRead(false);
1526 return null; 1616 return null;
1527 instance = m_Scripts[itemID];
1528 } 1617 }
1618 instance = m_Scripts[itemID];
1619 lockScriptsForRead(false);
1529 return instance; 1620 return instance;
1530 } 1621 }
1531 1622
@@ -1549,6 +1640,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1549 return false; 1640 return false;
1550 } 1641 }
1551 1642
1643 [DebuggerNonUserCode]
1552 public void ApiResetScript(UUID itemID) 1644 public void ApiResetScript(UUID itemID)
1553 { 1645 {
1554 IScriptInstance instance = GetInstance(itemID); 1646 IScriptInstance instance = GetInstance(itemID);
@@ -1604,6 +1696,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1604 return UUID.Zero; 1696 return UUID.Zero;
1605 } 1697 }
1606 1698
1699 [DebuggerNonUserCode]
1607 public void SetState(UUID itemID, string newState) 1700 public void SetState(UUID itemID, string newState)
1608 { 1701 {
1609 IScriptInstance instance = GetInstance(itemID); 1702 IScriptInstance instance = GetInstance(itemID);
@@ -1626,11 +1719,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1626 1719
1627 List<IScriptInstance> instances = new List<IScriptInstance>(); 1720 List<IScriptInstance> instances = new List<IScriptInstance>();
1628 1721
1629 lock (m_Scripts) 1722 lockScriptsForRead(true);
1630 { 1723 foreach (IScriptInstance instance in m_Scripts.Values)
1631 foreach (IScriptInstance instance in m_Scripts.Values)
1632 instances.Add(instance); 1724 instances.Add(instance);
1633 } 1725 lockScriptsForRead(false);
1634 1726
1635 foreach (IScriptInstance i in instances) 1727 foreach (IScriptInstance i in instances)
1636 { 1728 {