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.cs3166
-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, 3181 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..a43a8bb 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>
@@ -2187,7 +2451,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2187 public LSL_Rotation llGetLocalRot() 2451 public LSL_Rotation llGetLocalRot()
2188 { 2452 {
2189 m_host.AddScriptLPS(1); 2453 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); 2454 Quaternion rot = m_host.RotationOffset;
2455 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2191 } 2456 }
2192 2457
2193 public void llSetForce(LSL_Vector force, int local) 2458 public void llSetForce(LSL_Vector force, int local)
@@ -2271,16 +2536,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 m_host.ApplyImpulse(v, local != 0); 2536 m_host.ApplyImpulse(v, local != 0);
2272 } 2537 }
2273 2538
2539
2274 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2540 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2275 { 2541 {
2276 m_host.AddScriptLPS(1); 2542 m_host.AddScriptLPS(1);
2277 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2543 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2278 } 2544 }
2279 2545
2280 public void llSetTorque(LSL_Vector torque, int local) 2546 public void llSetTorque(LSL_Vector torque, int local)
2281 { 2547 {
2282 m_host.AddScriptLPS(1); 2548 m_host.AddScriptLPS(1);
2283 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2549 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2284 } 2550 }
2285 2551
2286 public LSL_Vector llGetTorque() 2552 public LSL_Vector llGetTorque()
@@ -2297,20 +2563,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 llSetTorque(torque, local); 2563 llSetTorque(torque, local);
2298 } 2564 }
2299 2565
2566 public void llSetVelocity(LSL_Vector vel, int local)
2567 {
2568 m_host.AddScriptLPS(1);
2569 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2570 }
2571
2300 public LSL_Vector llGetVel() 2572 public LSL_Vector llGetVel()
2301 { 2573 {
2302 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2303 2575
2304 Vector3 vel; 2576 Vector3 vel = Vector3.Zero;
2305 2577
2306 if (m_host.ParentGroup.IsAttachment) 2578 if (m_host.ParentGroup.IsAttachment)
2307 { 2579 {
2308 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2580 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2309 vel = avatar.Velocity; 2581 if (avatar != null)
2582 vel = avatar.Velocity;
2310 } 2583 }
2311 else 2584 else
2312 { 2585 {
2313 vel = m_host.Velocity; 2586 vel = m_host.ParentGroup.RootPart.Velocity;
2314 } 2587 }
2315 2588
2316 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2589 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2322,10 +2595,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2595 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2323 } 2596 }
2324 2597
2598 public void llSetAngularVelocity(LSL_Vector avel, int local)
2599 {
2600 m_host.AddScriptLPS(1);
2601 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2602 }
2603
2325 public LSL_Vector llGetOmega() 2604 public LSL_Vector llGetOmega()
2326 { 2605 {
2327 m_host.AddScriptLPS(1); 2606 m_host.AddScriptLPS(1);
2328 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2607 Vector3 avel = m_host.AngularVelocity;
2608 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2329 } 2609 }
2330 2610
2331 public LSL_Float llGetTimeOfDay() 2611 public LSL_Float llGetTimeOfDay()
@@ -2854,16 +3134,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2854 new_group.RootPart.UUID.ToString()) }, 3134 new_group.RootPart.UUID.ToString()) },
2855 new DetectParams[0])); 3135 new DetectParams[0]));
2856 3136
2857 float groupmass = new_group.GetMass(); 3137 // do recoil
3138 SceneObjectGroup hostgrp = m_host.ParentGroup;
3139 if (hostgrp == null)
3140 return;
3141
3142 if (hostgrp.IsAttachment) // don't recoil avatars
3143 return;
2858 3144
2859 PhysicsActor pa = new_group.RootPart.PhysActor; 3145 PhysicsActor pa = new_group.RootPart.PhysActor;
2860 3146
2861 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3147 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2862 { 3148 {
2863 //Recoil. 3149 float groupmass = new_group.GetMass();
2864 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3150 llvel *= -groupmass;
3151 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2865 } 3152 }
2866 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3153 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3154 return;
3155
2867 }); 3156 });
2868 3157
2869 //ScriptSleep((int)((groupmass * velmag) / 10)); 3158 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2878,35 +3167,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 public void llLookAt(LSL_Vector target, double strength, double damping) 3167 public void llLookAt(LSL_Vector target, double strength, double damping)
2879 { 3168 {
2880 m_host.AddScriptLPS(1); 3169 m_host.AddScriptLPS(1);
2881 // Determine where we are looking from
2882 LSL_Vector from = llGetPos();
2883 3170
2884 // Work out the normalised vector from the source to the target 3171 // Get the normalized vector to the target
2885 LSL_Vector delta = llVecNorm(target - from); 3172 LSL_Vector d1 = llVecNorm(target - llGetPos());
2886 LSL_Vector angle = new LSL_Vector(0,0,0);
2887 3173
2888 // Calculate the yaw 3174 // Get the bearing (yaw)
2889 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3175 LSL_Vector a1 = new LSL_Vector(0,0,0);
2890 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3176 a1.z = llAtan2(d1.y, d1.x);
2891 3177
2892 // Calculate pitch 3178 // Get the elevation (pitch)
2893 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3179 LSL_Vector a2 = new LSL_Vector(0,0,0);
3180 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2894 3181
2895 // we need to convert from a vector describing 3182 LSL_Rotation r1 = llEuler2Rot(a1);
2896 // the angles of rotation in radians into rotation value 3183 LSL_Rotation r2 = llEuler2Rot(a2);
2897 LSL_Rotation rot = llEuler2Rot(angle); 3184 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 3185
2903 if (strength == 0 || pa == null || !pa.IsPhysical) 3186 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2904 { 3187 {
2905 llSetRot(rot); 3188 // Do nothing if either value is 0 (this has been checked in SL)
3189 if (strength <= 0.0 || damping <= 0.0)
3190 return;
3191
3192 llSetRot(r3 * r2 * r1);
2906 } 3193 }
2907 else 3194 else
2908 { 3195 {
2909 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3196 if (strength == 0)
3197 {
3198 llSetRot(r3 * r2 * r1);
3199 return;
3200 }
3201
3202 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2910 } 3203 }
2911 } 3204 }
2912 3205
@@ -2952,17 +3245,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2952 } 3245 }
2953 else 3246 else
2954 { 3247 {
2955 if (m_host.IsRoot) 3248 // new SL always returns object mass
2956 { 3249// if (m_host.IsRoot)
3250// {
2957 return m_host.ParentGroup.GetMass(); 3251 return m_host.ParentGroup.GetMass();
2958 } 3252// }
2959 else 3253// else
2960 { 3254// {
2961 return m_host.GetMass(); 3255// return m_host.GetMass();
2962 } 3256// }
2963 } 3257 }
2964 } 3258 }
2965 3259
3260
3261 public LSL_Float llGetMassMKS()
3262 {
3263 return 100f * llGetMass();
3264 }
3265
2966 public void llCollisionFilter(string name, string id, int accept) 3266 public void llCollisionFilter(string name, string id, int accept)
2967 { 3267 {
2968 m_host.AddScriptLPS(1); 3268 m_host.AddScriptLPS(1);
@@ -3037,7 +3337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3337 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3038 3338
3039 if (attachmentsModule != null) 3339 if (attachmentsModule != null)
3040 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3340 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
3041 else 3341 else
3042 return false; 3342 return false;
3043 } 3343 }
@@ -3067,9 +3367,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3067 { 3367 {
3068 m_host.AddScriptLPS(1); 3368 m_host.AddScriptLPS(1);
3069 3369
3070// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3071// return;
3072
3073 if (m_item.PermsGranter != m_host.OwnerID) 3370 if (m_item.PermsGranter != m_host.OwnerID)
3074 return; 3371 return;
3075 3372
@@ -3112,6 +3409,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 3409
3113 public void llInstantMessage(string user, string message) 3410 public void llInstantMessage(string user, string message)
3114 { 3411 {
3412 UUID result;
3413 if (!UUID.TryParse(user, out result))
3414 {
3415 ShoutError("An invalid key was passed to llInstantMessage");
3416 ScriptSleep(2000);
3417 return;
3418 }
3419
3420
3115 m_host.AddScriptLPS(1); 3421 m_host.AddScriptLPS(1);
3116 3422
3117 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3423 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3126,14 +3432,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3126 UUID friendTransactionID = UUID.Random(); 3432 UUID friendTransactionID = UUID.Random();
3127 3433
3128 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3434 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3129 3435
3130 GridInstantMessage msg = new GridInstantMessage(); 3436 GridInstantMessage msg = new GridInstantMessage();
3131 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3437 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3132 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3438 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3133 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3439 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); 3440// 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()); 3441// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3136 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3442// DateTime dt = DateTime.UtcNow;
3443//
3444// // Ticks from UtcNow, but make it look like local. Evil, huh?
3445// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3446//
3447// try
3448// {
3449// // Convert that to the PST timezone
3450// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3451// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3452// }
3453// catch
3454// {
3455// // No logging here, as it could be VERY spammy
3456// }
3457//
3458// // And make it look local again to fool the unix time util
3459// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3460
3461 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3462
3137 //if (client != null) 3463 //if (client != null)
3138 //{ 3464 //{
3139 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3465 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3147,12 +3473,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3147 msg.message = message.Substring(0, 1024); 3473 msg.message = message.Substring(0, 1024);
3148 else 3474 else
3149 msg.message = message; 3475 msg.message = message;
3150 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3476 msg.dialog = (byte)19; // MessageFromObject
3151 msg.fromGroup = false;// fromGroup; 3477 msg.fromGroup = false;// fromGroup;
3152 msg.offline = (byte)0; //offline; 3478 msg.offline = (byte)0; //offline;
3153 msg.ParentEstateID = 0; //ParentEstateID; 3479 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3154 msg.Position = new Vector3(m_host.AbsolutePosition); 3480 msg.Position = new Vector3(m_host.AbsolutePosition);
3155 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3481 msg.RegionID = World.RegionInfo.RegionID.Guid;
3156 msg.binaryBucket 3482 msg.binaryBucket
3157 = Util.StringToBytes256( 3483 = Util.StringToBytes256(
3158 "{0}/{1}/{2}/{3}", 3484 "{0}/{1}/{2}/{3}",
@@ -3180,7 +3506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 } 3506 }
3181 3507
3182 emailModule.SendEmail(m_host.UUID, address, subject, message); 3508 emailModule.SendEmail(m_host.UUID, address, subject, message);
3183 llSleep(EMAIL_PAUSE_TIME); 3509 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3184 } 3510 }
3185 3511
3186 public void llGetNextEmail(string address, string subject) 3512 public void llGetNextEmail(string address, string subject)
@@ -3382,6 +3708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3382 3708
3383 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3709 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3384 { 3710 {
3711 spinrate *= gain;
3385 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3712 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)));
3386 } 3713 }
3387 3714
@@ -3424,15 +3751,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3424 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3751 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3425 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3752 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3426 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3753 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3754 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3427 ScriptBaseClass.PERMISSION_ATTACH; 3755 ScriptBaseClass.PERMISSION_ATTACH;
3428 3756
3429 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3757 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3430 { 3758 {
3431 lock (m_host.TaskInventory) 3759 m_host.TaskInventory.LockItemsForWrite(true);
3432 { 3760 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3433 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3761 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3434 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3762 m_host.TaskInventory.LockItemsForWrite(false);
3435 }
3436 3763
3437 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3764 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3765 "run_time_permissions", new Object[] {
@@ -3442,28 +3769,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3442 return; 3769 return;
3443 } 3770 }
3444 } 3771 }
3445 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3772 else
3446 { 3773 {
3447 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3774 bool sitting = false;
3448 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3775 if (m_host.SitTargetAvatar == agentID)
3449 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3776 {
3450 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3777 sitting = true;
3451 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3778 }
3779 else
3780 {
3781 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3782 {
3783 if (p.SitTargetAvatar == agentID)
3784 sitting = true;
3785 }
3786 }
3452 3787
3453 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3788 if (sitting)
3454 { 3789 {
3455 lock (m_host.TaskInventory) 3790 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3791 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3792 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3793 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3794 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3795
3796 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3456 { 3797 {
3798 m_host.TaskInventory.LockItemsForWrite(true);
3457 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3799 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3458 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3800 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3459 } 3801 m_host.TaskInventory.LockItemsForWrite(false);
3460 3802
3461 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3803 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3804 "run_time_permissions", new Object[] {
3463 new LSL_Integer(perm) }, 3805 new LSL_Integer(perm) },
3464 new DetectParams[0])); 3806 new DetectParams[0]));
3465 3807
3466 return; 3808 return;
3809 }
3467 } 3810 }
3468 } 3811 }
3469 3812
@@ -3500,11 +3843,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3500 3843
3501 if (!m_waitingForScriptAnswer) 3844 if (!m_waitingForScriptAnswer)
3502 { 3845 {
3503 lock (m_host.TaskInventory) 3846 m_host.TaskInventory.LockItemsForWrite(true);
3504 { 3847 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3505 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3848 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3506 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3849 m_host.TaskInventory.LockItemsForWrite(false);
3507 }
3508 3850
3509 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3851 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3510 m_waitingForScriptAnswer=true; 3852 m_waitingForScriptAnswer=true;
@@ -3533,14 +3875,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3875 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3534 llReleaseControls(); 3876 llReleaseControls();
3535 3877
3536 lock (m_host.TaskInventory) 3878 m_host.TaskInventory.LockItemsForWrite(true);
3537 { 3879 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3538 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3880 m_host.TaskInventory.LockItemsForWrite(false);
3539 } 3881
3540 3882 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3541 m_ScriptEngine.PostScriptEvent( 3883 "run_time_permissions", new Object[] {
3542 m_item.ItemID, 3884 new LSL_Integer(answer) },
3543 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3885 new DetectParams[0]));
3544 } 3886 }
3545 3887
3546 public LSL_String llGetPermissionsKey() 3888 public LSL_String llGetPermissionsKey()
@@ -3579,14 +3921,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3921 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3922 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3923 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3924 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3925 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3926 try
3927 {
3928 parts[0].ParentGroup.areUpdatesSuspended = true;
3929 foreach (SceneObjectPart part in parts)
3930 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3931 }
3932 finally
3933 {
3934 parts[0].ParentGroup.areUpdatesSuspended = false;
3935 }
3936 }
3585 } 3937 }
3586 3938
3587 public void llCreateLink(string target, int parent) 3939 public void llCreateLink(string target, int parent)
3588 { 3940 {
3589 m_host.AddScriptLPS(1); 3941 m_host.AddScriptLPS(1);
3942
3590 UUID targetID; 3943 UUID targetID;
3591 3944
3592 if (!UUID.TryParse(target, out targetID)) 3945 if (!UUID.TryParse(target, out targetID))
@@ -3692,10 +4045,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 // Restructuring Multiple Prims. 4045 // Restructuring Multiple Prims.
3693 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4046 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3694 parts.Remove(parentPrim.RootPart); 4047 parts.Remove(parentPrim.RootPart);
3695 foreach (SceneObjectPart part in parts) 4048 if (parts.Count > 0)
3696 { 4049 {
3697 parentPrim.DelinkFromGroup(part.LocalId, true); 4050 try
4051 {
4052 parts[0].ParentGroup.areUpdatesSuspended = true;
4053 foreach (SceneObjectPart part in parts)
4054 {
4055 parentPrim.DelinkFromGroup(part.LocalId, true);
4056 }
4057 }
4058 finally
4059 {
4060 parts[0].ParentGroup.areUpdatesSuspended = false;
4061 }
3698 } 4062 }
4063
3699 parentPrim.HasGroupChanged = true; 4064 parentPrim.HasGroupChanged = true;
3700 parentPrim.ScheduleGroupForFullUpdate(); 4065 parentPrim.ScheduleGroupForFullUpdate();
3701 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4066 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3704,12 +4069,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3704 { 4069 {
3705 SceneObjectPart newRoot = parts[0]; 4070 SceneObjectPart newRoot = parts[0];
3706 parts.Remove(newRoot); 4071 parts.Remove(newRoot);
3707 foreach (SceneObjectPart part in parts) 4072
4073 try
3708 { 4074 {
3709 // Required for linking 4075 parts[0].ParentGroup.areUpdatesSuspended = true;
3710 part.ClearUpdateSchedule(); 4076 foreach (SceneObjectPart part in parts)
3711 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4077 {
4078 part.ClearUpdateSchedule();
4079 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4080 }
3712 } 4081 }
4082 finally
4083 {
4084 parts[0].ParentGroup.areUpdatesSuspended = false;
4085 }
4086
4087
3713 newRoot.ParentGroup.HasGroupChanged = true; 4088 newRoot.ParentGroup.HasGroupChanged = true;
3714 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4089 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3715 } 4090 }
@@ -3729,6 +4104,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3729 public void llBreakAllLinks() 4104 public void llBreakAllLinks()
3730 { 4105 {
3731 m_host.AddScriptLPS(1); 4106 m_host.AddScriptLPS(1);
4107
4108 TaskInventoryItem item = m_item;
4109
4110 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4111 && !m_automaticLinkPermission)
4112 {
4113 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4114 return;
4115 }
4116
3732 SceneObjectGroup parentPrim = m_host.ParentGroup; 4117 SceneObjectGroup parentPrim = m_host.ParentGroup;
3733 if (parentPrim.AttachmentPoint != 0) 4118 if (parentPrim.AttachmentPoint != 0)
3734 return; // Fail silently if attached 4119 return; // Fail silently if attached
@@ -3748,25 +4133,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 public LSL_String llGetLinkKey(int linknum) 4133 public LSL_String llGetLinkKey(int linknum)
3749 { 4134 {
3750 m_host.AddScriptLPS(1); 4135 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); 4136 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3771 if (part != null) 4137 if (part != null)
3772 { 4138 {
@@ -3774,6 +4140,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 } 4140 }
3775 else 4141 else
3776 { 4142 {
4143 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4144 {
4145 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4146
4147 if (linknum < 0)
4148 return UUID.Zero.ToString();
4149
4150 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4151 if (avatars.Count > linknum)
4152 {
4153 return avatars[linknum].UUID.ToString();
4154 }
4155 }
3777 return UUID.Zero.ToString(); 4156 return UUID.Zero.ToString();
3778 } 4157 }
3779 } 4158 }
@@ -3873,17 +4252,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3873 m_host.AddScriptLPS(1); 4252 m_host.AddScriptLPS(1);
3874 int count = 0; 4253 int count = 0;
3875 4254
3876 lock (m_host.TaskInventory) 4255 m_host.TaskInventory.LockItemsForRead(true);
4256 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3877 { 4257 {
3878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4258 if (inv.Value.Type == type || type == -1)
3879 { 4259 {
3880 if (inv.Value.Type == type || type == -1) 4260 count = count + 1;
3881 {
3882 count = count + 1;
3883 }
3884 } 4261 }
3885 } 4262 }
3886 4263
4264 m_host.TaskInventory.LockItemsForRead(false);
3887 return count; 4265 return count;
3888 } 4266 }
3889 4267
@@ -3892,16 +4270,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3892 m_host.AddScriptLPS(1); 4270 m_host.AddScriptLPS(1);
3893 ArrayList keys = new ArrayList(); 4271 ArrayList keys = new ArrayList();
3894 4272
3895 lock (m_host.TaskInventory) 4273 m_host.TaskInventory.LockItemsForRead(true);
4274 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3896 { 4275 {
3897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4276 if (inv.Value.Type == type || type == -1)
3898 { 4277 {
3899 if (inv.Value.Type == type || type == -1) 4278 keys.Add(inv.Value.Name);
3900 {
3901 keys.Add(inv.Value.Name);
3902 }
3903 } 4279 }
3904 } 4280 }
4281 m_host.TaskInventory.LockItemsForRead(false);
3905 4282
3906 if (keys.Count == 0) 4283 if (keys.Count == 0)
3907 { 4284 {
@@ -3939,7 +4316,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3939 if (item == null) 4316 if (item == null)
3940 { 4317 {
3941 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4318 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)); 4319 return;
4320// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3943 } 4321 }
3944 4322
3945 UUID objId = item.ItemID; 4323 UUID objId = item.ItemID;
@@ -3967,34 +4345,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 return; 4345 return;
3968 } 4346 }
3969 } 4347 }
4348
3970 // destination is an avatar 4349 // destination is an avatar
3971 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4350 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3972 4351
3973 if (agentItem == null) 4352 if (agentItem == null)
3974 return; 4353 return;
3975 4354
3976 byte[] bucket = new byte[17]; 4355 byte[] bucket = new byte[1];
3977 bucket[0] = (byte)item.Type; 4356 bucket[0] = (byte)item.Type;
3978 byte[] objBytes = agentItem.ID.GetBytes(); 4357 //byte[] objBytes = agentItem.ID.GetBytes();
3979 Array.Copy(objBytes, 0, bucket, 1, 16); 4358 //Array.Copy(objBytes, 0, bucket, 1, 16);
3980 4359
3981 GridInstantMessage msg = new GridInstantMessage(World, 4360 GridInstantMessage msg = new GridInstantMessage(World,
3982 m_host.UUID, m_host.Name + ", an object owned by " + 4361 m_host.OwnerID, m_host.Name, destId,
3983 resolveName(m_host.OwnerID) + ",", destId,
3984 (byte)InstantMessageDialog.TaskInventoryOffered, 4362 (byte)InstantMessageDialog.TaskInventoryOffered,
3985 false, item.Name + "\n" + m_host.Name + " is located at " + 4363 false, item.Name+". "+m_host.Name+" is located at "+
3986 World.RegionInfo.RegionName+" "+ 4364 World.RegionInfo.RegionName+" "+
3987 m_host.AbsolutePosition.ToString(), 4365 m_host.AbsolutePosition.ToString(),
3988 agentItem.ID, true, m_host.AbsolutePosition, 4366 agentItem.ID, true, m_host.AbsolutePosition,
3989 bucket); 4367 bucket);
3990 4368
3991 if (m_TransferModule != null) 4369 ScenePresence sp;
3992 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3993 4370
4371 if (World.TryGetScenePresence(destId, out sp))
4372 {
4373 sp.ControllingClient.SendInstantMessage(msg);
4374 }
4375 else
4376 {
4377 if (m_TransferModule != null)
4378 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4379 }
4380
4381 //This delay should only occur when giving inventory to avatars.
3994 ScriptSleep(3000); 4382 ScriptSleep(3000);
3995 } 4383 }
3996 } 4384 }
3997 4385
4386 [DebuggerNonUserCode]
3998 public void llRemoveInventory(string name) 4387 public void llRemoveInventory(string name)
3999 { 4388 {
4000 m_host.AddScriptLPS(1); 4389 m_host.AddScriptLPS(1);
@@ -4040,109 +4429,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4040 { 4429 {
4041 m_host.AddScriptLPS(1); 4430 m_host.AddScriptLPS(1);
4042 4431
4043 UUID uuid = (UUID)id; 4432 UUID uuid;
4044 PresenceInfo pinfo = null; 4433 if (UUID.TryParse(id, out uuid))
4045 UserAccount account;
4046
4047 UserInfoCacheEntry ce;
4048 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4049 { 4434 {
4050 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4435 PresenceInfo pinfo = null;
4051 if (account == null) 4436 UserAccount account;
4437
4438 UserInfoCacheEntry ce;
4439 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4052 { 4440 {
4053 m_userInfoCache[uuid] = null; // Cache negative 4441 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4054 return UUID.Zero.ToString(); 4442 if (account == null)
4055 } 4443 {
4444 m_userInfoCache[uuid] = null; // Cache negative
4445 return UUID.Zero.ToString();
4446 }
4056 4447
4057 4448
4058 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4449 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4059 if (pinfos != null && pinfos.Length > 0) 4450 if (pinfos != null && pinfos.Length > 0)
4060 {
4061 foreach (PresenceInfo p in pinfos)
4062 { 4451 {
4063 if (p.RegionID != UUID.Zero) 4452 foreach (PresenceInfo p in pinfos)
4064 { 4453 {
4065 pinfo = p; 4454 if (p.RegionID != UUID.Zero)
4455 {
4456 pinfo = p;
4457 }
4066 } 4458 }
4067 } 4459 }
4068 }
4069 4460
4070 ce = new UserInfoCacheEntry(); 4461 ce = new UserInfoCacheEntry();
4071 ce.time = Util.EnvironmentTickCount(); 4462 ce.time = Util.EnvironmentTickCount();
4072 ce.account = account; 4463 ce.account = account;
4073 ce.pinfo = pinfo; 4464 ce.pinfo = pinfo;
4074 } 4465 m_userInfoCache[uuid] = ce;
4075 else 4466 }
4076 { 4467 else
4077 if (ce == null) 4468 {
4078 return UUID.Zero.ToString(); 4469 if (ce == null)
4470 return UUID.Zero.ToString();
4079 4471
4080 account = ce.account; 4472 account = ce.account;
4081 pinfo = ce.pinfo; 4473 pinfo = ce.pinfo;
4082 } 4474 }
4083 4475
4084 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4476 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 { 4477 {
4089 foreach (PresenceInfo p in pinfos) 4478 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4479 if (pinfos != null && pinfos.Length > 0)
4090 { 4480 {
4091 if (p.RegionID != UUID.Zero) 4481 foreach (PresenceInfo p in pinfos)
4092 { 4482 {
4093 pinfo = p; 4483 if (p.RegionID != UUID.Zero)
4484 {
4485 pinfo = p;
4486 }
4094 } 4487 }
4095 } 4488 }
4096 } 4489 else
4097 else 4490 pinfo = null;
4098 pinfo = null;
4099 4491
4100 ce.time = Util.EnvironmentTickCount(); 4492 ce.time = Util.EnvironmentTickCount();
4101 ce.pinfo = pinfo; 4493 ce.pinfo = pinfo;
4102 } 4494 }
4103 4495
4104 string reply = String.Empty; 4496 string reply = String.Empty;
4105 4497
4106 switch (data) 4498 switch (data)
4107 { 4499 {
4108 case 1: // DATA_ONLINE (0|1) 4500 case 1: // DATA_ONLINE (0|1)
4109 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4501 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4110 reply = "1"; 4502 reply = "1";
4111 else 4503 else
4112 reply = "0"; 4504 reply = "0";
4113 break; 4505 break;
4114 case 2: // DATA_NAME (First Last) 4506 case 2: // DATA_NAME (First Last)
4115 reply = account.FirstName + " " + account.LastName; 4507 reply = account.FirstName + " " + account.LastName;
4116 break; 4508 break;
4117 case 3: // DATA_BORN (YYYY-MM-DD) 4509 case 3: // DATA_BORN (YYYY-MM-DD)
4118 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4510 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4119 born = born.AddSeconds(account.Created); 4511 born = born.AddSeconds(account.Created);
4120 reply = born.ToString("yyyy-MM-dd"); 4512 reply = born.ToString("yyyy-MM-dd");
4121 break; 4513 break;
4122 case 4: // DATA_RATING (0,0,0,0,0,0) 4514 case 4: // DATA_RATING (0,0,0,0,0,0)
4123 reply = "0,0,0,0,0,0"; 4515 reply = "0,0,0,0,0,0";
4124 break; 4516 break;
4125 case 7: // DATA_USERLEVEL (integer) 4517 case 8: // DATA_PAYINFO (0|1|2|3)
4126 reply = account.UserLevel.ToString(); 4518 reply = "0";
4127 break; 4519 break;
4128 case 8: // DATA_PAYINFO (0|1|2|3) 4520 default:
4129 reply = "0"; 4521 return UUID.Zero.ToString(); // Raise no event
4130 break; 4522 }
4131 default:
4132 return UUID.Zero.ToString(); // Raise no event
4133 }
4134 4523
4135 UUID rq = UUID.Random(); 4524 UUID rq = UUID.Random();
4136 4525
4137 UUID tid = AsyncCommands. 4526 UUID tid = AsyncCommands.
4138 DataserverPlugin.RegisterRequest(m_host.LocalId, 4527 DataserverPlugin.RegisterRequest(m_host.LocalId,
4139 m_item.ItemID, rq.ToString()); 4528 m_item.ItemID, rq.ToString());
4140 4529
4141 AsyncCommands. 4530 AsyncCommands.
4142 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4531 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4143 4532
4144 ScriptSleep(100); 4533 ScriptSleep(100);
4145 return tid.ToString(); 4534 return tid.ToString();
4535 }
4536 else
4537 {
4538 ShoutError("Invalid UUID passed to llRequestAgentData.");
4539 }
4540 return "";
4146 } 4541 }
4147 4542
4148 public LSL_String llRequestInventoryData(string name) 4543 public LSL_String llRequestInventoryData(string name)
@@ -4199,13 +4594,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4199 if (UUID.TryParse(agent, out agentId)) 4594 if (UUID.TryParse(agent, out agentId))
4200 { 4595 {
4201 ScenePresence presence = World.GetScenePresence(agentId); 4596 ScenePresence presence = World.GetScenePresence(agentId);
4202 if (presence != null) 4597 if (presence != null && presence.PresenceType != PresenceType.Npc)
4203 { 4598 {
4599 // agent must not be a god
4600 if (presence.UserLevel >= 200) return;
4601
4204 // agent must be over the owners land 4602 // agent must be over the owners land
4205 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4603 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4206 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4604 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4207 { 4605 {
4208 World.TeleportClientHome(agentId, presence.ControllingClient); 4606 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4607 {
4608 // They can't be teleported home for some reason
4609 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4610 if (regionInfo != null)
4611 {
4612 World.RequestTeleportLocation(
4613 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4614 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4615 }
4616 }
4209 } 4617 }
4210 } 4618 }
4211 } 4619 }
@@ -4317,7 +4725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4317 UUID av = new UUID(); 4725 UUID av = new UUID();
4318 if (!UUID.TryParse(agent,out av)) 4726 if (!UUID.TryParse(agent,out av))
4319 { 4727 {
4320 LSLError("First parameter to llDialog needs to be a key"); 4728 //LSLError("First parameter to llDialog needs to be a key");
4321 return; 4729 return;
4322 } 4730 }
4323 4731
@@ -4349,7 +4757,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4349 public void llCollisionSound(string impact_sound, double impact_volume) 4757 public void llCollisionSound(string impact_sound, double impact_volume)
4350 { 4758 {
4351 m_host.AddScriptLPS(1); 4759 m_host.AddScriptLPS(1);
4352 4760
4761 if(impact_sound == "")
4762 {
4763 m_host.CollisionSoundVolume = (float)impact_volume;
4764 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4765 m_host.CollisionSoundType = 0;
4766 return;
4767 }
4353 // TODO: Parameter check logic required. 4768 // TODO: Parameter check logic required.
4354 UUID soundId = UUID.Zero; 4769 UUID soundId = UUID.Zero;
4355 if (!UUID.TryParse(impact_sound, out soundId)) 4770 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4362,6 +4777,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4362 4777
4363 m_host.CollisionSound = soundId; 4778 m_host.CollisionSound = soundId;
4364 m_host.CollisionSoundVolume = (float)impact_volume; 4779 m_host.CollisionSoundVolume = (float)impact_volume;
4780 m_host.CollisionSoundType = 1;
4365 } 4781 }
4366 4782
4367 public LSL_String llGetAnimation(string id) 4783 public LSL_String llGetAnimation(string id)
@@ -4375,14 +4791,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4375 4791
4376 if (m_host.RegionHandle == presence.RegionHandle) 4792 if (m_host.RegionHandle == presence.RegionHandle)
4377 { 4793 {
4378 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4379
4380 if (presence != null) 4794 if (presence != null)
4381 { 4795 {
4382 AnimationSet currentAnims = presence.Animator.Animations; 4796 if (presence.SitGround)
4383 string currentAnimationState = String.Empty; 4797 return "Sitting on Ground";
4384 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4798 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4385 return currentAnimationState; 4799 return "Sitting";
4800
4801 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4802 string lslMovementAnimation;
4803
4804 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4805 return lslMovementAnimation;
4386 } 4806 }
4387 } 4807 }
4388 4808
@@ -4529,7 +4949,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4529 { 4949 {
4530 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4950 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4531 float distance_term = distance * distance * distance; // Script Energy 4951 float distance_term = distance * distance * distance; // Script Energy
4532 float pusher_mass = m_host.GetMass(); 4952 // use total object mass and not part
4953 float pusher_mass = m_host.ParentGroup.GetMass();
4533 4954
4534 float PUSH_ATTENUATION_DISTANCE = 17f; 4955 float PUSH_ATTENUATION_DISTANCE = 17f;
4535 float PUSH_ATTENUATION_SCALE = 5f; 4956 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4779,6 +5200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4779 { 5200 {
4780 return item.AssetID.ToString(); 5201 return item.AssetID.ToString();
4781 } 5202 }
5203 m_host.TaskInventory.LockItemsForRead(false);
4782 5204
4783 return UUID.Zero.ToString(); 5205 return UUID.Zero.ToString();
4784 } 5206 }
@@ -4912,7 +5334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4912 public LSL_Vector llGetCenterOfMass() 5334 public LSL_Vector llGetCenterOfMass()
4913 { 5335 {
4914 m_host.AddScriptLPS(1); 5336 m_host.AddScriptLPS(1);
4915 Vector3 center = m_host.GetGeometricCenter(); 5337 Vector3 center = m_host.GetCenterOfMass();
4916 return new LSL_Vector(center.X,center.Y,center.Z); 5338 return new LSL_Vector(center.X,center.Y,center.Z);
4917 } 5339 }
4918 5340
@@ -4931,14 +5353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4931 { 5353 {
4932 m_host.AddScriptLPS(1); 5354 m_host.AddScriptLPS(1);
4933 5355
4934 if (src == null) 5356 return src.Length;
4935 {
4936 return 0;
4937 }
4938 else
4939 {
4940 return src.Length;
4941 }
4942 } 5357 }
4943 5358
4944 public LSL_Integer llList2Integer(LSL_List src, int index) 5359 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4984,7 +5399,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4984 else if (src.Data[index] is LSL_Float) 5399 else if (src.Data[index] is LSL_Float)
4985 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5400 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4986 else if (src.Data[index] is LSL_String) 5401 else if (src.Data[index] is LSL_String)
4987 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5402 {
5403 string str = ((LSL_String) src.Data[index]).m_string;
5404 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5405 if (m != Match.Empty)
5406 {
5407 str = m.Value;
5408 double d = 0.0;
5409 if (!Double.TryParse(str, out d))
5410 return 0.0;
5411
5412 return d;
5413 }
5414 return 0.0;
5415 }
4988 return Convert.ToDouble(src.Data[index]); 5416 return Convert.ToDouble(src.Data[index]);
4989 } 5417 }
4990 catch (FormatException) 5418 catch (FormatException)
@@ -5257,7 +5685,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5257 } 5685 }
5258 } 5686 }
5259 } 5687 }
5260 else { 5688 else
5689 {
5261 object[] array = new object[src.Length]; 5690 object[] array = new object[src.Length];
5262 Array.Copy(src.Data, 0, array, 0, src.Length); 5691 Array.Copy(src.Data, 0, array, 0, src.Length);
5263 result = new LSL_List(array); 5692 result = new LSL_List(array);
@@ -5364,7 +5793,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5364 public LSL_Integer llGetRegionAgentCount() 5793 public LSL_Integer llGetRegionAgentCount()
5365 { 5794 {
5366 m_host.AddScriptLPS(1); 5795 m_host.AddScriptLPS(1);
5367 return new LSL_Integer(World.GetRootAgentCount()); 5796
5797 int count = 0;
5798 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5799 count++;
5800 });
5801
5802 return new LSL_Integer(count);
5368 } 5803 }
5369 5804
5370 public LSL_Vector llGetRegionCorner() 5805 public LSL_Vector llGetRegionCorner()
@@ -5644,6 +6079,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5644 flags |= ScriptBaseClass.AGENT_SITTING; 6079 flags |= ScriptBaseClass.AGENT_SITTING;
5645 } 6080 }
5646 6081
6082 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6083 {
6084 flags |= ScriptBaseClass.AGENT_MALE;
6085 }
6086
5647 return flags; 6087 return flags;
5648 } 6088 }
5649 6089
@@ -5790,10 +6230,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5790 m_host.AddScriptLPS(1); 6230 m_host.AddScriptLPS(1);
5791 6231
5792 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6232 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5793 6233 if (parts.Count > 0)
5794 foreach (var part in parts)
5795 { 6234 {
5796 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6235 try
6236 {
6237 parts[0].ParentGroup.areUpdatesSuspended = true;
6238 foreach (var part in parts)
6239 {
6240 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6241 }
6242 }
6243 finally
6244 {
6245 parts[0].ParentGroup.areUpdatesSuspended = false;
6246 }
5797 } 6247 }
5798 } 6248 }
5799 6249
@@ -5845,13 +6295,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5845 6295
5846 if (m_host.OwnerID == land.LandData.OwnerID) 6296 if (m_host.OwnerID == land.LandData.OwnerID)
5847 { 6297 {
5848 World.TeleportClientHome(agentID, presence.ControllingClient); 6298 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6299 presence.TeleportWithMomentum(pos, null);
6300 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5849 } 6301 }
5850 } 6302 }
5851 } 6303 }
5852 ScriptSleep(5000); 6304 ScriptSleep(5000);
5853 } 6305 }
5854 6306
6307 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6308 {
6309 return ParseString2List(str, separators, in_spacers, false);
6310 }
6311
5855 public LSL_Integer llOverMyLand(string id) 6312 public LSL_Integer llOverMyLand(string id)
5856 { 6313 {
5857 m_host.AddScriptLPS(1); 6314 m_host.AddScriptLPS(1);
@@ -5916,8 +6373,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5916 UUID agentId = new UUID(); 6373 UUID agentId = new UUID();
5917 if (!UUID.TryParse(agent, out agentId)) 6374 if (!UUID.TryParse(agent, out agentId))
5918 return new LSL_Integer(0); 6375 return new LSL_Integer(0);
6376 if (agentId == m_host.GroupID)
6377 return new LSL_Integer(1);
5919 ScenePresence presence = World.GetScenePresence(agentId); 6378 ScenePresence presence = World.GetScenePresence(agentId);
5920 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6379 if (presence == null || presence.IsChildAgent) // Return false for child agents
5921 return new LSL_Integer(0); 6380 return new LSL_Integer(0);
5922 IClientAPI client = presence.ControllingClient; 6381 IClientAPI client = presence.ControllingClient;
5923 if (m_host.GroupID == client.ActiveGroupId) 6382 if (m_host.GroupID == client.ActiveGroupId)
@@ -6052,7 +6511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6052 return m_host.ParentGroup.AttachmentPoint; 6511 return m_host.ParentGroup.AttachmentPoint;
6053 } 6512 }
6054 6513
6055 public LSL_Integer llGetFreeMemory() 6514 public virtual LSL_Integer llGetFreeMemory()
6056 { 6515 {
6057 m_host.AddScriptLPS(1); 6516 m_host.AddScriptLPS(1);
6058 // Make scripts designed for LSO happy 6517 // Make scripts designed for LSO happy
@@ -6169,7 +6628,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6169 SetParticleSystem(m_host, rules); 6628 SetParticleSystem(m_host, rules);
6170 } 6629 }
6171 6630
6172 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6631 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6632 {
6173 6633
6174 6634
6175 if (rules.Length == 0) 6635 if (rules.Length == 0)
@@ -6397,17 +6857,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6397 if (folderID == UUID.Zero) 6857 if (folderID == UUID.Zero)
6398 return; 6858 return;
6399 6859
6400 byte[] bucket = new byte[17]; 6860 byte[] bucket = new byte[1];
6401 bucket[0] = (byte)AssetType.Folder; 6861 bucket[0] = (byte)AssetType.Folder;
6402 byte[] objBytes = folderID.GetBytes(); 6862 //byte[] objBytes = folderID.GetBytes();
6403 Array.Copy(objBytes, 0, bucket, 1, 16); 6863 //Array.Copy(objBytes, 0, bucket, 1, 16);
6404 6864
6405 GridInstantMessage msg = new GridInstantMessage(World, 6865 GridInstantMessage msg = new GridInstantMessage(World,
6406 m_host.UUID, m_host.Name + ", an object owned by " + 6866 m_host.OwnerID, m_host.Name, destID,
6407 resolveName(m_host.OwnerID) + ",", destID, 6867 (byte)InstantMessageDialog.TaskInventoryOffered,
6408 (byte)InstantMessageDialog.InventoryOffered, 6868 false, category+". "+m_host.Name+" is located at "+
6409 false, category + "\n" + m_host.Name + " is located at " + 6869 World.RegionInfo.RegionName+" "+
6410 World.RegionInfo.RegionName + " " +
6411 m_host.AbsolutePosition.ToString(), 6870 m_host.AbsolutePosition.ToString(),
6412 folderID, true, m_host.AbsolutePosition, 6871 folderID, true, m_host.AbsolutePosition,
6413 bucket); 6872 bucket);
@@ -6487,7 +6946,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6487 { 6946 {
6488 // LSL quaternions can normalize to 0, normal Quaternions can't. 6947 // LSL quaternions can normalize to 0, normal Quaternions can't.
6489 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6948 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6490 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6949 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6491 6950
6492 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6951 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6493 part.SitTargetOrientation = Rot2Quaternion(rot); 6952 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6644,13 +7103,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6644 UUID av = new UUID(); 7103 UUID av = new UUID();
6645 if (!UUID.TryParse(avatar,out av)) 7104 if (!UUID.TryParse(avatar,out av))
6646 { 7105 {
6647 LSLError("First parameter to llDialog needs to be a key"); 7106 //LSLError("First parameter to llDialog needs to be a key");
6648 return; 7107 return;
6649 } 7108 }
6650 if (buttons.Length < 1) 7109 if (buttons.Length < 1)
6651 { 7110 {
6652 LSLError("No less than 1 button can be shown"); 7111 buttons.Add("OK");
6653 return;
6654 } 7112 }
6655 if (buttons.Length > 12) 7113 if (buttons.Length > 12)
6656 { 7114 {
@@ -6667,7 +7125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6667 } 7125 }
6668 if (buttons.Data[i].ToString().Length > 24) 7126 if (buttons.Data[i].ToString().Length > 24)
6669 { 7127 {
6670 LSLError("button label cannot be longer than 24 characters"); 7128 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6671 return; 7129 return;
6672 } 7130 }
6673 buts[i] = buttons.Data[i].ToString(); 7131 buts[i] = buttons.Data[i].ToString();
@@ -6734,9 +7192,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6734 return; 7192 return;
6735 } 7193 }
6736 7194
6737 // the rest of the permission checks are done in RezScript, so check the pin there as well 7195 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6738 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7196 if (dest != null)
7197 {
7198 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7199 {
7200 // the rest of the permission checks are done in RezScript, so check the pin there as well
7201 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6739 7202
7203 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7204 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7205 }
7206 }
6740 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7207 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6741 ScriptSleep(3000); 7208 ScriptSleep(3000);
6742 } 7209 }
@@ -6799,19 +7266,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 public LSL_String llMD5String(string src, int nonce) 7266 public LSL_String llMD5String(string src, int nonce)
6800 { 7267 {
6801 m_host.AddScriptLPS(1); 7268 m_host.AddScriptLPS(1);
6802 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7269 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6803 } 7270 }
6804 7271
6805 public LSL_String llSHA1String(string src) 7272 public LSL_String llSHA1String(string src)
6806 { 7273 {
6807 m_host.AddScriptLPS(1); 7274 m_host.AddScriptLPS(1);
6808 return Util.SHA1Hash(src).ToLower(); 7275 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6809 } 7276 }
6810 7277
6811 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7278 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6812 { 7279 {
6813 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7280 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6814 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7281 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7282 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7283 return shapeBlock;
6815 7284
6816 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7285 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6817 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7286 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6916,6 +7385,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6916 // Prim type box, cylinder and prism. 7385 // 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) 7386 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 { 7387 {
7388 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7389 return;
7390
6919 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7391 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6920 ObjectShapePacket.ObjectDataBlock shapeBlock; 7392 ObjectShapePacket.ObjectDataBlock shapeBlock;
6921 7393
@@ -6969,6 +7441,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6969 // Prim type sphere. 7441 // 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) 7442 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6971 { 7443 {
7444 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7445 return;
7446
6972 ObjectShapePacket.ObjectDataBlock shapeBlock; 7447 ObjectShapePacket.ObjectDataBlock shapeBlock;
6973 7448
6974 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7449 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7010,6 +7485,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7010 // Prim type torus, tube and ring. 7485 // 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) 7486 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 { 7487 {
7488 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7489 return;
7490
7013 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7491 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7014 ObjectShapePacket.ObjectDataBlock shapeBlock; 7492 ObjectShapePacket.ObjectDataBlock shapeBlock;
7015 7493
@@ -7145,6 +7623,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7145 // Prim type sculpt. 7623 // Prim type sculpt.
7146 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7624 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7147 { 7625 {
7626 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7627 return;
7628
7148 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7629 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7149 UUID sculptId; 7630 UUID sculptId;
7150 7631
@@ -7169,7 +7650,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7169 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7650 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7170 { 7651 {
7171 // default 7652 // default
7172 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7653 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7173 } 7654 }
7174 7655
7175 part.Shape.SetSculptProperties((byte)type, sculptId); 7656 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7185,34 +7666,315 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7185 ScriptSleep(200); 7666 ScriptSleep(200);
7186 } 7667 }
7187 7668
7188 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7669 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7189 { 7670 {
7190 m_host.AddScriptLPS(1); 7671 m_host.AddScriptLPS(1);
7191 7672
7192 setLinkPrimParams(linknumber, rules); 7673 setLinkPrimParams(linknumber, rules);
7674 }
7193 7675
7676 private void setLinkPrimParams(int linknumber, LSL_List rules)
7677 {
7678 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7679 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7680 if (parts.Count>0)
7681 {
7682 try
7683 {
7684 parts[0].ParentGroup.areUpdatesSuspended = true;
7685 foreach (SceneObjectPart part in parts)
7686 SetPrimParams(part, rules);
7687 }
7688 finally
7689 {
7690 parts[0].ParentGroup.areUpdatesSuspended = false;
7691 }
7692 }
7693 if (avatars.Count > 0)
7694 {
7695 foreach (ScenePresence avatar in avatars)
7696 SetPrimParams(avatar, rules);
7697 }
7698 }
7699
7700 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7701 float material_density, float material_friction,
7702 float material_restitution, float material_gravity_modifier)
7703 {
7704 ExtraPhysicsData physdata = new ExtraPhysicsData();
7705 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7706 physdata.Density = part.Density;
7707 physdata.Friction = part.Friction;
7708 physdata.Bounce = part.Bounciness;
7709 physdata.GravitationModifier = part.GravityModifier;
7710
7711 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7712 physdata.Density = material_density;
7713 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7714 physdata.Friction = material_friction;
7715 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7716 physdata.Bounce = material_restitution;
7717 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7718 physdata.GravitationModifier = material_gravity_modifier;
7719
7720 part.UpdateExtraPhysics(physdata);
7721 }
7722
7723 public void llSetPhysicsMaterial(int material_bits,
7724 float material_gravity_modifier, float material_restitution,
7725 float material_friction, float material_density)
7726 {
7727 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7728 }
7729
7730 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7731 {
7732 llSetLinkPrimitiveParamsFast(linknumber, rules);
7194 ScriptSleep(200); 7733 ScriptSleep(200);
7195 } 7734 }
7196 7735
7197 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7736 // vector up using libomv (c&p from sop )
7737 // vector up rotated by r
7738 private Vector3 Zrot(Quaternion r)
7198 { 7739 {
7199 m_host.AddScriptLPS(1); 7740 double x, y, z, m;
7200 7741
7201 setLinkPrimParams(linknumber, rules); 7742 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7743 if (Math.Abs(1.0 - m) > 0.000001)
7744 {
7745 m = 1.0 / Math.Sqrt(m);
7746 r.X *= (float)m;
7747 r.Y *= (float)m;
7748 r.Z *= (float)m;
7749 r.W *= (float)m;
7750 }
7751
7752 x = 2 * (r.X * r.Z + r.Y * r.W);
7753 y = 2 * (-r.X * r.W + r.Y * r.Z);
7754 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7755
7756 return new Vector3((float)x, (float)y, (float)z);
7202 } 7757 }
7203 7758
7204 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7759 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7205 { 7760 {
7206 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7761 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7207 7762
7208 foreach (SceneObjectPart part in parts) 7763 int idx = 0;
7209 SetPrimParams(part, rules); 7764 SceneObjectPart sitpart = World.GetSceneObjectPart(av.ParentID); // betting this will be used
7765
7766 bool positionChanged = false;
7767 Vector3 finalPos = Vector3.Zero;
7768
7769 try
7770 {
7771 while (idx < rules.Length)
7772 {
7773 int code = rules.GetLSLIntegerItem(idx++);
7774
7775 int remain = rules.Length - idx;
7776
7777 switch (code)
7778 {
7779 // a avatar is a child
7780 case (int)ScriptBaseClass.PRIM_POSITION:
7781 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7782 {
7783 if (remain < 1)
7784 return;
7785 LSL_Vector v;
7786 v = rules.GetVector3Item(idx++);
7787
7788 if (sitpart == null)
7789 break;
7790
7791 Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z); // requested absolute position
7792
7793 if (sitpart != sitpart.ParentGroup.RootPart)
7794 {
7795 pos -= sitpart.OffsetPosition; // remove sit part offset
7796 Quaternion rot = sitpart.RotationOffset;
7797 pos *= Quaternion.Conjugate(rot); // removed sit part rotation
7798 }
7799 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f * 2.0f);
7800 pos += sitOffset;
7801
7802 finalPos = pos;
7803 positionChanged = true;
7804 }
7805 break;
7806
7807 case (int)ScriptBaseClass.PRIM_ROTATION:
7808 {
7809 if (remain < 1)
7810 return;
7811
7812 if (sitpart == null)
7813 break;
7814
7815 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7816 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested world rotation
7817
7818// need to replicate SL bug
7819 SceneObjectGroup sitgrp = sitpart.ParentGroup;
7820 if (sitgrp != null && sitgrp.RootPart != sitpart)
7821 {
7822 rot = sitgrp.RootPart.RotationOffset * rot;
7823 }
7824
7825 Quaternion srot = sitpart.RotationOffset;
7826 rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation
7827 av.Rotation = rot;
7828// av.SendAvatarDataToAllAgents();
7829 av.SendTerseUpdateToAllClients();
7830 }
7831 break;
7832
7833 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7834 {
7835 if (remain < 1)
7836 return;
7837
7838 if (sitpart == null)
7839 break;
7840
7841 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7842 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested offset rotation
7843 if (sitpart != sitpart.ParentGroup.RootPart)
7844 {
7845 Quaternion srot = sitpart.RotationOffset;
7846 rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation
7847 }
7848 av.Rotation = rot;
7849// av.SendAvatarDataToAllAgents();
7850 av.SendTerseUpdateToAllClients();
7851 }
7852 break;
7853
7854 // parse rest doing nothing but number of parameters error check
7855 case (int)ScriptBaseClass.PRIM_SIZE:
7856 case (int)ScriptBaseClass.PRIM_MATERIAL:
7857 case (int)ScriptBaseClass.PRIM_PHANTOM:
7858 case (int)ScriptBaseClass.PRIM_PHYSICS:
7859 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7860 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7861 case (int)ScriptBaseClass.PRIM_NAME:
7862 case (int)ScriptBaseClass.PRIM_DESC:
7863 if (remain < 1)
7864 return;
7865 idx++;
7866 break;
7867
7868 case (int)ScriptBaseClass.PRIM_GLOW:
7869 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7870 case (int)ScriptBaseClass.PRIM_TEXGEN:
7871 if (remain < 2)
7872 return;
7873 idx += 2;
7874 break;
7875
7876 case (int)ScriptBaseClass.PRIM_TYPE:
7877 if (remain < 3)
7878 return;
7879 code = (int)rules.GetLSLIntegerItem(idx++);
7880 remain = rules.Length - idx;
7881 switch (code)
7882 {
7883 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7884 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7885 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7886 if (remain < 6)
7887 return;
7888 idx += 6;
7889 break;
7890
7891 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7892 if (remain < 5)
7893 return;
7894 idx += 5;
7895 break;
7896
7897 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7898 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7899 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7900 if (remain < 11)
7901 return;
7902 idx += 11;
7903 break;
7904
7905 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7906 if (remain < 2)
7907 return;
7908 idx += 2;
7909 break;
7910 }
7911 break;
7912
7913 case (int)ScriptBaseClass.PRIM_COLOR:
7914 case (int)ScriptBaseClass.PRIM_TEXT:
7915 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7916 case (int)ScriptBaseClass.PRIM_OMEGA:
7917 if (remain < 3)
7918 return;
7919 idx += 3;
7920 break;
7921
7922 case (int)ScriptBaseClass.PRIM_TEXTURE:
7923 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7924 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7925 if (remain < 5)
7926 return;
7927 idx += 5;
7928 break;
7929
7930 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7931 if (remain < 7)
7932 return;
7933
7934 idx += 7;
7935 break;
7936
7937 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7938 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7939 return;
7940
7941 if (positionChanged)
7942 {
7943 positionChanged = false;
7944 av.OffsetPosition = finalPos;
7945// av.SendAvatarDataToAllAgents();
7946 av.SendTerseUpdateToAllClients();
7947 }
7948
7949 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7950 LSL_List new_rules = rules.GetSublist(idx, -1);
7951 setLinkPrimParams((int)new_linknumber, new_rules);
7952 return;
7953 }
7954 }
7955 }
7956
7957 finally
7958 {
7959 if (positionChanged)
7960 {
7961 av.OffsetPosition = finalPos;
7962// av.SendAvatarDataToAllAgents();
7963 av.SendTerseUpdateToAllClients();
7964 positionChanged = false;
7965 }
7966 }
7210 } 7967 }
7211 7968
7212 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7969 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7213 { 7970 {
7971 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7972 return;
7973
7214 int idx = 0; 7974 int idx = 0;
7215 7975
7976 SceneObjectGroup parentgrp = part.ParentGroup;
7977
7216 bool positionChanged = false; 7978 bool positionChanged = false;
7217 LSL_Vector currentPosition = GetPartLocalPos(part); 7979 LSL_Vector currentPosition = GetPartLocalPos(part);
7218 7980
@@ -7235,8 +7997,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7235 return; 7997 return;
7236 7998
7237 v=rules.GetVector3Item(idx++); 7999 v=rules.GetVector3Item(idx++);
7238 positionChanged = true;
7239 currentPosition = GetSetPosTarget(part, v, currentPosition); 8000 currentPosition = GetSetPosTarget(part, v, currentPosition);
8001 positionChanged = true;
7240 8002
7241 break; 8003 break;
7242 case (int)ScriptBaseClass.PRIM_SIZE: 8004 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7252,8 +8014,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7252 return; 8014 return;
7253 8015
7254 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8016 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8017 SceneObjectPart rootPart = parentgrp.RootPart;
7255 // try to let this work as in SL... 8018 // try to let this work as in SL...
7256 if (part.ParentID == 0) 8019 if (rootPart == part)
7257 { 8020 {
7258 // special case: If we are root, rotate complete SOG to new rotation 8021 // special case: If we are root, rotate complete SOG to new rotation
7259 SetRot(part, Rot2Quaternion(q)); 8022 SetRot(part, Rot2Quaternion(q));
@@ -7261,7 +8024,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7261 else 8024 else
7262 { 8025 {
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. 8026 // 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; 8027 // sounds like sl bug that we need to replicate
7265 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8028 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7266 } 8029 }
7267 8030
@@ -7514,7 +8277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7514 return; 8277 return;
7515 8278
7516 string ph = rules.Data[idx++].ToString(); 8279 string ph = rules.Data[idx++].ToString();
7517 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8280 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7518 8281
7519 break; 8282 break;
7520 8283
@@ -7532,12 +8295,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7532 part.ScriptSetPhysicsStatus(physics); 8295 part.ScriptSetPhysicsStatus(physics);
7533 break; 8296 break;
7534 8297
8298 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8299 if (remain < 1)
8300 return;
8301
8302 int shape_type = rules.GetLSLIntegerItem(idx++);
8303
8304 ExtraPhysicsData physdata = new ExtraPhysicsData();
8305 physdata.Density = part.Density;
8306 physdata.Bounce = part.Bounciness;
8307 physdata.GravitationModifier = part.GravityModifier;
8308 physdata.PhysShapeType = (PhysShapeType)shape_type;
8309
8310 part.UpdateExtraPhysics(physdata);
8311
8312 break;
8313
8314 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8315 if (remain < 5)
8316 return;
8317
8318 int material_bits = rules.GetLSLIntegerItem(idx++);
8319 float material_density = (float)rules.GetLSLFloatItem(idx++);
8320 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8321 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8322 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8323
8324 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8325
8326 break;
8327
7535 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8328 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7536 if (remain < 1) 8329 if (remain < 1)
7537 return; 8330 return;
7538 string temp = rules.Data[idx++].ToString(); 8331 string temp = rules.Data[idx++].ToString();
7539 8332
7540 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8333 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7541 8334
7542 break; 8335 break;
7543 8336
@@ -7576,6 +8369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7576 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8369 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7577 if (remain < 1) 8370 if (remain < 1)
7578 return; 8371 return;
8372
7579 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8373 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7580 SetRot(part, Rot2Quaternion(lr)); 8374 SetRot(part, Rot2Quaternion(lr));
7581 break; 8375 break;
@@ -7587,13 +8381,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7587 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8381 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7588 TargetOmega(part, axis, (double)spinrate, (double)gain); 8382 TargetOmega(part, axis, (double)spinrate, (double)gain);
7589 break; 8383 break;
8384
7590 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8385 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. 8386 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; 8387 return;
8388
8389 // do a pending position change before jumping to other part/avatar
8390 if (positionChanged)
8391 {
8392 positionChanged = false;
8393 if (parentgrp == null)
8394 return;
8395
8396 if (parentgrp.RootPart == part)
8397 {
8398
8399 Util.FireAndForget(delegate(object x)
8400 {
8401 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8402 });
8403 }
8404 else
8405 {
8406 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8407 parentgrp.HasGroupChanged = true;
8408 parentgrp.ScheduleGroupForTerseUpdate();
8409 }
8410 }
8411
7593 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8412 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7594 LSL_List new_rules = rules.GetSublist(idx, -1); 8413 LSL_List new_rules = rules.GetSublist(idx, -1);
7595 setLinkPrimParams((int)new_linknumber, new_rules); 8414 setLinkPrimParams((int)new_linknumber, new_rules);
7596
7597 return; 8415 return;
7598 } 8416 }
7599 } 8417 }
@@ -7605,7 +8423,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7605 if (part.ParentGroup.RootPart == part) 8423 if (part.ParentGroup.RootPart == part)
7606 { 8424 {
7607 SceneObjectGroup parent = part.ParentGroup; 8425 SceneObjectGroup parent = part.ParentGroup;
7608 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8426 Util.FireAndForget(delegate(object x) {
8427 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8428 });
7609 } 8429 }
7610 else 8430 else
7611 { 8431 {
@@ -7649,10 +8469,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7649 8469
7650 public LSL_String llXorBase64Strings(string str1, string str2) 8470 public LSL_String llXorBase64Strings(string str1, string str2)
7651 { 8471 {
7652 m_host.AddScriptLPS(1); 8472 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7653 Deprecated("llXorBase64Strings"); 8473
7654 ScriptSleep(300); 8474 ScriptSleep(300);
7655 return String.Empty; 8475 m_host.AddScriptLPS(1);
8476
8477 if (str1 == String.Empty)
8478 return String.Empty;
8479 if (str2 == String.Empty)
8480 return str1;
8481
8482 int len = str2.Length;
8483 if ((len % 4) != 0) // LL is EVIL!!!!
8484 {
8485 while (str2.EndsWith("="))
8486 str2 = str2.Substring(0, str2.Length - 1);
8487
8488 len = str2.Length;
8489 int mod = len % 4;
8490
8491 if (mod == 1)
8492 str2 = str2.Substring(0, str2.Length - 1);
8493 else if (mod == 2)
8494 str2 += "==";
8495 else if (mod == 3)
8496 str2 += "=";
8497 }
8498
8499 byte[] data1;
8500 byte[] data2;
8501 try
8502 {
8503 data1 = Convert.FromBase64String(str1);
8504 data2 = Convert.FromBase64String(str2);
8505 }
8506 catch (Exception)
8507 {
8508 return new LSL_String(String.Empty);
8509 }
8510
8511 // For cases where the decoded length of s2 is greater
8512 // than the decoded length of s1, simply perform a normal
8513 // decode and XOR
8514 //
8515 if (data2.Length >= data1.Length)
8516 {
8517 for (int pos = 0 ; pos < data1.Length ; pos++ )
8518 data1[pos] ^= data2[pos];
8519
8520 return Convert.ToBase64String(data1);
8521 }
8522
8523 // Remove padding
8524 while (str1.EndsWith("="))
8525 str1 = str1.Substring(0, str1.Length - 1);
8526 while (str2.EndsWith("="))
8527 str2 = str2.Substring(0, str2.Length - 1);
8528
8529 byte[] d1 = new byte[str1.Length];
8530 byte[] d2 = new byte[str2.Length];
8531
8532 for (int i = 0 ; i < str1.Length ; i++)
8533 {
8534 int idx = b64.IndexOf(str1.Substring(i, 1));
8535 if (idx == -1)
8536 idx = 0;
8537 d1[i] = (byte)idx;
8538 }
8539
8540 for (int i = 0 ; i < str2.Length ; i++)
8541 {
8542 int idx = b64.IndexOf(str2.Substring(i, 1));
8543 if (idx == -1)
8544 idx = 0;
8545 d2[i] = (byte)idx;
8546 }
8547
8548 string output = String.Empty;
8549
8550 for (int pos = 0 ; pos < d1.Length ; pos++)
8551 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8552
8553 while (output.Length % 3 > 0)
8554 output += "=";
8555
8556 return output;
7656 } 8557 }
7657 8558
7658 public void llRemoteDataSetRegion() 8559 public void llRemoteDataSetRegion()
@@ -7776,13 +8677,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 public LSL_Integer llGetNumberOfPrims() 8677 public LSL_Integer llGetNumberOfPrims()
7777 { 8678 {
7778 m_host.AddScriptLPS(1); 8679 m_host.AddScriptLPS(1);
7779 int avatarCount = 0; 8680 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7780 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8681
7781 {
7782 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7783 avatarCount++;
7784 });
7785
7786 return m_host.ParentGroup.PrimCount + avatarCount; 8682 return m_host.ParentGroup.PrimCount + avatarCount;
7787 } 8683 }
7788 8684
@@ -7798,55 +8694,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7798 m_host.AddScriptLPS(1); 8694 m_host.AddScriptLPS(1);
7799 UUID objID = UUID.Zero; 8695 UUID objID = UUID.Zero;
7800 LSL_List result = new LSL_List(); 8696 LSL_List result = new LSL_List();
8697
8698 // If the ID is not valid, return null result
7801 if (!UUID.TryParse(obj, out objID)) 8699 if (!UUID.TryParse(obj, out objID))
7802 { 8700 {
7803 result.Add(new LSL_Vector()); 8701 result.Add(new LSL_Vector());
7804 result.Add(new LSL_Vector()); 8702 result.Add(new LSL_Vector());
7805 return result; 8703 return result;
7806 } 8704 }
8705
8706 // Check if this is an attached prim. If so, replace
8707 // the UUID with the avatar UUID and report it's bounding box
8708 SceneObjectPart part = World.GetSceneObjectPart(objID);
8709 if (part != null && part.ParentGroup.IsAttachment)
8710 objID = part.ParentGroup.AttachedAvatar;
8711
8712 // Find out if this is an avatar ID. If so, return it's box
7807 ScenePresence presence = World.GetScenePresence(objID); 8713 ScenePresence presence = World.GetScenePresence(objID);
7808 if (presence != null) 8714 if (presence != null)
7809 { 8715 {
7810 if (presence.ParentID == 0) // not sat on an object 8716 // As per LSL Wiki, there is no difference between sitting
8717 // and standing avatar since server 1.36
8718 LSL_Vector lower;
8719 LSL_Vector upper;
8720 if (presence.Animator.Animations.DefaultAnimation.AnimID
8721 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7811 { 8722 {
7812 LSL_Vector lower; 8723 // This is for ground sitting avatars
7813 LSL_Vector upper; 8724 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7814 if (presence.Animator.Animations.DefaultAnimation.AnimID 8725 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7815 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8726 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 } 8727 }
7833 else 8728 else
7834 { 8729 {
7835 // sitting on an object so we need the bounding box of that 8730 // This is for standing/flying avatars
7836 // which should include the avatar so set the UUID to the 8731 float height = presence.Appearance.AvatarHeight / 2.0f;
7837 // UUID of the object the avatar is sat on and allow it to fall through 8732 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7838 // to processing an object 8733 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7839 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7840 objID = p.UUID;
7841 } 8734 }
8735
8736 // Adjust to the documented error offsets (see LSL Wiki)
8737 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8738 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8739
8740 if (lower.x > upper.x)
8741 lower.x = upper.x;
8742 if (lower.y > upper.y)
8743 lower.y = upper.y;
8744 if (lower.z > upper.z)
8745 lower.z = upper.z;
8746
8747 result.Add(lower);
8748 result.Add(upper);
8749 return result;
7842 } 8750 }
7843 SceneObjectPart part = World.GetSceneObjectPart(objID); 8751
8752 part = World.GetSceneObjectPart(objID);
7844 // Currently only works for single prims without a sitting avatar 8753 // Currently only works for single prims without a sitting avatar
7845 if (part != null) 8754 if (part != null)
7846 { 8755 {
7847 Vector3 halfSize = part.Scale / 2.0f; 8756 float minX;
7848 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8757 float maxX;
7849 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8758 float minY;
8759 float maxY;
8760 float minZ;
8761 float maxZ;
8762
8763 // This BBox is in sim coordinates, with the offset being
8764 // a contained point.
8765 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8766 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8767
8768 minX -= offsets[0].X;
8769 maxX -= offsets[0].X;
8770 minY -= offsets[0].Y;
8771 maxY -= offsets[0].Y;
8772 minZ -= offsets[0].Z;
8773 maxZ -= offsets[0].Z;
8774
8775 LSL_Vector lower;
8776 LSL_Vector upper;
8777
8778 // Adjust to the documented error offsets (see LSL Wiki)
8779 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8780 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8781
8782 if (lower.x > upper.x)
8783 lower.x = upper.x;
8784 if (lower.y > upper.y)
8785 lower.y = upper.y;
8786 if (lower.z > upper.z)
8787 lower.z = upper.z;
8788
7850 result.Add(lower); 8789 result.Add(lower);
7851 result.Add(upper); 8790 result.Add(upper);
7852 return result; 8791 return result;
@@ -7860,7 +8799,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7860 8799
7861 public LSL_Vector llGetGeometricCenter() 8800 public LSL_Vector llGetGeometricCenter()
7862 { 8801 {
7863 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8802 Vector3 tmp = m_host.GetGeometricCenter();
8803 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7864 } 8804 }
7865 8805
7866 public LSL_List llGetPrimitiveParams(LSL_List rules) 8806 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7873,16 +8813,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7873 { 8813 {
7874 m_host.AddScriptLPS(1); 8814 m_host.AddScriptLPS(1);
7875 8815
8816 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8817 // keep other options as before
8818
7876 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8819 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8820 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7877 8821
7878 LSL_List res = new LSL_List(); 8822 LSL_List res = new LSL_List();
7879 8823
7880 foreach (var part in parts) 8824 if (parts.Count > 0)
8825 {
8826 foreach (var part in parts)
8827 {
8828 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8829 res += partRes;
8830 }
8831 }
8832 if (avatars.Count > 0)
7881 { 8833 {
7882 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8834 foreach (ScenePresence avatar in avatars)
7883 res += partRes; 8835 {
8836 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8837 res += avaRes;
8838 }
7884 } 8839 }
8840 return res;
8841 }
8842
8843 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8844 {
8845 // avatars case
8846 // replies as SL wiki
8847
8848 LSL_List res = new LSL_List();
8849// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8850 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
7885 8851
8852 int idx = 0;
8853 while (idx < rules.Length)
8854 {
8855 int code = (int)rules.GetLSLIntegerItem(idx++);
8856 int remain = rules.Length - idx;
8857
8858 switch (code)
8859 {
8860 case (int)ScriptBaseClass.PRIM_MATERIAL:
8861 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8862 break;
8863
8864 case (int)ScriptBaseClass.PRIM_PHYSICS:
8865 res.Add(new LSL_Integer(0));
8866 break;
8867
8868 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8869 res.Add(new LSL_Integer(0));
8870 break;
8871
8872 case (int)ScriptBaseClass.PRIM_PHANTOM:
8873 res.Add(new LSL_Integer(0));
8874 break;
8875
8876 case (int)ScriptBaseClass.PRIM_POSITION:
8877
8878 Vector3 pos = avatar.OffsetPosition;
8879
8880 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8881 pos -= sitOffset;
8882
8883 if( sitPart != null)
8884 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8885
8886 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8887 break;
8888
8889 case (int)ScriptBaseClass.PRIM_SIZE:
8890 // as in llGetAgentSize above
8891 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8892 break;
8893
8894 case (int)ScriptBaseClass.PRIM_ROTATION:
8895 Quaternion rot = avatar.Rotation;
8896 if (sitPart != null)
8897 {
8898 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8899 }
8900
8901 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8902 break;
8903
8904 case (int)ScriptBaseClass.PRIM_TYPE:
8905 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8906 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8907 res.Add(new LSL_Vector(0f,1.0f,0f));
8908 res.Add(new LSL_Float(0.0f));
8909 res.Add(new LSL_Vector(0, 0, 0));
8910 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8911 res.Add(new LSL_Vector(0, 0, 0));
8912 break;
8913
8914 case (int)ScriptBaseClass.PRIM_TEXTURE:
8915 if (remain < 1)
8916 return res;
8917
8918 int face = (int)rules.GetLSLIntegerItem(idx++);
8919 if (face == ScriptBaseClass.ALL_SIDES)
8920 {
8921 for (face = 0; face < 21; face++)
8922 {
8923 res.Add(new LSL_String(""));
8924 res.Add(new LSL_Vector(0,0,0));
8925 res.Add(new LSL_Vector(0,0,0));
8926 res.Add(new LSL_Float(0.0));
8927 }
8928 }
8929 else
8930 {
8931 if (face >= 0 && face < 21)
8932 {
8933 res.Add(new LSL_String(""));
8934 res.Add(new LSL_Vector(0,0,0));
8935 res.Add(new LSL_Vector(0,0,0));
8936 res.Add(new LSL_Float(0.0));
8937 }
8938 }
8939 break;
8940
8941 case (int)ScriptBaseClass.PRIM_COLOR:
8942 if (remain < 1)
8943 return res;
8944
8945 face = (int)rules.GetLSLIntegerItem(idx++);
8946
8947 if (face == ScriptBaseClass.ALL_SIDES)
8948 {
8949 for (face = 0; face < 21; face++)
8950 {
8951 res.Add(new LSL_Vector(0,0,0));
8952 res.Add(new LSL_Float(0));
8953 }
8954 }
8955 else
8956 {
8957 res.Add(new LSL_Vector(0,0,0));
8958 res.Add(new LSL_Float(0));
8959 }
8960 break;
8961
8962 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8963 if (remain < 1)
8964 return res;
8965 face = (int)rules.GetLSLIntegerItem(idx++);
8966
8967 if (face == ScriptBaseClass.ALL_SIDES)
8968 {
8969 for (face = 0; face < 21; face++)
8970 {
8971 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8972 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8973 }
8974 }
8975 else
8976 {
8977 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8979 }
8980 break;
8981
8982 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8983 if (remain < 1)
8984 return res;
8985 face = (int)rules.GetLSLIntegerItem(idx++);
8986
8987 if (face == ScriptBaseClass.ALL_SIDES)
8988 {
8989 for (face = 0; face < 21; face++)
8990 {
8991 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8992 }
8993 }
8994 else
8995 {
8996 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8997 }
8998 break;
8999
9000 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9001 res.Add(new LSL_Integer(0));
9002 res.Add(new LSL_Integer(0));// softness
9003 res.Add(new LSL_Float(0.0f)); // gravity
9004 res.Add(new LSL_Float(0.0f)); // friction
9005 res.Add(new LSL_Float(0.0f)); // wind
9006 res.Add(new LSL_Float(0.0f)); // tension
9007 res.Add(new LSL_Vector(0f,0f,0f));
9008 break;
9009
9010 case (int)ScriptBaseClass.PRIM_TEXGEN:
9011 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9012 if (remain < 1)
9013 return res;
9014 face = (int)rules.GetLSLIntegerItem(idx++);
9015
9016 if (face == ScriptBaseClass.ALL_SIDES)
9017 {
9018 for (face = 0; face < 21; face++)
9019 {
9020 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9021 }
9022 }
9023 else
9024 {
9025 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9026 }
9027 break;
9028
9029 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9030 res.Add(new LSL_Integer(0));
9031 res.Add(new LSL_Vector(0f,0f,0f));
9032 res.Add(new LSL_Float(0f)); // intensity
9033 res.Add(new LSL_Float(0f)); // radius
9034 res.Add(new LSL_Float(0f)); // falloff
9035 break;
9036
9037 case (int)ScriptBaseClass.PRIM_GLOW:
9038 if (remain < 1)
9039 return res;
9040 face = (int)rules.GetLSLIntegerItem(idx++);
9041
9042 if (face == ScriptBaseClass.ALL_SIDES)
9043 {
9044 for (face = 0; face < 21; face++)
9045 {
9046 res.Add(new LSL_Float(0f));
9047 }
9048 }
9049 else
9050 {
9051 res.Add(new LSL_Float(0f));
9052 }
9053 break;
9054
9055 case (int)ScriptBaseClass.PRIM_TEXT:
9056 res.Add(new LSL_String(""));
9057 res.Add(new LSL_Vector(0f,0f,0f));
9058 res.Add(new LSL_Float(1.0f));
9059 break;
9060
9061 case (int)ScriptBaseClass.PRIM_NAME:
9062 res.Add(new LSL_String(avatar.Name));
9063 break;
9064
9065 case (int)ScriptBaseClass.PRIM_DESC:
9066 res.Add(new LSL_String(""));
9067 break;
9068
9069 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9070 Quaternion lrot = avatar.Rotation;
9071
9072 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9073 {
9074 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9075 }
9076 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9077 break;
9078
9079 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9080 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9081 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9082 lpos -= lsitOffset;
9083
9084 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9085 {
9086 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9087 }
9088 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9089 break;
9090
9091 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9092 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9093 return res;
9094 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9095 LSL_List new_rules = rules.GetSublist(idx, -1);
9096
9097 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9098 return res;
9099 }
9100 }
7886 return res; 9101 return res;
7887 } 9102 }
7888 9103
@@ -7926,13 +9141,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7926 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9141 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7927 part.AbsolutePosition.Y, 9142 part.AbsolutePosition.Y,
7928 part.AbsolutePosition.Z); 9143 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); 9144 res.Add(v);
7937 break; 9145 break;
7938 9146
@@ -8103,56 +9311,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8103 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9311 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8104 if (remain < 1) 9312 if (remain < 1)
8105 return res; 9313 return res;
8106 9314 face = (int)rules.GetLSLIntegerItem(idx++);
8107 face=(int)rules.GetLSLIntegerItem(idx++);
8108 9315
8109 tex = part.Shape.Textures; 9316 tex = part.Shape.Textures;
9317 int shiny;
8110 if (face == ScriptBaseClass.ALL_SIDES) 9318 if (face == ScriptBaseClass.ALL_SIDES)
8111 { 9319 {
8112 for (face = 0; face < GetNumberOfSides(part); face++) 9320 for (face = 0; face < GetNumberOfSides(part); face++)
8113 { 9321 {
8114 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9322 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8115 // Convert Shininess to PRIM_SHINY_* 9323 if (shinyness == Shininess.High)
8116 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9324 {
8117 // PRIM_BUMP_* 9325 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8118 res.Add(new LSL_Integer((int)texface.Bump)); 9326 }
9327 else if (shinyness == Shininess.Medium)
9328 {
9329 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9330 }
9331 else if (shinyness == Shininess.Low)
9332 {
9333 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9334 }
9335 else
9336 {
9337 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9338 }
9339 res.Add(new LSL_Integer(shiny));
9340 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8119 } 9341 }
8120 } 9342 }
8121 else 9343 else
8122 { 9344 {
8123 if (face >= 0 && face < GetNumberOfSides(part)) 9345 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9346 if (shinyness == Shininess.High)
8124 { 9347 {
8125 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9348 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8126 // Convert Shininess to PRIM_SHINY_* 9349 }
8127 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9350 else if (shinyness == Shininess.Medium)
8128 // PRIM_BUMP_* 9351 {
8129 res.Add(new LSL_Integer((int)texface.Bump)); 9352 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9353 }
9354 else if (shinyness == Shininess.Low)
9355 {
9356 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8130 } 9357 }
9358 else
9359 {
9360 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9361 }
9362 res.Add(new LSL_Integer(shiny));
9363 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8131 } 9364 }
8132 break; 9365 break;
8133 9366
8134 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9367 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8135 if (remain < 1) 9368 if (remain < 1)
8136 return res; 9369 return res;
8137 9370 face = (int)rules.GetLSLIntegerItem(idx++);
8138 face=(int)rules.GetLSLIntegerItem(idx++);
8139 9371
8140 tex = part.Shape.Textures; 9372 tex = part.Shape.Textures;
9373 int fullbright;
8141 if (face == ScriptBaseClass.ALL_SIDES) 9374 if (face == ScriptBaseClass.ALL_SIDES)
8142 { 9375 {
8143 for (face = 0; face < GetNumberOfSides(part); face++) 9376 for (face = 0; face < GetNumberOfSides(part); face++)
8144 { 9377 {
8145 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9378 if (tex.GetFace((uint)face).Fullbright == true)
8146 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9379 {
9380 fullbright = ScriptBaseClass.TRUE;
9381 }
9382 else
9383 {
9384 fullbright = ScriptBaseClass.FALSE;
9385 }
9386 res.Add(new LSL_Integer(fullbright));
8147 } 9387 }
8148 } 9388 }
8149 else 9389 else
8150 { 9390 {
8151 if (face >= 0 && face < GetNumberOfSides(part)) 9391 if (tex.GetFace((uint)face).Fullbright == true)
8152 { 9392 {
8153 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9393 fullbright = ScriptBaseClass.TRUE;
8154 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9394 }
9395 else
9396 {
9397 fullbright = ScriptBaseClass.FALSE;
8155 } 9398 }
9399 res.Add(new LSL_Integer(fullbright));
8156 } 9400 }
8157 break; 9401 break;
8158 9402
@@ -8174,27 +9418,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8174 break; 9418 break;
8175 9419
8176 case (int)ScriptBaseClass.PRIM_TEXGEN: 9420 case (int)ScriptBaseClass.PRIM_TEXGEN:
9421 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8177 if (remain < 1) 9422 if (remain < 1)
8178 return res; 9423 return res;
8179 9424 face = (int)rules.GetLSLIntegerItem(idx++);
8180 face=(int)rules.GetLSLIntegerItem(idx++);
8181 9425
8182 tex = part.Shape.Textures; 9426 tex = part.Shape.Textures;
8183 if (face == ScriptBaseClass.ALL_SIDES) 9427 if (face == ScriptBaseClass.ALL_SIDES)
8184 { 9428 {
8185 for (face = 0; face < GetNumberOfSides(part); face++) 9429 for (face = 0; face < GetNumberOfSides(part); face++)
8186 { 9430 {
8187 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9431 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8188 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9432 {
8189 res.Add(new LSL_Integer((uint)texgen >> 1)); 9433 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9434 }
9435 else
9436 {
9437 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9438 }
8190 } 9439 }
8191 } 9440 }
8192 else 9441 else
8193 { 9442 {
8194 if (face >= 0 && face < GetNumberOfSides(part)) 9443 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9444 {
9445 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9446 }
9447 else
8195 { 9448 {
8196 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9449 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8197 res.Add(new LSL_Integer((uint)texgen >> 1));
8198 } 9450 }
8199 } 9451 }
8200 break; 9452 break;
@@ -8217,25 +9469,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 case (int)ScriptBaseClass.PRIM_GLOW: 9469 case (int)ScriptBaseClass.PRIM_GLOW:
8218 if (remain < 1) 9470 if (remain < 1)
8219 return res; 9471 return res;
8220 9472 face = (int)rules.GetLSLIntegerItem(idx++);
8221 face=(int)rules.GetLSLIntegerItem(idx++);
8222 9473
8223 tex = part.Shape.Textures; 9474 tex = part.Shape.Textures;
9475 float primglow;
8224 if (face == ScriptBaseClass.ALL_SIDES) 9476 if (face == ScriptBaseClass.ALL_SIDES)
8225 { 9477 {
8226 for (face = 0; face < GetNumberOfSides(part); face++) 9478 for (face = 0; face < GetNumberOfSides(part); face++)
8227 { 9479 {
8228 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9480 primglow = tex.GetFace((uint)face).Glow;
8229 res.Add(new LSL_Float(texface.Glow)); 9481 res.Add(new LSL_Float(primglow));
8230 } 9482 }
8231 } 9483 }
8232 else 9484 else
8233 { 9485 {
8234 if (face >= 0 && face < GetNumberOfSides(part)) 9486 primglow = tex.GetFace((uint)face).Glow;
8235 { 9487 res.Add(new LSL_Float(primglow));
8236 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8237 res.Add(new LSL_Float(texface.Glow));
8238 }
8239 } 9488 }
8240 break; 9489 break;
8241 9490
@@ -8247,18 +9496,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8247 textColor.B)); 9496 textColor.B));
8248 res.Add(new LSL_Float(textColor.A)); 9497 res.Add(new LSL_Float(textColor.A));
8249 break; 9498 break;
9499
8250 case (int)ScriptBaseClass.PRIM_NAME: 9500 case (int)ScriptBaseClass.PRIM_NAME:
8251 res.Add(new LSL_String(part.Name)); 9501 res.Add(new LSL_String(part.Name));
8252 break; 9502 break;
9503
8253 case (int)ScriptBaseClass.PRIM_DESC: 9504 case (int)ScriptBaseClass.PRIM_DESC:
8254 res.Add(new LSL_String(part.Description)); 9505 res.Add(new LSL_String(part.Description));
8255 break; 9506 break;
9507
8256 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9508 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8257 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9509 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8258 break; 9510 break;
9511
8259 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9512 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8260 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9513 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8261 break; 9514 break;
9515
9516 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9517 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9518 return res;
9519 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9520 LSL_List new_rules = rules.GetSublist(idx, -1);
9521 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9522 res += tres;
9523 return res;
8262 } 9524 }
8263 } 9525 }
8264 return res; 9526 return res;
@@ -8851,8 +10113,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8851 // The function returns an ordered list 10113 // The function returns an ordered list
8852 // representing the tokens found in the supplied 10114 // representing the tokens found in the supplied
8853 // sources string. If two successive tokenizers 10115 // sources string. If two successive tokenizers
8854 // are encountered, then a NULL entry is added 10116 // are encountered, then a null-string entry is
8855 // to the list. 10117 // added to the list.
8856 // 10118 //
8857 // It is a precondition that the source and 10119 // It is a precondition that the source and
8858 // toekizer lisst are non-null. If they are null, 10120 // toekizer lisst are non-null. If they are null,
@@ -8860,7 +10122,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8860 // while their lengths are being determined. 10122 // while their lengths are being determined.
8861 // 10123 //
8862 // A small amount of working memoryis required 10124 // A small amount of working memoryis required
8863 // of approximately 8*#tokenizers. 10125 // of approximately 8*#tokenizers + 8*srcstrlen.
8864 // 10126 //
8865 // There are many ways in which this function 10127 // There are many ways in which this function
8866 // can be implemented, this implementation is 10128 // can be implemented, this implementation is
@@ -8876,155 +10138,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8876 // and eliminates redundant tokenizers as soon 10138 // and eliminates redundant tokenizers as soon
8877 // as is possible. 10139 // as is possible.
8878 // 10140 //
8879 // The implementation tries to avoid any copying 10141 // The implementation tries to minimize temporary
8880 // of arrays or other objects. 10142 // garbage generation.
8881 // </remarks> 10143 // </remarks>
8882 10144
8883 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10145 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8884 { 10146 {
8885 int beginning = 0; 10147 return ParseString2List(src, separators, spacers, true);
8886 int srclen = src.Length; 10148 }
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 10149
8901 LSL_List tokens = new LSL_List(); 10150 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10151 {
10152 int srclen = src.Length;
10153 int seplen = separators.Length;
10154 object[] separray = separators.Data;
10155 int spclen = spacers.Length;
10156 object[] spcarray = spacers.Data;
10157 int dellen = 0;
10158 string[] delarray = new string[seplen+spclen];
8902 10159
8903 // All entries are initially valid 10160 int outlen = 0;
10161 string[] outarray = new string[srclen*2+1];
8904 10162
8905 for (int i = 0; i < mlen; i++) 10163 int i, j;
8906 active[i] = true; 10164 string d;
8907 10165
8908 offset[mlen] = srclen; 10166 m_host.AddScriptLPS(1);
8909 10167
8910 while (beginning < srclen) 10168 /*
10169 * Convert separator and spacer lists to C# strings.
10170 * Also filter out null strings so we don't hang.
10171 */
10172 for (i = 0; i < seplen; i ++)
8911 { 10173 {
10174 d = separray[i].ToString();
10175 if (d.Length > 0)
10176 {
10177 delarray[dellen++] = d;
10178 }
10179 }
10180 seplen = dellen;
8912 10181
8913 best = mlen; // as bad as it gets 10182 for (i = 0; i < spclen; i ++)
10183 {
10184 d = spcarray[i].ToString();
10185 if (d.Length > 0)
10186 {
10187 delarray[dellen++] = d;
10188 }
10189 }
8914 10190
8915 // Scan for separators 10191 /*
10192 * Scan through source string from beginning to end.
10193 */
10194 for (i = 0;;)
10195 {
8916 10196
8917 for (j = 0; j < seplen; j++) 10197 /*
10198 * Find earliest delimeter in src starting at i (if any).
10199 */
10200 int earliestDel = -1;
10201 int earliestSrc = srclen;
10202 string earliestStr = null;
10203 for (j = 0; j < dellen; j ++)
8918 { 10204 {
8919 if (separray[j].ToString() == String.Empty) 10205 d = delarray[j];
8920 active[j] = false; 10206 if (d != null)
8921
8922 if (active[j])
8923 { 10207 {
8924 // scan all of the markers 10208 int index = src.IndexOf(d, i);
8925 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10209 if (index < 0)
8926 { 10210 {
8927 // not present at all 10211 delarray[j] = null; // delim nowhere in src, don't check it anymore
8928 active[j] = false;
8929 } 10212 }
8930 else 10213 else if (index < earliestSrc)
8931 { 10214 {
8932 // present and correct 10215 earliestSrc = index; // where delimeter starts in source string
8933 if (offset[j] < offset[best]) 10216 earliestDel = j; // where delimeter is in delarray[]
8934 { 10217 earliestStr = d; // the delimeter string from delarray[]
8935 // closest so far 10218 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 } 10219 }
8941 } 10220 }
8942 } 10221 }
8943 10222
8944 // Scan for spacers 10223 /*
8945 10224 * Output source string starting at i through start of earliest delimeter.
8946 if (offset[best] != beginning) 10225 */
10226 if (keepNulls || (earliestSrc > i))
8947 { 10227 {
8948 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10228 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 } 10229 }
8973 10230
8974 // This is the normal exit from the scanning loop 10231 /*
10232 * If no delimeter found at or after i, we're done scanning.
10233 */
10234 if (earliestDel < 0) break;
8975 10235
8976 if (best == mlen) 10236 /*
10237 * If delimeter was a spacer, output the spacer.
10238 */
10239 if (earliestDel >= seplen)
8977 { 10240 {
8978 // no markers were found on this pass 10241 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 } 10242 }
8984 10243
8985 // Otherwise we just add the newly delimited token 10244 /*
8986 // and recalculate where the search should continue. 10245 * Look at rest of src string following delimeter.
8987 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10246 */
8988 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10247 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 } 10248 }
9002 10249
9003 // This an awkward an not very intuitive boundary case. If the 10250 /*
9004 // last substring is a tokenizer, then there is an implied trailing 10251 * 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 10252 */
9006 // arduous. Alternatively the 'break' could be replced with a return 10253 object[] outlist = new object[outlen];
9007 // but that's shabby programming. 10254 for (i = 0; i < outlen; i ++)
9008
9009 if ((beginning == srclen) && (keepNulls))
9010 { 10255 {
9011 if (srclen != 0) 10256 outlist[i] = new LSL_String(outarray[i]);
9012 tokens.Add(new LSL_String(""));
9013 } 10257 }
9014 10258 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 } 10259 }
9029 10260
9030 public LSL_Integer llGetObjectPermMask(int mask) 10261 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9119,6 +10350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9119 case 4: 10350 case 4:
9120 return (int)item.NextPermissions; 10351 return (int)item.NextPermissions;
9121 } 10352 }
10353 m_host.TaskInventory.LockItemsForRead(false);
9122 10354
9123 return -1; 10355 return -1;
9124 } 10356 }
@@ -9309,9 +10541,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9309 { 10541 {
9310 try 10542 try
9311 { 10543 {
10544 /*
9312 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10545 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9313 if (obj != null) 10546 if (obj != null)
9314 return (double)obj.GetMass(); 10547 return (double)obj.GetMass();
10548 */
10549 // return total object mass
10550 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10551 if (obj != null)
10552 return obj.GetMass();
10553
9315 // the object is null so the key is for an avatar 10554 // the object is null so the key is for an avatar
9316 ScenePresence avatar = World.GetScenePresence(key); 10555 ScenePresence avatar = World.GetScenePresence(key);
9317 if (avatar != null) 10556 if (avatar != null)
@@ -9331,7 +10570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9331 } 10570 }
9332 10571
9333 /// <summary> 10572 /// <summary>
9334 /// illListReplaceList removes the sub-list defined by the inclusive indices 10573 /// llListReplaceList removes the sub-list defined by the inclusive indices
9335 /// start and end and inserts the src list in its place. The inclusive 10574 /// 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 10575 /// 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 10576 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9388,16 +10627,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9388 // based upon end. Note that if end exceeds the upper 10627 // based upon end. Note that if end exceeds the upper
9389 // bound in this case, the entire destination list 10628 // bound in this case, the entire destination list
9390 // is removed. 10629 // is removed.
9391 else 10630 else if (start == 0)
9392 { 10631 {
9393 if (end + 1 < dest.Length) 10632 if (end + 1 < dest.Length)
9394 {
9395 return src + dest.GetSublist(end + 1, -1); 10633 return src + dest.GetSublist(end + 1, -1);
9396 }
9397 else 10634 else
9398 {
9399 return src; 10635 return src;
9400 } 10636 }
10637 else // Start < 0
10638 {
10639 if (end + 1 < dest.Length)
10640 return dest.GetSublist(end + 1, -1);
10641 else
10642 return new LSL_List();
9401 } 10643 }
9402 } 10644 }
9403 // Finally, if start > end, we strip away a prefix and 10645 // Finally, if start > end, we strip away a prefix and
@@ -9448,17 +10690,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9448 int width = 0; 10690 int width = 0;
9449 int height = 0; 10691 int height = 0;
9450 10692
9451 ParcelMediaCommandEnum? commandToSend = null; 10693 uint commandToSend = 0;
9452 float time = 0.0f; // default is from start 10694 float time = 0.0f; // default is from start
9453 10695
9454 ScenePresence presence = null; 10696 ScenePresence presence = null;
9455 10697
9456 for (int i = 0; i < commandList.Data.Length; i++) 10698 for (int i = 0; i < commandList.Data.Length; i++)
9457 { 10699 {
9458 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10700 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9459 switch (command) 10701 switch (command)
9460 { 10702 {
9461 case ParcelMediaCommandEnum.Agent: 10703 case (uint)ParcelMediaCommandEnum.Agent:
9462 // we send only to one agent 10704 // we send only to one agent
9463 if ((i + 1) < commandList.Length) 10705 if ((i + 1) < commandList.Length)
9464 { 10706 {
@@ -9475,25 +10717,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9475 } 10717 }
9476 break; 10718 break;
9477 10719
9478 case ParcelMediaCommandEnum.Loop: 10720 case (uint)ParcelMediaCommandEnum.Loop:
9479 loop = 1; 10721 loop = 1;
9480 commandToSend = command; 10722 commandToSend = command;
9481 update = true; //need to send the media update packet to set looping 10723 update = true; //need to send the media update packet to set looping
9482 break; 10724 break;
9483 10725
9484 case ParcelMediaCommandEnum.Play: 10726 case (uint)ParcelMediaCommandEnum.Play:
9485 loop = 0; 10727 loop = 0;
9486 commandToSend = command; 10728 commandToSend = command;
9487 update = true; //need to send the media update packet to make sure it doesn't loop 10729 update = true; //need to send the media update packet to make sure it doesn't loop
9488 break; 10730 break;
9489 10731
9490 case ParcelMediaCommandEnum.Pause: 10732 case (uint)ParcelMediaCommandEnum.Pause:
9491 case ParcelMediaCommandEnum.Stop: 10733 case (uint)ParcelMediaCommandEnum.Stop:
9492 case ParcelMediaCommandEnum.Unload: 10734 case (uint)ParcelMediaCommandEnum.Unload:
9493 commandToSend = command; 10735 commandToSend = command;
9494 break; 10736 break;
9495 10737
9496 case ParcelMediaCommandEnum.Url: 10738 case (uint)ParcelMediaCommandEnum.Url:
9497 if ((i + 1) < commandList.Length) 10739 if ((i + 1) < commandList.Length)
9498 { 10740 {
9499 if (commandList.Data[i + 1] is LSL_String) 10741 if (commandList.Data[i + 1] is LSL_String)
@@ -9506,7 +10748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 } 10748 }
9507 break; 10749 break;
9508 10750
9509 case ParcelMediaCommandEnum.Texture: 10751 case (uint)ParcelMediaCommandEnum.Texture:
9510 if ((i + 1) < commandList.Length) 10752 if ((i + 1) < commandList.Length)
9511 { 10753 {
9512 if (commandList.Data[i + 1] is LSL_String) 10754 if (commandList.Data[i + 1] is LSL_String)
@@ -9519,7 +10761,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9519 } 10761 }
9520 break; 10762 break;
9521 10763
9522 case ParcelMediaCommandEnum.Time: 10764 case (uint)ParcelMediaCommandEnum.Time:
9523 if ((i + 1) < commandList.Length) 10765 if ((i + 1) < commandList.Length)
9524 { 10766 {
9525 if (commandList.Data[i + 1] is LSL_Float) 10767 if (commandList.Data[i + 1] is LSL_Float)
@@ -9531,7 +10773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9531 } 10773 }
9532 break; 10774 break;
9533 10775
9534 case ParcelMediaCommandEnum.AutoAlign: 10776 case (uint)ParcelMediaCommandEnum.AutoAlign:
9535 if ((i + 1) < commandList.Length) 10777 if ((i + 1) < commandList.Length)
9536 { 10778 {
9537 if (commandList.Data[i + 1] is LSL_Integer) 10779 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9545,7 +10787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9545 } 10787 }
9546 break; 10788 break;
9547 10789
9548 case ParcelMediaCommandEnum.Type: 10790 case (uint)ParcelMediaCommandEnum.Type:
9549 if ((i + 1) < commandList.Length) 10791 if ((i + 1) < commandList.Length)
9550 { 10792 {
9551 if (commandList.Data[i + 1] is LSL_String) 10793 if (commandList.Data[i + 1] is LSL_String)
@@ -9558,7 +10800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 } 10800 }
9559 break; 10801 break;
9560 10802
9561 case ParcelMediaCommandEnum.Desc: 10803 case (uint)ParcelMediaCommandEnum.Desc:
9562 if ((i + 1) < commandList.Length) 10804 if ((i + 1) < commandList.Length)
9563 { 10805 {
9564 if (commandList.Data[i + 1] is LSL_String) 10806 if (commandList.Data[i + 1] is LSL_String)
@@ -9571,7 +10813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9571 } 10813 }
9572 break; 10814 break;
9573 10815
9574 case ParcelMediaCommandEnum.Size: 10816 case (uint)ParcelMediaCommandEnum.Size:
9575 if ((i + 2) < commandList.Length) 10817 if ((i + 2) < commandList.Length)
9576 { 10818 {
9577 if (commandList.Data[i + 1] is LSL_Integer) 10819 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9641,7 +10883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9641 } 10883 }
9642 } 10884 }
9643 10885
9644 if (commandToSend != null) 10886 if (commandToSend != 0)
9645 { 10887 {
9646 // the commandList contained a start/stop/... command, too 10888 // the commandList contained a start/stop/... command, too
9647 if (presence == null) 10889 if (presence == null)
@@ -9678,7 +10920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 10920
9679 if (aList.Data[i] != null) 10921 if (aList.Data[i] != null)
9680 { 10922 {
9681 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10923 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9682 { 10924 {
9683 case ParcelMediaCommandEnum.Url: 10925 case ParcelMediaCommandEnum.Url:
9684 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10926 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9735,15 +10977,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9735 10977
9736 if (quick_pay_buttons.Data.Length < 4) 10978 if (quick_pay_buttons.Data.Length < 4)
9737 { 10979 {
9738 LSLError("List must have at least 4 elements"); 10980 int x;
9739 return; 10981 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10982 {
10983 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10984 }
9740 } 10985 }
9741 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10986 int[] nPrice = new int[5];
9742 10987 nPrice[0] = price;
9743 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10988 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9744 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10989 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9745 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10990 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9746 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10991 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10992 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9747 m_host.ParentGroup.HasGroupChanged = true; 10993 m_host.ParentGroup.HasGroupChanged = true;
9748 } 10994 }
9749 10995
@@ -9760,7 +11006,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9760 return new LSL_Vector(); 11006 return new LSL_Vector();
9761 } 11007 }
9762 11008
9763 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11009// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11010 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9764 if (presence != null) 11011 if (presence != null)
9765 { 11012 {
9766 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11013 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9782,7 +11029,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 return new LSL_Rotation(); 11029 return new LSL_Rotation();
9783 } 11030 }
9784 11031
9785 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11032// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11033 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9786 if (presence != null) 11034 if (presence != null)
9787 { 11035 {
9788 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11036 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9842,8 +11090,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9842 { 11090 {
9843 m_host.AddScriptLPS(1); 11091 m_host.AddScriptLPS(1);
9844 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11092 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9845 if (detectedParams == null) return; // only works on the first detected avatar 11093 if (detectedParams == null)
9846 11094 {
11095 if (m_host.ParentGroup.IsAttachment == true)
11096 {
11097 detectedParams = new DetectParams();
11098 detectedParams.Key = m_host.OwnerID;
11099 }
11100 else
11101 {
11102 return;
11103 }
11104 }
11105
9847 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11106 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9848 if (avatar != null) 11107 if (avatar != null)
9849 { 11108 {
@@ -9851,6 +11110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9851 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11110 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9852 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11111 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9853 } 11112 }
11113
9854 ScriptSleep(1000); 11114 ScriptSleep(1000);
9855 } 11115 }
9856 11116
@@ -9974,12 +11234,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9974 11234
9975 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11235 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9976 object[] data = rules.Data; 11236 object[] data = rules.Data;
9977 for (int i = 0; i < data.Length; ++i) { 11237 for (int i = 0; i < data.Length; ++i)
11238 {
9978 int type = Convert.ToInt32(data[i++].ToString()); 11239 int type = Convert.ToInt32(data[i++].ToString());
9979 if (i >= data.Length) break; // odd number of entries => ignore the last 11240 if (i >= data.Length) break; // odd number of entries => ignore the last
9980 11241
9981 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11242 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9982 switch (type) { 11243 switch (type)
11244 {
9983 case ScriptBaseClass.CAMERA_FOCUS: 11245 case ScriptBaseClass.CAMERA_FOCUS:
9984 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11246 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9985 case ScriptBaseClass.CAMERA_POSITION: 11247 case ScriptBaseClass.CAMERA_POSITION:
@@ -10085,19 +11347,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11347 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10086 { 11348 {
10087 m_host.AddScriptLPS(1); 11349 m_host.AddScriptLPS(1);
10088 string ret = String.Empty; 11350
10089 string src1 = llBase64ToString(str1); 11351 if (str1 == String.Empty)
10090 string src2 = llBase64ToString(str2); 11352 return String.Empty;
10091 int c = 0; 11353 if (str2 == String.Empty)
10092 for (int i = 0; i < src1.Length; i++) 11354 return str1;
11355
11356 int len = str2.Length;
11357 if ((len % 4) != 0) // LL is EVIL!!!!
10093 { 11358 {
10094 ret += (char) (src1[i] ^ src2[c]); 11359 while (str2.EndsWith("="))
11360 str2 = str2.Substring(0, str2.Length - 1);
11361
11362 len = str2.Length;
11363 int mod = len % 4;
10095 11364
10096 c++; 11365 if (mod == 1)
10097 if (c >= src2.Length) 11366 str2 = str2.Substring(0, str2.Length - 1);
10098 c = 0; 11367 else if (mod == 2)
11368 str2 += "==";
11369 else if (mod == 3)
11370 str2 += "=";
10099 } 11371 }
10100 return llStringToBase64(ret); 11372
11373 byte[] data1;
11374 byte[] data2;
11375 try
11376 {
11377 data1 = Convert.FromBase64String(str1);
11378 data2 = Convert.FromBase64String(str2);
11379 }
11380 catch (Exception)
11381 {
11382 return new LSL_String(String.Empty);
11383 }
11384
11385 byte[] d2 = new Byte[data1.Length];
11386 int pos = 0;
11387
11388 if (data1.Length <= data2.Length)
11389 {
11390 Array.Copy(data2, 0, d2, 0, data1.Length);
11391 }
11392 else
11393 {
11394 while (pos < data1.Length)
11395 {
11396 len = data1.Length - pos;
11397 if (len > data2.Length)
11398 len = data2.Length;
11399
11400 Array.Copy(data2, 0, d2, pos, len);
11401 pos += len;
11402 }
11403 }
11404
11405 for (pos = 0 ; pos < data1.Length ; pos++ )
11406 data1[pos] ^= d2[pos];
11407
11408 return Convert.ToBase64String(data1);
10101 } 11409 }
10102 11410
10103 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11411 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10154,12 +11462,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10154 Regex r = new Regex(authregex); 11462 Regex r = new Regex(authregex);
10155 int[] gnums = r.GetGroupNumbers(); 11463 int[] gnums = r.GetGroupNumbers();
10156 Match m = r.Match(url); 11464 Match m = r.Match(url);
10157 if (m.Success) { 11465 if (m.Success)
10158 for (int i = 1; i < gnums.Length; i++) { 11466 {
11467 for (int i = 1; i < gnums.Length; i++)
11468 {
10159 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11469 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10160 //CaptureCollection cc = g.Captures; 11470 //CaptureCollection cc = g.Captures;
10161 } 11471 }
10162 if (m.Groups.Count == 5) { 11472 if (m.Groups.Count == 5)
11473 {
10163 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11474 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(); 11475 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10165 } 11476 }
@@ -10362,6 +11673,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10362 11673
10363 LSL_List ret = new LSL_List(); 11674 LSL_List ret = new LSL_List();
10364 UUID key = new UUID(); 11675 UUID key = new UUID();
11676
11677
10365 if (UUID.TryParse(id, out key)) 11678 if (UUID.TryParse(id, out key))
10366 { 11679 {
10367 ScenePresence av = World.GetScenePresence(key); 11680 ScenePresence av = World.GetScenePresence(key);
@@ -10379,13 +11692,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10379 ret.Add(new LSL_String("")); 11692 ret.Add(new LSL_String(""));
10380 break; 11693 break;
10381 case ScriptBaseClass.OBJECT_POS: 11694 case ScriptBaseClass.OBJECT_POS:
10382 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11695 Vector3 avpos;
11696
11697 if (av.ParentID != 0 && av.ParentPart != null)
11698 {
11699 avpos = av.OffsetPosition;
11700
11701 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11702 avpos -= sitOffset;
11703
11704 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11705 }
11706 else
11707 avpos = av.AbsolutePosition;
11708
11709 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10383 break; 11710 break;
10384 case ScriptBaseClass.OBJECT_ROT: 11711 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)); 11712 Quaternion avrot = av.Rotation;
11713 if (av.ParentID != 0 && av.ParentPart != null)
11714 {
11715 avrot = av.ParentPart.GetWorldRotation() * avrot;
11716 }
11717 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10386 break; 11718 break;
10387 case ScriptBaseClass.OBJECT_VELOCITY: 11719 case ScriptBaseClass.OBJECT_VELOCITY:
10388 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11720 Vector3 avvel = av.Velocity;
11721 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10389 break; 11722 break;
10390 case ScriptBaseClass.OBJECT_OWNER: 11723 case ScriptBaseClass.OBJECT_OWNER:
10391 ret.Add(new LSL_String(id)); 11724 ret.Add(new LSL_String(id));
@@ -10441,17 +11774,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10441 case ScriptBaseClass.OBJECT_NAME: 11774 case ScriptBaseClass.OBJECT_NAME:
10442 ret.Add(new LSL_String(obj.Name)); 11775 ret.Add(new LSL_String(obj.Name));
10443 break; 11776 break;
10444 case ScriptBaseClass.OBJECT_DESC: 11777 case ScriptBaseClass.OBJECT_DESC:
10445 ret.Add(new LSL_String(obj.Description)); 11778 ret.Add(new LSL_String(obj.Description));
10446 break; 11779 break;
10447 case ScriptBaseClass.OBJECT_POS: 11780 case ScriptBaseClass.OBJECT_POS:
10448 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11781 Vector3 opos = obj.AbsolutePosition;
11782 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10449 break; 11783 break;
10450 case ScriptBaseClass.OBJECT_ROT: 11784 case ScriptBaseClass.OBJECT_ROT:
10451 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11785// Quaternion orot = obj.RotationOffset;
11786// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11787
11788 LSL_Rotation objrot = GetPartRot(obj);
11789 ret.Add(objrot);
10452 break; 11790 break;
10453 case ScriptBaseClass.OBJECT_VELOCITY: 11791 case ScriptBaseClass.OBJECT_VELOCITY:
10454 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11792 Vector3 ovel = obj.Velocity;
11793 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10455 break; 11794 break;
10456 case ScriptBaseClass.OBJECT_OWNER: 11795 case ScriptBaseClass.OBJECT_OWNER:
10457 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11796 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10485,9 +11824,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10485 // The value returned in SL for normal prims is prim count 11824 // The value returned in SL for normal prims is prim count
10486 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11825 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10487 break; 11826 break;
10488 // The following 3 costs I have intentionaly coded to return zero. They are part of 11827
10489 // "Land Impact" calculations. These calculations are probably not applicable 11828 // 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: 11829 case ScriptBaseClass.OBJECT_SERVER_COST:
10492 // The linden calculation is here 11830 // The linden calculation is here
10493 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11831 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10495,16 +11833,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10495 ret.Add(new LSL_Float(0)); 11833 ret.Add(new LSL_Float(0));
10496 break; 11834 break;
10497 case ScriptBaseClass.OBJECT_STREAMING_COST: 11835 case ScriptBaseClass.OBJECT_STREAMING_COST:
10498 // The linden calculation is here 11836 // The value returned in SL for normal prims is prim count * 0.06
10499 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11837 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; 11838 break;
10503 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11839 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10504 // The linden calculation is here 11840 // The value returned in SL for normal prims is prim count
10505 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11841 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; 11842 break;
10509 default: 11843 default:
10510 // Invalid or unhandled constant. 11844 // Invalid or unhandled constant.
@@ -10693,15 +12027,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10693 return GetLinkPrimitiveParams(obj, rules); 12027 return GetLinkPrimitiveParams(obj, rules);
10694 } 12028 }
10695 12029
10696 public void print(string str) 12030 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10697 { 12031 {
10698 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12032 List<SceneObjectPart> parts = GetLinkParts(link);
10699 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12033 if (parts.Count < 1)
10700 if (ossl != null) 12034 return 0;
10701 { 12035
10702 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12036 return GetNumberOfSides(parts[0]);
10703 m_log.Info("LSL print():" + str);
10704 }
10705 } 12037 }
10706 12038
10707 private string Name2Username(string name) 12039 private string Name2Username(string name)
@@ -10746,7 +12078,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10746 12078
10747 return rq.ToString(); 12079 return rq.ToString();
10748 } 12080 }
10749 12081/*
12082 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12083 {
12084 m_SayShoutCount = 0;
12085 }
12086*/
10750 private struct Tri 12087 private struct Tri
10751 { 12088 {
10752 public Vector3 p1; 12089 public Vector3 p1;
@@ -10886,9 +12223,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10886 12223
10887 ContactResult result = new ContactResult (); 12224 ContactResult result = new ContactResult ();
10888 result.ConsumerID = group.LocalId; 12225 result.ConsumerID = group.LocalId;
10889 result.Depth = intersection.distance; 12226// result.Depth = intersection.distance;
10890 result.Normal = intersection.normal; 12227 result.Normal = intersection.normal;
10891 result.Pos = intersection.ipoint; 12228 result.Pos = intersection.ipoint;
12229 result.Depth = Vector3.Mag(rayStart - result.Pos);
10892 12230
10893 contacts.Add(result); 12231 contacts.Add(result);
10894 }); 12232 });
@@ -11021,6 +12359,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11021 12359
11022 return contacts[0]; 12360 return contacts[0];
11023 } 12361 }
12362/*
12363 // not done:
12364 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12365 {
12366 ContactResult[] contacts = null;
12367 World.ForEachSOG(delegate(SceneObjectGroup group)
12368 {
12369 if (m_host.ParentGroup == group)
12370 return;
12371
12372 if (group.IsAttachment)
12373 return;
12374
12375 if(group.RootPart.PhysActor != null)
12376 return;
12377
12378 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12379 });
12380 return contacts;
12381 }
12382*/
11024 12383
11025 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12384 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11026 { 12385 {
@@ -11062,32 +12421,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11062 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12421 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11063 12422
11064 12423
11065 if (checkTerrain) 12424 if (World.SuportsRayCastFiltered())
11066 { 12425 {
11067 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12426 if (dist == 0)
11068 if (groundContact != null) 12427 return list;
11069 results.Add((ContactResult)groundContact);
11070 }
11071 12428
11072 if (checkAgents) 12429 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11073 { 12430 if (checkTerrain)
11074 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12431 rayfilter |= RayFilterFlags.land;
11075 foreach (ContactResult r in agentHits) 12432// if (checkAgents)
11076 results.Add(r); 12433// rayfilter |= RayFilterFlags.agent;
11077 } 12434 if (checkPhysical)
12435 rayfilter |= RayFilterFlags.physical;
12436 if (checkNonPhysical)
12437 rayfilter |= RayFilterFlags.nonphysical;
12438 if (detectPhantom)
12439 rayfilter |= RayFilterFlags.LSLPhanton;
12440
12441 Vector3 direction = dir * ( 1/dist);
12442
12443 if(rayfilter == 0)
12444 {
12445 list.Add(new LSL_Integer(0));
12446 return list;
12447 }
12448
12449 // get some more contacts to sort ???
12450 int physcount = 4 * count;
12451 if (physcount > 20)
12452 physcount = 20;
12453
12454 object physresults;
12455 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12456
12457 if (physresults == null)
12458 {
12459 list.Add(new LSL_Integer(-3)); // timeout error
12460 return list;
12461 }
11078 12462
11079 if (checkPhysical || checkNonPhysical || detectPhantom) 12463 results = (List<ContactResult>)physresults;
12464
12465 // for now physics doesn't detect sitted avatars so do it outside physics
12466 if (checkAgents)
12467 {
12468 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12469 foreach (ContactResult r in agentHits)
12470 results.Add(r);
12471 }
12472
12473 // TODO: Replace this with a better solution. ObjectIntersection can only
12474 // detect nonphysical phantoms. They are detected by virtue of being
12475 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12476 // physicsl phantoms as done by the physics scene
12477 // We don't want anything else but phantoms here.
12478 if (detectPhantom)
12479 {
12480 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12481 foreach (ContactResult r in objectHits)
12482 results.Add(r);
12483 }
12484 }
12485 else
11080 { 12486 {
11081 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12487 if (checkTerrain)
11082 foreach (ContactResult r in objectHits) 12488 {
11083 results.Add(r); 12489 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12490 if (groundContact != null)
12491 results.Add((ContactResult)groundContact);
12492 }
12493
12494 if (checkAgents)
12495 {
12496 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12497 foreach (ContactResult r in agentHits)
12498 results.Add(r);
12499 }
12500
12501 if (checkPhysical || checkNonPhysical || detectPhantom)
12502 {
12503 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12504 foreach (ContactResult r in objectHits)
12505 results.Add(r);
12506 }
11084 } 12507 }
11085 12508
11086 results.Sort(delegate(ContactResult a, ContactResult b) 12509 results.Sort(delegate(ContactResult a, ContactResult b)
11087 { 12510 {
11088 return a.Depth.CompareTo(b.Depth); 12511 return a.Depth.CompareTo(b.Depth);
11089 }); 12512 });
11090 12513
11091 int values = 0; 12514 int values = 0;
11092 SceneObjectGroup thisgrp = m_host.ParentGroup; 12515 SceneObjectGroup thisgrp = m_host.ParentGroup;
11093 12516
@@ -11180,7 +12603,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11180 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12603 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11181 if (!isAccount) return 0; 12604 if (!isAccount) return 0;
11182 if (estate.HasAccess(id)) return 1; 12605 if (estate.HasAccess(id)) return 1;
11183 if (estate.IsBanned(id)) 12606 if (estate.IsBanned(id, World.GetUserFlags(id)))
11184 estate.RemoveBan(id); 12607 estate.RemoveBan(id);
11185 estate.AddEstateUser(id); 12608 estate.AddEstateUser(id);
11186 break; 12609 break;
@@ -11199,14 +12622,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11199 break; 12622 break;
11200 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12623 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11201 if (!isAccount) return 0; 12624 if (!isAccount) return 0;
11202 if (estate.IsBanned(id)) return 1; 12625 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11203 EstateBan ban = new EstateBan(); 12626 EstateBan ban = new EstateBan();
11204 ban.EstateID = estate.EstateID; 12627 ban.EstateID = estate.EstateID;
11205 ban.BannedUserID = id; 12628 ban.BannedUserID = id;
11206 estate.AddBan(ban); 12629 estate.AddBan(ban);
11207 break; 12630 break;
11208 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12631 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11209 if (!isAccount || !estate.IsBanned(id)) return 0; 12632 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11210 estate.RemoveBan(id); 12633 estate.RemoveBan(id);
11211 break; 12634 break;
11212 default: return 0; 12635 default: return 0;
@@ -11235,7 +12658,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11235 return 16384; 12658 return 16384;
11236 } 12659 }
11237 12660
11238 public LSL_Integer llGetUsedMemory() 12661 public virtual LSL_Integer llGetUsedMemory()
11239 { 12662 {
11240 m_host.AddScriptLPS(1); 12663 m_host.AddScriptLPS(1);
11241 // The value returned for LSO scripts in SL 12664 // The value returned for LSO scripts in SL
@@ -11263,7 +12686,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11263 public void llSetSoundQueueing(int queue) 12686 public void llSetSoundQueueing(int queue)
11264 { 12687 {
11265 m_host.AddScriptLPS(1); 12688 m_host.AddScriptLPS(1);
11266 NotImplemented("llSetSoundQueueing");
11267 } 12689 }
11268 12690
11269 public void llCollisionSprite(string impact_sprite) 12691 public void llCollisionSprite(string impact_sprite)
@@ -11275,10 +12697,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11275 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12697 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11276 { 12698 {
11277 m_host.AddScriptLPS(1); 12699 m_host.AddScriptLPS(1);
11278 NotImplemented("llGodLikeRezObject"); 12700
12701 if (!World.Permissions.IsGod(m_host.OwnerID))
12702 NotImplemented("llGodLikeRezObject");
12703
12704 AssetBase rezAsset = World.AssetService.Get(inventory);
12705 if (rezAsset == null)
12706 {
12707 llSay(0, "Asset not found");
12708 return;
12709 }
12710
12711 SceneObjectGroup group = null;
12712
12713 try
12714 {
12715 string xmlData = Utils.BytesToString(rezAsset.Data);
12716 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12717 }
12718 catch
12719 {
12720 llSay(0, "Asset not found");
12721 return;
12722 }
12723
12724 if (group == null)
12725 {
12726 llSay(0, "Asset not found");
12727 return;
12728 }
12729
12730 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12731 group.RootPart.AttachOffset = group.AbsolutePosition;
12732
12733 group.ResetIDs();
12734
12735 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12736 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12737 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12738 group.ScheduleGroupForFullUpdate();
12739
12740 // objects rezzed with this method are die_at_edge by default.
12741 group.RootPart.SetDieAtEdge(true);
12742
12743 group.ResumeScripts();
12744
12745 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12746 "object_rez", new Object[] {
12747 new LSL_String(
12748 group.RootPart.UUID.ToString()) },
12749 new DetectParams[0]));
12750 }
12751
12752 public LSL_String llTransferLindenDollars(string destination, int amount)
12753 {
12754 UUID txn = UUID.Random();
12755
12756 Util.FireAndForget(delegate(object x)
12757 {
12758 int replycode = 0;
12759 string replydata = destination + "," + amount.ToString();
12760
12761 try
12762 {
12763 TaskInventoryItem item = m_item;
12764 if (item == null)
12765 {
12766 replydata = "SERVICE_ERROR";
12767 return;
12768 }
12769
12770 m_host.AddScriptLPS(1);
12771
12772 if (item.PermsGranter == UUID.Zero)
12773 {
12774 replydata = "MISSING_PERMISSION_DEBIT";
12775 return;
12776 }
12777
12778 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12779 {
12780 replydata = "MISSING_PERMISSION_DEBIT";
12781 return;
12782 }
12783
12784 UUID toID = new UUID();
12785
12786 if (!UUID.TryParse(destination, out toID))
12787 {
12788 replydata = "INVALID_AGENT";
12789 return;
12790 }
12791
12792 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12793
12794 if (money == null)
12795 {
12796 replydata = "TRANSFERS_DISABLED";
12797 return;
12798 }
12799
12800 bool result = money.ObjectGiveMoney(
12801 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12802
12803 if (result)
12804 {
12805 replycode = 1;
12806 return;
12807 }
12808
12809 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12810 }
12811 finally
12812 {
12813 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12814 "transaction_result", new Object[] {
12815 new LSL_String(txn.ToString()),
12816 new LSL_Integer(replycode),
12817 new LSL_String(replydata) },
12818 new DetectParams[0]));
12819 }
12820 });
12821
12822 return txn.ToString();
11279 } 12823 }
11280 12824
11281 #endregion 12825 #endregion
12826
12827 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12828 {
12829 SceneObjectGroup group = m_host.ParentGroup;
12830
12831 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12832 return;
12833 if (group.IsAttachment)
12834 return;
12835
12836 if (frames.Data.Length > 0) // We are getting a new motion
12837 {
12838 if (group.RootPart.KeyframeMotion != null)
12839 group.RootPart.KeyframeMotion.Stop();
12840 group.RootPart.KeyframeMotion = null;
12841
12842 int idx = 0;
12843
12844 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12845 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12846
12847 while (idx < options.Data.Length)
12848 {
12849 int option = (int)options.GetLSLIntegerItem(idx++);
12850 int remain = options.Data.Length - idx;
12851
12852 switch (option)
12853 {
12854 case ScriptBaseClass.KFM_MODE:
12855 if (remain < 1)
12856 break;
12857 int modeval = (int)options.GetLSLIntegerItem(idx++);
12858 switch(modeval)
12859 {
12860 case ScriptBaseClass.KFM_FORWARD:
12861 mode = KeyframeMotion.PlayMode.Forward;
12862 break;
12863 case ScriptBaseClass.KFM_REVERSE:
12864 mode = KeyframeMotion.PlayMode.Reverse;
12865 break;
12866 case ScriptBaseClass.KFM_LOOP:
12867 mode = KeyframeMotion.PlayMode.Loop;
12868 break;
12869 case ScriptBaseClass.KFM_PING_PONG:
12870 mode = KeyframeMotion.PlayMode.PingPong;
12871 break;
12872 }
12873 break;
12874 case ScriptBaseClass.KFM_DATA:
12875 if (remain < 1)
12876 break;
12877 int dataval = (int)options.GetLSLIntegerItem(idx++);
12878 data = (KeyframeMotion.DataFormat)dataval;
12879 break;
12880 }
12881 }
12882
12883 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12884
12885 idx = 0;
12886
12887 int elemLength = 2;
12888 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12889 elemLength = 3;
12890
12891 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12892 while (idx < frames.Data.Length)
12893 {
12894 int remain = frames.Data.Length - idx;
12895
12896 if (remain < elemLength)
12897 break;
12898
12899 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12900 frame.Position = null;
12901 frame.Rotation = null;
12902
12903 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12904 {
12905 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12906 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12907 }
12908 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12909 {
12910 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12911 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12912 }
12913
12914 float tempf = (float)frames.GetLSLFloatItem(idx++);
12915 frame.TimeMS = (int)(tempf * 1000.0f);
12916
12917 keyframes.Add(frame);
12918 }
12919
12920 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12921 group.RootPart.KeyframeMotion.Start();
12922 }
12923 else
12924 {
12925 if (group.RootPart.KeyframeMotion == null)
12926 return;
12927
12928 if (options.Data.Length == 0)
12929 {
12930 group.RootPart.KeyframeMotion.Stop();
12931 return;
12932 }
12933
12934 int code = (int)options.GetLSLIntegerItem(0);
12935
12936 int idx = 0;
12937
12938 while (idx < options.Data.Length)
12939 {
12940 int option = (int)options.GetLSLIntegerItem(idx++);
12941 int remain = options.Data.Length - idx;
12942
12943 switch (option)
12944 {
12945 case ScriptBaseClass.KFM_COMMAND:
12946 int cmd = (int)options.GetLSLIntegerItem(idx++);
12947 switch (cmd)
12948 {
12949 case ScriptBaseClass.KFM_CMD_PLAY:
12950 group.RootPart.KeyframeMotion.Start();
12951 break;
12952 case ScriptBaseClass.KFM_CMD_STOP:
12953 group.RootPart.KeyframeMotion.Stop();
12954 break;
12955 case ScriptBaseClass.KFM_CMD_PAUSE:
12956 group.RootPart.KeyframeMotion.Pause();
12957 break;
12958 }
12959 break;
12960 }
12961 }
12962 }
12963 }
11282 } 12964 }
11283 12965
11284 public class NotecardCache 12966 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 f1abd4b..8d92ba5 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;
@@ -222,13 +223,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
222 223
223 if (part != null) 224 if (part != null)
224 { 225 {
225 lock (part.TaskInventory) 226 part.TaskInventory.LockItemsForRead(true);
227 if (part.TaskInventory.ContainsKey(ItemID))
226 { 228 {
227 if (part.TaskInventory.ContainsKey(ItemID)) 229 ScriptTask = part.TaskInventory[ItemID];
228 {
229 ScriptTask = part.TaskInventory[ItemID];
230 }
231 } 230 }
231 part.TaskInventory.LockItemsForRead(false);
232 } 232 }
233 233
234 ApiManager am = new ApiManager(); 234 ApiManager am = new ApiManager();
@@ -424,14 +424,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
424 { 424 {
425 int permsMask; 425 int permsMask;
426 UUID permsGranter; 426 UUID permsGranter;
427 lock (part.TaskInventory) 427 part.TaskInventory.LockItemsForRead(true);
428 if (!part.TaskInventory.ContainsKey(ItemID))
428 { 429 {
429 if (!part.TaskInventory.ContainsKey(ItemID)) 430 part.TaskInventory.LockItemsForRead(false);
430 return; 431 return;
431
432 permsGranter = part.TaskInventory[ItemID].PermsGranter;
433 permsMask = part.TaskInventory[ItemID].PermsMask;
434 } 432 }
433 permsGranter = part.TaskInventory[ItemID].PermsGranter;
434 permsMask = part.TaskInventory[ItemID].PermsMask;
435 part.TaskInventory.LockItemsForRead(false);
435 436
436 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 437 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
437 { 438 {
@@ -559,6 +560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
559 return true; 560 return true;
560 } 561 }
561 562
563 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
562 public void SetState(string state) 564 public void SetState(string state)
563 { 565 {
564 if (state == State) 566 if (state == State)
@@ -570,7 +572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
570 new DetectParams[0])); 572 new DetectParams[0]));
571 PostEvent(new EventParams("state_entry", new Object[0], 573 PostEvent(new EventParams("state_entry", new Object[0],
572 new DetectParams[0])); 574 new DetectParams[0]));
573 575
574 throw new EventAbortException(); 576 throw new EventAbortException();
575 } 577 }
576 578
@@ -660,45 +662,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
660 /// <returns></returns> 662 /// <returns></returns>
661 public object EventProcessor() 663 public object EventProcessor()
662 { 664 {
665 EventParams data = null;
663 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 666 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
664 if (!Running) 667 if (!Running)
665 return 0; 668 return 0;
666 669
667 lock (m_Script)
668 {
669// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 670// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
670 671
671 if (Suspended) 672 if (Suspended)
672 return 0; 673 return 0;
673
674 EventParams data = null;
675 674
676 lock (EventQueue) 675 lock (EventQueue)
676 {
677 data = (EventParams) EventQueue.Dequeue();
678 if (data == null) // Shouldn't happen
677 { 679 {
678 data = (EventParams)EventQueue.Dequeue(); 680 if (EventQueue.Count > 0 && Running && !ShuttingDown)
679 if (data == null) // Shouldn't happen
680 { 681 {
681 if (EventQueue.Count > 0 && Running && !ShuttingDown) 682 m_CurrentWorkItem = Engine.QueueEventHandler(this);
682 {
683 m_CurrentWorkItem = Engine.QueueEventHandler(this);
684 }
685 else
686 {
687 m_CurrentWorkItem = null;
688 }
689 return 0;
690 } 683 }
691 684 else
692 if (data.EventName == "timer")
693 m_TimerQueued = false;
694 if (data.EventName == "control")
695 { 685 {
696 if (m_ControlEventsInQueue > 0) 686 m_CurrentWorkItem = null;
697 m_ControlEventsInQueue--;
698 } 687 }
699 if (data.EventName == "collision") 688 return 0;
700 m_CollisionInQueue = false;
701 } 689 }
690
691 if (data.EventName == "timer")
692 m_TimerQueued = false;
693 if (data.EventName == "control")
694 {
695 if (m_ControlEventsInQueue > 0)
696 m_ControlEventsInQueue--;
697 }
698 if (data.EventName == "collision")
699 m_CollisionInQueue = false;
700 }
701
702 lock(m_Script)
703 {
702 704
703// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 705// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
704 706
@@ -853,6 +855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
853 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 855 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
854 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 856 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
855 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 857 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
858 part.CollisionSound = UUID.Zero;
856 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 859 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
857 EventQueue.Clear(); 860 EventQueue.Clear();
858 m_Script.ResetVars(); 861 m_Script.ResetVars();
@@ -867,6 +870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 new Object[0], new DetectParams[0])); 870 new Object[0], new DetectParams[0]));
868 } 871 }
869 872
873 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
870 public void ApiResetScript() 874 public void ApiResetScript()
871 { 875 {
872 // bool running = Running; 876 // bool running = Running;
@@ -878,6 +882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
878 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 882 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
879 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 883 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
880 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 884 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
885 part.CollisionSound = UUID.Zero;
881 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 886 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
882 887
883 EventQueue.Clear(); 888 EventQueue.Clear();
@@ -898,10 +903,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
898 903
899 public Dictionary<string, object> GetVars() 904 public Dictionary<string, object> GetVars()
900 { 905 {
901 if (m_Script != null) 906 return m_Script.GetVars();
902 return m_Script.GetVars();
903 else
904 return new Dictionary<string, object>();
905 } 907 }
906 908
907 public void SetVars(Dictionary<string, object> vars) 909 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 20fad05..d763063 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
@@ -1556,6 +1647,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1556 return false; 1647 return false;
1557 } 1648 }
1558 1649
1650 [DebuggerNonUserCode]
1559 public void ApiResetScript(UUID itemID) 1651 public void ApiResetScript(UUID itemID)
1560 { 1652 {
1561 IScriptInstance instance = GetInstance(itemID); 1653 IScriptInstance instance = GetInstance(itemID);
@@ -1611,6 +1703,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1611 return UUID.Zero; 1703 return UUID.Zero;
1612 } 1704 }
1613 1705
1706 [DebuggerNonUserCode]
1614 public void SetState(UUID itemID, string newState) 1707 public void SetState(UUID itemID, string newState)
1615 { 1708 {
1616 IScriptInstance instance = GetInstance(itemID); 1709 IScriptInstance instance = GetInstance(itemID);
@@ -1633,11 +1726,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1633 1726
1634 List<IScriptInstance> instances = new List<IScriptInstance>(); 1727 List<IScriptInstance> instances = new List<IScriptInstance>();
1635 1728
1636 lock (m_Scripts) 1729 lockScriptsForRead(true);
1637 { 1730 foreach (IScriptInstance instance in m_Scripts.Values)
1638 foreach (IScriptInstance instance in m_Scripts.Values)
1639 instances.Add(instance); 1731 instances.Add(instance);
1640 } 1732 lockScriptsForRead(false);
1641 1733
1642 foreach (IScriptInstance i in instances) 1734 foreach (IScriptInstance i in instances)
1643 { 1735 {