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.cs3193
-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.cs11
-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.cs51
-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.cs348
19 files changed, 3202 insertions, 989 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 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 0a25454..b257cd4 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,48 @@ 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
119 private Dictionary<string, string> MovementAnimationsForLSL =
120 new Dictionary<string, string> {
121 {"FLY", "Flying"},
122 {"FLYSLOW", "FlyingSlow"},
123 {"HOVER_UP", "Hovering Up"},
124 {"HOVER_DOWN", "Hovering Down"},
125 {"HOVER", "Hovering"},
126 {"LAND", "Landing"},
127 {"FALLDOWN", "Falling Down"},
128 {"PREJUMP", "PreJumping"},
129 {"JUMP", "Jumping"},
130 {"STANDUP", "Standing Up"},
131 {"SOFT_LAND", "Soft Landing"},
132 {"STAND", "Standing"},
133 {"CROUCHWALK", "CrouchWalking"},
134 {"RUN", "Running"},
135 {"WALK", "Walking"},
136 {"CROUCH", "Crouching"},
137 {"TURNLEFT", "Turning Left"},
138 {"TURNRIGHT", "Turning Right"}
139 };
109 140
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 142 {
143 m_ShoutSayTimer = new Timer(1000);
144 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
145 m_ShoutSayTimer.AutoReset = true;
146 m_ShoutSayTimer.Start();
147
112 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
113 m_host = host; 149 m_host = host;
114 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 152
116 LoadLimits(); // read script limits from config. 153 LoadLimits(); // read script limits from config.
117 154
@@ -171,6 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 208 get { return m_ScriptEngine.World; }
172 } 209 }
173 210
211 [DebuggerNonUserCode]
174 public void state(string newState) 212 public void state(string newState)
175 { 213 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 214 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 218 /// Reset the named script. The script must be present
181 /// in the same prim. 219 /// in the same prim.
182 /// </summary> 220 /// </summary>
221 [DebuggerNonUserCode]
183 public void llResetScript() 222 public void llResetScript()
184 { 223 {
185 m_host.AddScriptLPS(1); 224 m_host.AddScriptLPS(1);
@@ -236,9 +275,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 275 }
237 } 276 }
238 277
278 public List<ScenePresence> GetLinkAvatars(int linkType)
279 {
280 List<ScenePresence> ret = new List<ScenePresence>();
281 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
282 return ret;
283
284 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
285
286 switch (linkType)
287 {
288 case ScriptBaseClass.LINK_SET:
289 return avs;
290
291 case ScriptBaseClass.LINK_ROOT:
292 return ret;
293
294 case ScriptBaseClass.LINK_ALL_OTHERS:
295 return avs;
296
297 case ScriptBaseClass.LINK_ALL_CHILDREN:
298 return avs;
299
300 case ScriptBaseClass.LINK_THIS:
301 return ret;
302
303 default:
304 if (linkType < 0)
305 return ret;
306
307 int partCount = m_host.ParentGroup.GetPartCount();
308
309 if (linkType <= partCount)
310 {
311 return ret;
312 }
313 else
314 {
315 linkType = linkType - partCount;
316 if (linkType > avs.Count)
317 {
318 return ret;
319 }
320 else
321 {
322 ret.Add(avs[linkType-1]);
323 return ret;
324 }
325 }
326 }
327 }
328
239 public List<SceneObjectPart> GetLinkParts(int linkType) 329 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 330 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 331 List<SceneObjectPart> ret = new List<SceneObjectPart>();
332 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
333 return ret;
242 ret.Add(m_host); 334 ret.Add(m_host);
243 335
244 switch (linkType) 336 switch (linkType)
@@ -432,31 +524,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
432 524
433 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 525 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
434 526
435 /// <summary> 527 // Utility function for llRot2Euler
436 /// Convert an LSL rotation to a Euler vector. 528
437 /// </summary> 529 // normalize an angle between -PI and PI (-180 to +180 degrees)
438 /// <remarks> 530 protected double NormalizeAngle(double angle)
439 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
440 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
441 /// </remarks>
442 /// <param name="r"></param>
443 /// <returns></returns>
444 public LSL_Vector llRot2Euler(LSL_Rotation r)
445 { 531 {
446 m_host.AddScriptLPS(1); 532 if (angle > -Math.PI && angle < Math.PI)
533 return angle;
534
535 int numPis = (int)(Math.PI / angle);
536 double remainder = angle - Math.PI * numPis;
537 if (numPis % 2 == 1)
538 return Math.PI - angle;
539 return remainder;
540 }
447 541
448 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 542 public LSL_Vector llRot2Euler(LSL_Rotation q1)
449 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 543 {
450 if (m == 0.0) return new LSL_Vector(); 544 m_host.AddScriptLPS(1);
451 double x = Math.Atan2(-v.y, v.z); 545 LSL_Vector eul = new LSL_Vector();
452 double sin = v.x / m;
453 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
454 double y = Math.Asin(sin);
455 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
456 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)));
457 double z = Math.Atan2(v.y, v.x);
458 546
459 return new LSL_Vector(x, y, z); 547 double sqw = q1.s*q1.s;
548 double sqx = q1.x*q1.x;
549 double sqy = q1.z*q1.z;
550 double sqz = q1.y*q1.y;
551 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
552 double test = q1.x*q1.z + q1.y*q1.s;
553 if (test > 0.4999*unit) { // singularity at north pole
554 eul.z = 2 * Math.Atan2(q1.x,q1.s);
555 eul.y = Math.PI/2;
556 eul.x = 0;
557 return eul;
558 }
559 if (test < -0.4999*unit) { // singularity at south pole
560 eul.z = -2 * Math.Atan2(q1.x,q1.s);
561 eul.y = -Math.PI/2;
562 eul.x = 0;
563 return eul;
564 }
565 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
566 eul.y = Math.Asin(2*test/unit);
567 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
568 return eul;
460 } 569 }
461 570
462 /* From wiki: 571 /* From wiki:
@@ -509,18 +618,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
509 m_host.AddScriptLPS(1); 618 m_host.AddScriptLPS(1);
510 619
511 double x,y,z,s; 620 double x,y,z,s;
512 621 v.x *= 0.5;
513 double c1 = Math.Cos(v.x * 0.5); 622 v.y *= 0.5;
514 double c2 = Math.Cos(v.y * 0.5); 623 v.z *= 0.5;
515 double c3 = Math.Cos(v.z * 0.5); 624 double c1 = Math.Cos(v.x);
516 double s1 = Math.Sin(v.x * 0.5); 625 double c2 = Math.Cos(v.y);
517 double s2 = Math.Sin(v.y * 0.5); 626 double c1c2 = c1 * c2;
518 double s3 = Math.Sin(v.z * 0.5); 627 double s1 = Math.Sin(v.x);
519 628 double s2 = Math.Sin(v.y);
520 x = s1 * c2 * c3 + c1 * s2 * s3; 629 double s1s2 = s1 * s2;
521 y = c1 * s2 * c3 - s1 * c2 * s3; 630 double c1s2 = c1 * s2;
522 z = s1 * s2 * c3 + c1 * c2 * s3; 631 double s1c2 = s1 * c2;
523 s = c1 * c2 * c3 - s1 * s2 * s3; 632 double c3 = Math.Cos(v.z);
633 double s3 = Math.Sin(v.z);
634
635 x = s1c2 * c3 + c1s2 * s3;
636 y = c1s2 * c3 - s1c2 * s3;
637 z = s1s2 * c3 + c1c2 * s3;
638 s = c1c2 * c3 - s1s2 * s3;
524 639
525 return new LSL_Rotation(x, y, z, s); 640 return new LSL_Rotation(x, y, z, s);
526 } 641 }
@@ -658,77 +773,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
658 { 773 {
659 //A and B should both be normalized 774 //A and B should both be normalized
660 m_host.AddScriptLPS(1); 775 m_host.AddScriptLPS(1);
661 LSL_Rotation rotBetween; 776 /* This method is more accurate than the SL one, and thus causes problems
662 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 777 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
663 // continue calculation. 778
664 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 779 double dotProduct = LSL_Vector.Dot(a, b);
780 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
781 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
782 double angle = Math.Acos(dotProduct / magProduct);
783 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
784 double s = Math.Sin(angle / 2);
785
786 double x = axis.x * s;
787 double y = axis.y * s;
788 double z = axis.z * s;
789 double w = Math.Cos(angle / 2);
790
791 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
792 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
793
794 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
795 */
796
797 // This method mimics the 180 errors found in SL
798 // See www.euclideanspace.com... angleBetween
799 LSL_Vector vec_a = a;
800 LSL_Vector vec_b = b;
801
802 // Eliminate zero length
803 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
804 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
805 if (vec_a_mag < 0.00001 ||
806 vec_b_mag < 0.00001)
665 { 807 {
666 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 808 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
667 } 809 }
668 else 810
811 // Normalize
812 vec_a = llVecNorm(vec_a);
813 vec_b = llVecNorm(vec_b);
814
815 // Calculate axis and rotation angle
816 LSL_Vector axis = vec_a % vec_b;
817 LSL_Float cos_theta = vec_a * vec_b;
818
819 // Check if parallel
820 if (cos_theta > 0.99999)
669 { 821 {
670 a = LSL_Vector.Norm(a); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
671 b = LSL_Vector.Norm(b); 823 }
672 double dotProduct = LSL_Vector.Dot(a, b); 824
673 // There are two degenerate cases possible. These are for vectors 180 or 825 // Check if anti-parallel
674 // 0 degrees apart. These have to be detected and handled individually. 826 else if (cos_theta < -0.99999)
675 // 827 {
676 // Check for vectors 180 degrees apart. 828 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
677 // A dot product of -1 would mean the angle between vectors is 180 degrees. 829 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
678 if (dotProduct < -0.9999999f) 830 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
679 { 831 }
680 // First assume X axis is orthogonal to the vectors. 832 else // other rotation
681 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 833 {
682 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 834 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
683 // Check for near zero vector. A very small non-zero number here will create 835 axis = llVecNorm(axis);
684 // a rotation in an undesired direction. 836 double x, y, z, s, t;
685 if (LSL_Vector.Mag(orthoVector) > 0.0001) 837 s = Math.Cos(theta);
686 { 838 t = Math.Sin(theta);
687 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 839 x = axis.x * t;
688 } 840 y = axis.y * t;
689 // If the magnitude of the vector was near zero, then assume the X axis is not 841 z = axis.z * t;
690 // orthogonal and use the Z axis instead. 842 return new LSL_Rotation(x,y,z,s);
691 else
692 {
693 // Set 180 z rotation.
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
695 }
696 }
697 // Check for parallel vectors.
698 // A dot product of 1 would mean the angle between vectors is 0 degrees.
699 else if (dotProduct > 0.9999999f)
700 {
701 // Set zero rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
703 }
704 else
705 {
706 // All special checks have been performed so get the axis of rotation.
707 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
708 // Quarternion s value is the length of the unit vector + dot product.
709 double qs = 1.0 + dotProduct;
710 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
711 // Normalize the rotation.
712 double mag = LSL_Rotation.Mag(rotBetween);
713 // We shouldn't have to worry about a divide by zero here. The qs value will be
714 // non-zero because we already know if we're here, then the dotProduct is not -1 so
715 // qs will not be zero. Also, we've already handled the input vectors being zero so the
716 // crossProduct vector should also not be zero.
717 rotBetween.x = rotBetween.x / mag;
718 rotBetween.y = rotBetween.y / mag;
719 rotBetween.z = rotBetween.z / mag;
720 rotBetween.s = rotBetween.s / mag;
721 // Check for undefined values and set zero rotation if any found. This code might not actually be required
722 // any longer since zero vectors are checked for at the top.
723 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
724 {
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
726 }
727 }
728 } 843 }
729 return rotBetween;
730 } 844 }
731 845
732 public void llWhisper(int channelID, string text) 846 public void llWhisper(int channelID, string text)
733 { 847 {
734 m_host.AddScriptLPS(1); 848 m_host.AddScriptLPS(1);
@@ -748,6 +862,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
748 { 862 {
749 m_host.AddScriptLPS(1); 863 m_host.AddScriptLPS(1);
750 864
865 if (channelID == 0)
866 m_SayShoutCount++;
867
868 if (m_SayShoutCount >= 11)
869 ScriptSleep(2000);
870
751 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 871 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
752 { 872 {
753 Console.WriteLine(text); 873 Console.WriteLine(text);
@@ -770,6 +890,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
770 { 890 {
771 m_host.AddScriptLPS(1); 891 m_host.AddScriptLPS(1);
772 892
893 if (channelID == 0)
894 m_SayShoutCount++;
895
896 if (m_SayShoutCount >= 11)
897 ScriptSleep(2000);
898
773 if (text.Length > 1023) 899 if (text.Length > 1023)
774 text = text.Substring(0, 1023); 900 text = text.Substring(0, 1023);
775 901
@@ -801,22 +927,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 927
802 public void llRegionSayTo(string target, int channel, string msg) 928 public void llRegionSayTo(string target, int channel, string msg)
803 { 929 {
930 string error = String.Empty;
931
804 if (msg.Length > 1023) 932 if (msg.Length > 1023)
805 msg = msg.Substring(0, 1023); 933 msg = msg.Substring(0, 1023);
806 934
807 m_host.AddScriptLPS(1); 935 m_host.AddScriptLPS(1);
808 936
809 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
810 {
811 return;
812 }
813
814 UUID TargetID; 937 UUID TargetID;
815 UUID.TryParse(target, out TargetID); 938 UUID.TryParse(target, out TargetID);
816 939
817 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 940 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
818 if (wComm != null) 941 if (wComm != null)
819 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 942 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
943 LSLError(error);
820 } 944 }
821 945
822 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 946 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1072,10 +1196,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1072 return detectedParams.TouchUV; 1196 return detectedParams.TouchUV;
1073 } 1197 }
1074 1198
1199 [DebuggerNonUserCode]
1075 public virtual void llDie() 1200 public virtual void llDie()
1076 { 1201 {
1077 m_host.AddScriptLPS(1); 1202 m_host.AddScriptLPS(1);
1078 throw new SelfDeleteException(); 1203 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1079 } 1204 }
1080 1205
1081 public LSL_Float llGround(LSL_Vector offset) 1206 public LSL_Float llGround(LSL_Vector offset)
@@ -1148,6 +1273,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1148 1273
1149 public void llSetStatus(int status, int value) 1274 public void llSetStatus(int status, int value)
1150 { 1275 {
1276 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1277 return;
1151 m_host.AddScriptLPS(1); 1278 m_host.AddScriptLPS(1);
1152 1279
1153 int statusrotationaxis = 0; 1280 int statusrotationaxis = 0;
@@ -1171,6 +1298,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1171 if (!allow) 1298 if (!allow)
1172 return; 1299 return;
1173 1300
1301 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1302 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1303 return;
1304
1174 m_host.ScriptSetPhysicsStatus(true); 1305 m_host.ScriptSetPhysicsStatus(true);
1175 } 1306 }
1176 else 1307 else
@@ -1379,6 +1510,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1379 { 1510 {
1380 m_host.AddScriptLPS(1); 1511 m_host.AddScriptLPS(1);
1381 1512
1513 SetColor(m_host, color, face);
1514 }
1515
1516 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1517 {
1518 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1519 return;
1520
1521 Primitive.TextureEntry tex = part.Shape.Textures;
1522 Color4 texcolor;
1523 if (face >= 0 && face < GetNumberOfSides(part))
1524 {
1525 texcolor = tex.CreateFace((uint)face).RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[face].RGBA = texcolor;
1530 part.UpdateTextureEntry(tex.GetBytes());
1531 return;
1532 }
1533 else if (face == ScriptBaseClass.ALL_SIDES)
1534 {
1535 for (uint i = 0; i < GetNumberOfSides(part); i++)
1536 {
1537 if (tex.FaceTextures[i] != null)
1538 {
1539 texcolor = tex.FaceTextures[i].RGBA;
1540 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1541 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1542 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1543 tex.FaceTextures[i].RGBA = texcolor;
1544 }
1545 texcolor = tex.DefaultTexture.RGBA;
1546 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1547 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1548 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1549 tex.DefaultTexture.RGBA = texcolor;
1550 }
1551 part.UpdateTextureEntry(tex.GetBytes());
1552 return;
1553 }
1554
1382 if (face == ScriptBaseClass.ALL_SIDES) 1555 if (face == ScriptBaseClass.ALL_SIDES)
1383 face = SceneObjectPart.ALL_SIDES; 1556 face = SceneObjectPart.ALL_SIDES;
1384 1557
@@ -1387,6 +1560,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 1560
1388 public void SetTexGen(SceneObjectPart part, int face,int style) 1561 public void SetTexGen(SceneObjectPart part, int face,int style)
1389 { 1562 {
1563 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1564 return;
1565
1390 Primitive.TextureEntry tex = part.Shape.Textures; 1566 Primitive.TextureEntry tex = part.Shape.Textures;
1391 MappingType textype; 1567 MappingType textype;
1392 textype = MappingType.Default; 1568 textype = MappingType.Default;
@@ -1417,6 +1593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 1593
1418 public void SetGlow(SceneObjectPart part, int face, float glow) 1594 public void SetGlow(SceneObjectPart part, int face, float glow)
1419 { 1595 {
1596 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1597 return;
1598
1420 Primitive.TextureEntry tex = part.Shape.Textures; 1599 Primitive.TextureEntry tex = part.Shape.Textures;
1421 if (face >= 0 && face < GetNumberOfSides(part)) 1600 if (face >= 0 && face < GetNumberOfSides(part))
1422 { 1601 {
@@ -1442,6 +1621,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 1621
1443 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1622 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1444 { 1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1445 1626
1446 Shininess sval = new Shininess(); 1627 Shininess sval = new Shininess();
1447 1628
@@ -1492,6 +1673,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 1673
1493 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1674 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1494 { 1675 {
1676 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return;
1678
1495 Primitive.TextureEntry tex = part.Shape.Textures; 1679 Primitive.TextureEntry tex = part.Shape.Textures;
1496 if (face >= 0 && face < GetNumberOfSides(part)) 1680 if (face >= 0 && face < GetNumberOfSides(part))
1497 { 1681 {
@@ -1552,13 +1736,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1552 m_host.AddScriptLPS(1); 1736 m_host.AddScriptLPS(1);
1553 1737
1554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1738 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1555 1739 if (parts.Count > 0)
1556 foreach (SceneObjectPart part in parts) 1740 {
1557 SetAlpha(part, alpha, face); 1741 try
1742 {
1743 parts[0].ParentGroup.areUpdatesSuspended = true;
1744 foreach (SceneObjectPart part in parts)
1745 SetAlpha(part, alpha, face);
1746 }
1747 finally
1748 {
1749 parts[0].ParentGroup.areUpdatesSuspended = false;
1750 }
1751 }
1558 } 1752 }
1559 1753
1560 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1754 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1561 { 1755 {
1756 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1757 return;
1758
1562 Primitive.TextureEntry tex = part.Shape.Textures; 1759 Primitive.TextureEntry tex = part.Shape.Textures;
1563 Color4 texcolor; 1760 Color4 texcolor;
1564 if (face >= 0 && face < GetNumberOfSides(part)) 1761 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1611,7 +1808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1808 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1612 float wind, float tension, LSL_Vector Force) 1809 float wind, float tension, LSL_Vector Force)
1613 { 1810 {
1614 if (part == null) 1811 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1812 return;
1616 1813
1617 if (flexi) 1814 if (flexi)
@@ -1645,7 +1842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1842 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1843 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1844 {
1648 if (part == null) 1845 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1846 return;
1650 1847
1651 if (light) 1848 if (light)
@@ -1678,11 +1875,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1678 Primitive.TextureEntry tex = part.Shape.Textures; 1875 Primitive.TextureEntry tex = part.Shape.Textures;
1679 Color4 texcolor; 1876 Color4 texcolor;
1680 LSL_Vector rgb = new LSL_Vector(); 1877 LSL_Vector rgb = new LSL_Vector();
1878 int nsides = GetNumberOfSides(part);
1879
1681 if (face == ScriptBaseClass.ALL_SIDES) 1880 if (face == ScriptBaseClass.ALL_SIDES)
1682 { 1881 {
1683 int i; 1882 int i;
1684 1883 for (i = 0; i < nsides; i++)
1685 for (i = 0 ; i < GetNumberOfSides(part); i++)
1686 { 1884 {
1687 texcolor = tex.GetFace((uint)i).RGBA; 1885 texcolor = tex.GetFace((uint)i).RGBA;
1688 rgb.x += texcolor.R; 1886 rgb.x += texcolor.R;
@@ -1690,14 +1888,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1690 rgb.z += texcolor.B; 1888 rgb.z += texcolor.B;
1691 } 1889 }
1692 1890
1693 rgb.x /= (float)GetNumberOfSides(part); 1891 float invnsides = 1.0f / (float)nsides;
1694 rgb.y /= (float)GetNumberOfSides(part); 1892
1695 rgb.z /= (float)GetNumberOfSides(part); 1893 rgb.x *= invnsides;
1894 rgb.y *= invnsides;
1895 rgb.z *= invnsides;
1696 1896
1697 return rgb; 1897 return rgb;
1698 } 1898 }
1699 1899 if (face >= 0 && face < nsides)
1700 if (face >= 0 && face < GetNumberOfSides(part))
1701 { 1900 {
1702 texcolor = tex.GetFace((uint)face).RGBA; 1901 texcolor = tex.GetFace((uint)face).RGBA;
1703 rgb.x = texcolor.R; 1902 rgb.x = texcolor.R;
@@ -1724,15 +1923,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 m_host.AddScriptLPS(1); 1923 m_host.AddScriptLPS(1);
1725 1924
1726 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1925 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1727 1926 if (parts.Count > 0)
1728 foreach (SceneObjectPart part in parts) 1927 {
1729 SetTexture(part, texture, face); 1928 try
1730 1929 {
1930 parts[0].ParentGroup.areUpdatesSuspended = true;
1931 foreach (SceneObjectPart part in parts)
1932 SetTexture(part, texture, face);
1933 }
1934 finally
1935 {
1936 parts[0].ParentGroup.areUpdatesSuspended = false;
1937 }
1938 }
1731 ScriptSleep(200); 1939 ScriptSleep(200);
1732 } 1940 }
1733 1941
1734 protected void SetTexture(SceneObjectPart part, string texture, int face) 1942 protected void SetTexture(SceneObjectPart part, string texture, int face)
1735 { 1943 {
1944 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1945 return;
1946
1736 UUID textureID = new UUID(); 1947 UUID textureID = new UUID();
1737 1948
1738 textureID = InventoryKey(texture, (int)AssetType.Texture); 1949 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1777,6 +1988,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1777 1988
1778 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1989 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1779 { 1990 {
1991 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1992 return;
1993
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1994 Primitive.TextureEntry tex = part.Shape.Textures;
1781 if (face >= 0 && face < GetNumberOfSides(part)) 1995 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 1996 {
@@ -1813,6 +2027,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2027
1814 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2028 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2029 {
2030 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2031 return;
2032
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2033 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2034 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2035 {
@@ -1849,6 +2066,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2066
1850 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2067 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1851 { 2068 {
2069 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2070 return;
2071
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2072 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2073 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2074 {
@@ -1953,26 +2173,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 return real_vec; 2173 return real_vec;
1954 } 2174 }
1955 2175
2176 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2177 {
2178 return new LSL_Integer(SetRegionPos(m_host, pos));
2179 }
2180
2181 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2182 {
2183 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2184 return 0;
2185
2186 SceneObjectGroup grp = part.ParentGroup;
2187
2188 if (grp.IsAttachment)
2189 return 0;
2190
2191 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2192 return 0;
2193
2194 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2195 return 0;
2196
2197 float constrainedX = (float)targetPos.x;
2198 float constrainedY = (float)targetPos.y;
2199
2200 if (constrainedX < 0.0f)
2201 constrainedX = 0.0f;
2202 if (constrainedY < 0.0f)
2203 constrainedY = 0.0f;
2204 if (constrainedX >= (float)Constants.RegionSize)
2205 constrainedX = (float)Constants.RegionSize - 0.1f;
2206 if (constrainedY >= (float)Constants.RegionSize)
2207 constrainedY = (float)Constants.RegionSize -0.1f;
2208
2209 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2210
2211 if (targetPos.z < ground)
2212 targetPos.z = ground;
2213
2214 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2215
2216 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2217 return 0;
2218
2219 grp.UpdateGroupPosition(dest);
2220
2221 return 1;
2222 }
2223
1956 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2224 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1957 { 2225 {
1958 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2227 return;
2228
1959 LSL_Vector currentPos = GetPartLocalPos(part); 2229 LSL_Vector currentPos = GetPartLocalPos(part);
2230 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1960 2231
1961 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1962 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1963 2232
1964 if (part.ParentGroup.RootPart == part) 2233 if (part.ParentGroup.RootPart == part)
1965 { 2234 {
1966 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1967 targetPos.z = ground;
1968 SceneObjectGroup parent = part.ParentGroup; 2235 SceneObjectGroup parent = part.ParentGroup;
1969 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2236 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1970 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2237 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2238 return;
2239 Util.FireAndForget(delegate(object x) {
2240 parent.UpdateGroupPosition(dest);
2241 });
1971 } 2242 }
1972 else 2243 else
1973 { 2244 {
1974 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2245 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1975 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1976 SceneObjectGroup parent = part.ParentGroup; 2246 SceneObjectGroup parent = part.ParentGroup;
1977 parent.HasGroupChanged = true; 2247 parent.HasGroupChanged = true;
1978 parent.ScheduleGroupForTerseUpdate(); 2248 parent.ScheduleGroupForTerseUpdate();
@@ -2005,17 +2275,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2005 else 2275 else
2006 { 2276 {
2007 if (part.ParentGroup.IsAttachment) 2277 if (part.ParentGroup.IsAttachment)
2008 {
2009 pos = part.AttachedPos; 2278 pos = part.AttachedPos;
2010 }
2011 else 2279 else
2012 {
2013 pos = part.AbsolutePosition; 2280 pos = part.AbsolutePosition;
2014 }
2015 } 2281 }
2016 2282
2017// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2018
2019 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2283 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2020 } 2284 }
2021 2285
@@ -2024,18 +2288,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 m_host.AddScriptLPS(1); 2288 m_host.AddScriptLPS(1);
2025 2289
2026 // try to let this work as in SL... 2290 // try to let this work as in SL...
2027 if (m_host.ParentID == 0) 2291 if (m_host.LinkNum < 2)
2028 { 2292 {
2029 // special case: If we are root, rotate complete SOG to new rotation 2293 // Special case: If we are root, rotate complete SOG to new
2294 // rotation.
2295 // We are root if the link number is 0 (single prim) or 1
2296 // (root prim). ParentID may be nonzero in attachments and
2297 // using it would cause attachments and HUDs to rotate
2298 // to the wrong positions.
2299
2030 SetRot(m_host, Rot2Quaternion(rot)); 2300 SetRot(m_host, Rot2Quaternion(rot));
2031 } 2301 }
2032 else 2302 else
2033 { 2303 {
2034 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2304 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2035 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2305 SceneObjectPart rootPart;
2036 if (rootPart != null) // better safe than sorry 2306 if (m_host.ParentGroup != null) // better safe than sorry
2037 { 2307 {
2038 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2308 rootPart = m_host.ParentGroup.RootPart;
2309 if (rootPart != null)
2310 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2039 } 2311 }
2040 } 2312 }
2041 2313
@@ -2045,31 +2317,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2045 public void llSetLocalRot(LSL_Rotation rot) 2317 public void llSetLocalRot(LSL_Rotation rot)
2046 { 2318 {
2047 m_host.AddScriptLPS(1); 2319 m_host.AddScriptLPS(1);
2320
2048 SetRot(m_host, Rot2Quaternion(rot)); 2321 SetRot(m_host, Rot2Quaternion(rot));
2049 ScriptSleep(200); 2322 ScriptSleep(200);
2050 } 2323 }
2051 2324
2052 protected void SetRot(SceneObjectPart part, Quaternion rot) 2325 protected void SetRot(SceneObjectPart part, Quaternion rot)
2053 { 2326 {
2054 part.UpdateRotation(rot); 2327 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2055 // Update rotation does not move the object in the physics scene if it's a linkset. 2328 return;
2056 2329
2057//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2330 bool isroot = (part == part.ParentGroup.RootPart);
2058// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2331 bool isphys;
2059 2332
2060 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2061 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2062 // It's perfectly okay when the object is not an active physical body though.
2063 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2064 // but only if the object is not physial and active. This is important for rotating doors.
2065 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2066 // scene
2067 PhysicsActor pa = part.PhysActor; 2333 PhysicsActor pa = part.PhysActor;
2068 2334
2069 if (pa != null && !pa.IsPhysical) 2335 // keep using physactor ideia of isphysical
2336 // it should be SOP ideia of that
2337 // not much of a issue with ubitODE
2338 if (pa != null && pa.IsPhysical)
2339 isphys = true;
2340 else
2341 isphys = false;
2342
2343 // SL doesn't let scripts rotate root of physical linksets
2344 if (isroot && isphys)
2345 return;
2346
2347 part.UpdateRotation(rot);
2348
2349 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2350 // so do a nasty update of parts positions if is a root part rotation
2351 if (isroot && pa != null) // with if above implies non physical root part
2070 { 2352 {
2071 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2353 part.ParentGroup.ResetChildPrimPhysicsPositions();
2072 } 2354 }
2355 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2356 {
2357 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2358 if (sittingavas.Count > 0)
2359 {
2360 foreach (ScenePresence av in sittingavas)
2361 {
2362 if (isroot || part.LocalId == av.ParentID)
2363 av.SendTerseUpdateToAllClients();
2364 }
2365 }
2366 }
2073 } 2367 }
2074 2368
2075 /// <summary> 2369 /// <summary>
@@ -2118,7 +2412,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2118 public LSL_Rotation llGetLocalRot() 2412 public LSL_Rotation llGetLocalRot()
2119 { 2413 {
2120 m_host.AddScriptLPS(1); 2414 m_host.AddScriptLPS(1);
2121 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2415 Quaternion rot = m_host.RotationOffset;
2416 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2122 } 2417 }
2123 2418
2124 public void llSetForce(LSL_Vector force, int local) 2419 public void llSetForce(LSL_Vector force, int local)
@@ -2202,16 +2497,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2202 m_host.ApplyImpulse(v, local != 0); 2497 m_host.ApplyImpulse(v, local != 0);
2203 } 2498 }
2204 2499
2500
2205 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2501 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2206 { 2502 {
2207 m_host.AddScriptLPS(1); 2503 m_host.AddScriptLPS(1);
2208 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2504 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2209 } 2505 }
2210 2506
2211 public void llSetTorque(LSL_Vector torque, int local) 2507 public void llSetTorque(LSL_Vector torque, int local)
2212 { 2508 {
2213 m_host.AddScriptLPS(1); 2509 m_host.AddScriptLPS(1);
2214 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2510 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2215 } 2511 }
2216 2512
2217 public LSL_Vector llGetTorque() 2513 public LSL_Vector llGetTorque()
@@ -2228,20 +2524,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2228 llSetTorque(torque, local); 2524 llSetTorque(torque, local);
2229 } 2525 }
2230 2526
2527 public void llSetVelocity(LSL_Vector vel, int local)
2528 {
2529 m_host.AddScriptLPS(1);
2530 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2531 }
2532
2231 public LSL_Vector llGetVel() 2533 public LSL_Vector llGetVel()
2232 { 2534 {
2233 m_host.AddScriptLPS(1); 2535 m_host.AddScriptLPS(1);
2234 2536
2235 Vector3 vel; 2537 Vector3 vel = Vector3.Zero;
2236 2538
2237 if (m_host.ParentGroup.IsAttachment) 2539 if (m_host.ParentGroup.IsAttachment)
2238 { 2540 {
2239 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2541 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2240 vel = avatar.Velocity; 2542 if (avatar != null)
2543 vel = avatar.Velocity;
2241 } 2544 }
2242 else 2545 else
2243 { 2546 {
2244 vel = m_host.Velocity; 2547 vel = m_host.ParentGroup.RootPart.Velocity;
2245 } 2548 }
2246 2549
2247 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2550 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2253,10 +2556,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2253 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2556 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2254 } 2557 }
2255 2558
2559
2560 public void llSetAngularVelocity(LSL_Vector avel, int local)
2561 {
2562 m_host.AddScriptLPS(1);
2563 // Still not done !!!!
2564// m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2565 }
2566
2256 public LSL_Vector llGetOmega() 2567 public LSL_Vector llGetOmega()
2257 { 2568 {
2258 m_host.AddScriptLPS(1); 2569 m_host.AddScriptLPS(1);
2259 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2570 Vector3 avel = m_host.AngularVelocity;
2571 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2260 } 2572 }
2261 2573
2262 public LSL_Float llGetTimeOfDay() 2574 public LSL_Float llGetTimeOfDay()
@@ -2785,16 +3097,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2785 new_group.RootPart.UUID.ToString()) }, 3097 new_group.RootPart.UUID.ToString()) },
2786 new DetectParams[0])); 3098 new DetectParams[0]));
2787 3099
2788 float groupmass = new_group.GetMass(); 3100 // do recoil
3101 SceneObjectGroup hostgrp = m_host.ParentGroup;
3102 if (hostgrp == null)
3103 return;
3104
3105 if (hostgrp.IsAttachment) // don't recoil avatars
3106 return;
2789 3107
2790 PhysicsActor pa = new_group.RootPart.PhysActor; 3108 PhysicsActor pa = new_group.RootPart.PhysActor;
2791 3109
2792 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3110 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2793 { 3111 {
2794 //Recoil. 3112 float groupmass = new_group.GetMass();
2795 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3113 llvel *= -groupmass;
3114 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2796 } 3115 }
2797 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3116 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3117 return;
3118
2798 }); 3119 });
2799 3120
2800 //ScriptSleep((int)((groupmass * velmag) / 10)); 3121 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2809,35 +3130,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2809 public void llLookAt(LSL_Vector target, double strength, double damping) 3130 public void llLookAt(LSL_Vector target, double strength, double damping)
2810 { 3131 {
2811 m_host.AddScriptLPS(1); 3132 m_host.AddScriptLPS(1);
2812 // Determine where we are looking from
2813 LSL_Vector from = llGetPos();
2814 3133
2815 // Work out the normalised vector from the source to the target 3134 // Get the normalized vector to the target
2816 LSL_Vector delta = llVecNorm(target - from); 3135 LSL_Vector d1 = llVecNorm(target - llGetPos());
2817 LSL_Vector angle = new LSL_Vector(0,0,0);
2818 3136
2819 // Calculate the yaw 3137 // Get the bearing (yaw)
2820 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3138 LSL_Vector a1 = new LSL_Vector(0,0,0);
2821 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3139 a1.z = llAtan2(d1.y, d1.x);
2822 3140
2823 // Calculate pitch 3141 // Get the elevation (pitch)
2824 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3142 LSL_Vector a2 = new LSL_Vector(0,0,0);
3143 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2825 3144
2826 // we need to convert from a vector describing 3145 LSL_Rotation r1 = llEuler2Rot(a1);
2827 // the angles of rotation in radians into rotation value 3146 LSL_Rotation r2 = llEuler2Rot(a2);
2828 LSL_Rotation rot = llEuler2Rot(angle); 3147 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2829
2830 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2831 // set the rotation of the object, copy that behavior
2832 PhysicsActor pa = m_host.PhysActor;
2833 3148
2834 if (strength == 0 || pa == null || !pa.IsPhysical) 3149 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2835 { 3150 {
2836 llSetRot(rot); 3151 // Do nothing if either value is 0 (this has been checked in SL)
3152 if (strength <= 0.0 || damping <= 0.0)
3153 return;
3154
3155 llSetRot(r3 * r2 * r1);
2837 } 3156 }
2838 else 3157 else
2839 { 3158 {
2840 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3159 if (strength == 0)
3160 {
3161 llSetRot(r3 * r2 * r1);
3162 return;
3163 }
3164
3165 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2841 } 3166 }
2842 } 3167 }
2843 3168
@@ -2883,17 +3208,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2883 } 3208 }
2884 else 3209 else
2885 { 3210 {
2886 if (m_host.IsRoot) 3211 // new SL always returns object mass
2887 { 3212// if (m_host.IsRoot)
3213// {
2888 return m_host.ParentGroup.GetMass(); 3214 return m_host.ParentGroup.GetMass();
2889 } 3215// }
2890 else 3216// else
2891 { 3217// {
2892 return m_host.GetMass(); 3218// return m_host.GetMass();
2893 } 3219// }
2894 } 3220 }
2895 } 3221 }
2896 3222
3223
3224 public LSL_Float llGetMassMKS()
3225 {
3226 return 100f * llGetMass();
3227 }
3228
2897 public void llCollisionFilter(string name, string id, int accept) 3229 public void llCollisionFilter(string name, string id, int accept)
2898 { 3230 {
2899 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
@@ -2968,7 +3300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2968 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3300 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2969 3301
2970 if (attachmentsModule != null) 3302 if (attachmentsModule != null)
2971 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3303 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
2972 else 3304 else
2973 return false; 3305 return false;
2974 } 3306 }
@@ -2998,9 +3330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2998 { 3330 {
2999 m_host.AddScriptLPS(1); 3331 m_host.AddScriptLPS(1);
3000 3332
3001// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3002// return;
3003
3004 if (m_item.PermsGranter != m_host.OwnerID) 3333 if (m_item.PermsGranter != m_host.OwnerID)
3005 return; 3334 return;
3006 3335
@@ -3043,6 +3372,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3043 3372
3044 public void llInstantMessage(string user, string message) 3373 public void llInstantMessage(string user, string message)
3045 { 3374 {
3375 UUID result;
3376 if (!UUID.TryParse(user, out result))
3377 {
3378 ShoutError("An invalid key was passed to llInstantMessage");
3379 ScriptSleep(2000);
3380 return;
3381 }
3382
3383
3046 m_host.AddScriptLPS(1); 3384 m_host.AddScriptLPS(1);
3047 3385
3048 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3386 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3057,14 +3395,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 UUID friendTransactionID = UUID.Random(); 3395 UUID friendTransactionID = UUID.Random();
3058 3396
3059 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3397 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3060 3398
3061 GridInstantMessage msg = new GridInstantMessage(); 3399 GridInstantMessage msg = new GridInstantMessage();
3062 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3400 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3063 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3401 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3064 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3402 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3065// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3403// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3066// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3404// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3067 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3405// DateTime dt = DateTime.UtcNow;
3406//
3407// // Ticks from UtcNow, but make it look like local. Evil, huh?
3408// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3409//
3410// try
3411// {
3412// // Convert that to the PST timezone
3413// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3414// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3415// }
3416// catch
3417// {
3418// // No logging here, as it could be VERY spammy
3419// }
3420//
3421// // And make it look local again to fool the unix time util
3422// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3423
3424 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3425
3068 //if (client != null) 3426 //if (client != null)
3069 //{ 3427 //{
3070 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3428 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3078,12 +3436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3078 msg.message = message.Substring(0, 1024); 3436 msg.message = message.Substring(0, 1024);
3079 else 3437 else
3080 msg.message = message; 3438 msg.message = message;
3081 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3439 msg.dialog = (byte)19; // MessageFromObject
3082 msg.fromGroup = false;// fromGroup; 3440 msg.fromGroup = false;// fromGroup;
3083 msg.offline = (byte)0; //offline; 3441 msg.offline = (byte)0; //offline;
3084 msg.ParentEstateID = 0; //ParentEstateID; 3442 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3085 msg.Position = new Vector3(m_host.AbsolutePosition); 3443 msg.Position = new Vector3(m_host.AbsolutePosition);
3086 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3444 msg.RegionID = World.RegionInfo.RegionID.Guid;
3087 msg.binaryBucket 3445 msg.binaryBucket
3088 = Util.StringToBytes256( 3446 = Util.StringToBytes256(
3089 "{0}/{1}/{2}/{3}", 3447 "{0}/{1}/{2}/{3}",
@@ -3111,7 +3469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 } 3469 }
3112 3470
3113 emailModule.SendEmail(m_host.UUID, address, subject, message); 3471 emailModule.SendEmail(m_host.UUID, address, subject, message);
3114 llSleep(EMAIL_PAUSE_TIME); 3472 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3115 } 3473 }
3116 3474
3117 public void llGetNextEmail(string address, string subject) 3475 public void llGetNextEmail(string address, string subject)
@@ -3355,15 +3713,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3355 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3713 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3356 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3714 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3357 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3715 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3716 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3358 ScriptBaseClass.PERMISSION_ATTACH; 3717 ScriptBaseClass.PERMISSION_ATTACH;
3359 3718
3360 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3719 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3361 { 3720 {
3362 lock (m_host.TaskInventory) 3721 m_host.TaskInventory.LockItemsForWrite(true);
3363 { 3722 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3364 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3723 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3365 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3724 m_host.TaskInventory.LockItemsForWrite(false);
3366 }
3367 3725
3368 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3726 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3369 "run_time_permissions", new Object[] { 3727 "run_time_permissions", new Object[] {
@@ -3373,28 +3731,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 return; 3731 return;
3374 } 3732 }
3375 } 3733 }
3376 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3734 else
3377 { 3735 {
3378 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3736 bool sitting = false;
3379 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3737 if (m_host.SitTargetAvatar == agentID)
3380 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3738 {
3381 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3739 sitting = true;
3382 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3740 }
3741 else
3742 {
3743 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3744 {
3745 if (p.SitTargetAvatar == agentID)
3746 sitting = true;
3747 }
3748 }
3383 3749
3384 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3750 if (sitting)
3385 { 3751 {
3386 lock (m_host.TaskInventory) 3752 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3753 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3754 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3755 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3756 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3757
3758 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3387 { 3759 {
3760 m_host.TaskInventory.LockItemsForWrite(true);
3388 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3761 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3389 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3762 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3390 } 3763 m_host.TaskInventory.LockItemsForWrite(false);
3391 3764
3392 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3765 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3393 "run_time_permissions", new Object[] { 3766 "run_time_permissions", new Object[] {
3394 new LSL_Integer(perm) }, 3767 new LSL_Integer(perm) },
3395 new DetectParams[0])); 3768 new DetectParams[0]));
3396 3769
3397 return; 3770 return;
3771 }
3398 } 3772 }
3399 } 3773 }
3400 3774
@@ -3431,11 +3805,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3431 3805
3432 if (!m_waitingForScriptAnswer) 3806 if (!m_waitingForScriptAnswer)
3433 { 3807 {
3434 lock (m_host.TaskInventory) 3808 m_host.TaskInventory.LockItemsForWrite(true);
3435 { 3809 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3436 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3810 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3437 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3811 m_host.TaskInventory.LockItemsForWrite(false);
3438 }
3439 3812
3440 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3813 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3441 m_waitingForScriptAnswer=true; 3814 m_waitingForScriptAnswer=true;
@@ -3464,14 +3837,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3464 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3837 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3465 llReleaseControls(); 3838 llReleaseControls();
3466 3839
3467 lock (m_host.TaskInventory) 3840 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3841 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3469 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3842 m_host.TaskInventory.LockItemsForWrite(false);
3470 } 3843
3471 3844 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3472 m_ScriptEngine.PostScriptEvent( 3845 "run_time_permissions", new Object[] {
3473 m_item.ItemID, 3846 new LSL_Integer(answer) },
3474 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3847 new DetectParams[0]));
3475 } 3848 }
3476 3849
3477 public LSL_String llGetPermissionsKey() 3850 public LSL_String llGetPermissionsKey()
@@ -3510,14 +3883,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3510 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3883 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3511 { 3884 {
3512 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3885 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3513 3886 if (parts.Count > 0)
3514 foreach (SceneObjectPart part in parts) 3887 {
3515 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3888 try
3889 {
3890 parts[0].ParentGroup.areUpdatesSuspended = true;
3891 foreach (SceneObjectPart part in parts)
3892 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3893 }
3894 finally
3895 {
3896 parts[0].ParentGroup.areUpdatesSuspended = false;
3897 }
3898 }
3516 } 3899 }
3517 3900
3518 public void llCreateLink(string target, int parent) 3901 public void llCreateLink(string target, int parent)
3519 { 3902 {
3520 m_host.AddScriptLPS(1); 3903 m_host.AddScriptLPS(1);
3904
3521 UUID targetID; 3905 UUID targetID;
3522 3906
3523 if (!UUID.TryParse(target, out targetID)) 3907 if (!UUID.TryParse(target, out targetID))
@@ -3623,10 +4007,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3623 // Restructuring Multiple Prims. 4007 // Restructuring Multiple Prims.
3624 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4008 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3625 parts.Remove(parentPrim.RootPart); 4009 parts.Remove(parentPrim.RootPart);
3626 foreach (SceneObjectPart part in parts) 4010 if (parts.Count > 0)
3627 { 4011 {
3628 parentPrim.DelinkFromGroup(part.LocalId, true); 4012 try
4013 {
4014 parts[0].ParentGroup.areUpdatesSuspended = true;
4015 foreach (SceneObjectPart part in parts)
4016 {
4017 parentPrim.DelinkFromGroup(part.LocalId, true);
4018 }
4019 }
4020 finally
4021 {
4022 parts[0].ParentGroup.areUpdatesSuspended = false;
4023 }
3629 } 4024 }
4025
3630 parentPrim.HasGroupChanged = true; 4026 parentPrim.HasGroupChanged = true;
3631 parentPrim.ScheduleGroupForFullUpdate(); 4027 parentPrim.ScheduleGroupForFullUpdate();
3632 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4028 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3635,12 +4031,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3635 { 4031 {
3636 SceneObjectPart newRoot = parts[0]; 4032 SceneObjectPart newRoot = parts[0];
3637 parts.Remove(newRoot); 4033 parts.Remove(newRoot);
3638 foreach (SceneObjectPart part in parts) 4034
4035 try
3639 { 4036 {
3640 // Required for linking 4037 parts[0].ParentGroup.areUpdatesSuspended = true;
3641 part.ClearUpdateSchedule(); 4038 foreach (SceneObjectPart part in parts)
3642 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4039 {
4040 part.ClearUpdateSchedule();
4041 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4042 }
3643 } 4043 }
4044 finally
4045 {
4046 parts[0].ParentGroup.areUpdatesSuspended = false;
4047 }
4048
4049
3644 newRoot.ParentGroup.HasGroupChanged = true; 4050 newRoot.ParentGroup.HasGroupChanged = true;
3645 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4051 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3646 } 4052 }
@@ -3660,6 +4066,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3660 public void llBreakAllLinks() 4066 public void llBreakAllLinks()
3661 { 4067 {
3662 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
4069
4070 TaskInventoryItem item = m_item;
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3663 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3664 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3665 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3679,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3679 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3680 { 4096 {
3681 m_host.AddScriptLPS(1); 4097 m_host.AddScriptLPS(1);
3682 List<UUID> keytable = new List<UUID>();
3683 // parse for sitting avatare-uuids
3684 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3685 {
3686 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3687 keytable.Add(presence.UUID);
3688 });
3689
3690 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3691 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3692 {
3693 return keytable[totalprims - linknum].ToString();
3694 }
3695
3696 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3697 {
3698 return m_host.UUID.ToString();
3699 }
3700
3701 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3702 if (part != null) 4099 if (part != null)
3703 { 4100 {
@@ -3705,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 } 4102 }
3706 else 4103 else
3707 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3708 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3709 } 4119 }
3710 } 4120 }
@@ -3804,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3805 int count = 0; 4215 int count = 0;
3806 4216
3807 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3808 { 4219 {
3809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3810 { 4221 {
3811 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3812 {
3813 count = count + 1;
3814 }
3815 } 4223 }
3816 } 4224 }
3817 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3818 return count; 4227 return count;
3819 } 4228 }
3820 4229
@@ -3823,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3823 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3824 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3825 4234
3826 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3827 { 4237 {
3828 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3829 { 4239 {
3830 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3831 {
3832 keys.Add(inv.Value.Name);
3833 }
3834 } 4241 }
3835 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3836 4244
3837 if (keys.Count == 0) 4245 if (keys.Count == 0)
3838 { 4246 {
@@ -3870,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3870 if (item == null) 4278 if (item == null)
3871 { 4279 {
3872 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3873 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3874 } 4283 }
3875 4284
3876 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3898,34 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3898 return; 4307 return;
3899 } 4308 }
3900 } 4309 }
4310
3901 // destination is an avatar 4311 // destination is an avatar
3902 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3903 4313
3904 if (agentItem == null) 4314 if (agentItem == null)
3905 return; 4315 return;
3906 4316
3907 byte[] bucket = new byte[17]; 4317 byte[] bucket = new byte[1];
3908 bucket[0] = (byte)item.Type; 4318 bucket[0] = (byte)item.Type;
3909 byte[] objBytes = agentItem.ID.GetBytes(); 4319 //byte[] objBytes = agentItem.ID.GetBytes();
3910 Array.Copy(objBytes, 0, bucket, 1, 16); 4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
3911 4321
3912 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
3913 m_host.UUID, m_host.Name + ", an object owned by " + 4323 m_host.OwnerID, m_host.Name, destId,
3914 resolveName(m_host.OwnerID) + ",", destId,
3915 (byte)InstantMessageDialog.TaskInventoryOffered, 4324 (byte)InstantMessageDialog.TaskInventoryOffered,
3916 false, item.Name + "\n" + m_host.Name + " is located at " + 4325 false, item.Name+". "+m_host.Name+" is located at "+
3917 World.RegionInfo.RegionName+" "+ 4326 World.RegionInfo.RegionName+" "+
3918 m_host.AbsolutePosition.ToString(), 4327 m_host.AbsolutePosition.ToString(),
3919 agentItem.ID, true, m_host.AbsolutePosition, 4328 agentItem.ID, true, m_host.AbsolutePosition,
3920 bucket); 4329 bucket);
3921 4330
3922 if (m_TransferModule != null) 4331 ScenePresence sp;
3923 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3924 4332
4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
4336 }
4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3925 ScriptSleep(3000); 4344 ScriptSleep(3000);
3926 } 4345 }
3927 } 4346 }
3928 4347
4348 [DebuggerNonUserCode]
3929 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3930 { 4350 {
3931 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -3971,109 +4391,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 { 4391 {
3972 m_host.AddScriptLPS(1); 4392 m_host.AddScriptLPS(1);
3973 4393
3974 UUID uuid = (UUID)id; 4394 UUID uuid;
3975 PresenceInfo pinfo = null; 4395 if (UUID.TryParse(id, out uuid))
3976 UserAccount account;
3977
3978 UserInfoCacheEntry ce;
3979 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3980 { 4396 {
3981 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4397 PresenceInfo pinfo = null;
3982 if (account == null) 4398 UserAccount account;
4399
4400 UserInfoCacheEntry ce;
4401 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3983 { 4402 {
3984 m_userInfoCache[uuid] = null; // Cache negative 4403 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3985 return UUID.Zero.ToString(); 4404 if (account == null)
3986 } 4405 {
4406 m_userInfoCache[uuid] = null; // Cache negative
4407 return UUID.Zero.ToString();
4408 }
3987 4409
3988 4410
3989 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4411 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3990 if (pinfos != null && pinfos.Length > 0) 4412 if (pinfos != null && pinfos.Length > 0)
3991 {
3992 foreach (PresenceInfo p in pinfos)
3993 { 4413 {
3994 if (p.RegionID != UUID.Zero) 4414 foreach (PresenceInfo p in pinfos)
3995 { 4415 {
3996 pinfo = p; 4416 if (p.RegionID != UUID.Zero)
4417 {
4418 pinfo = p;
4419 }
3997 } 4420 }
3998 } 4421 }
3999 }
4000 4422
4001 ce = new UserInfoCacheEntry(); 4423 ce = new UserInfoCacheEntry();
4002 ce.time = Util.EnvironmentTickCount(); 4424 ce.time = Util.EnvironmentTickCount();
4003 ce.account = account; 4425 ce.account = account;
4004 ce.pinfo = pinfo; 4426 ce.pinfo = pinfo;
4005 } 4427 m_userInfoCache[uuid] = ce;
4006 else 4428 }
4007 { 4429 else
4008 if (ce == null) 4430 {
4009 return UUID.Zero.ToString(); 4431 if (ce == null)
4432 return UUID.Zero.ToString();
4010 4433
4011 account = ce.account; 4434 account = ce.account;
4012 pinfo = ce.pinfo; 4435 pinfo = ce.pinfo;
4013 } 4436 }
4014 4437
4015 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4438 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4016 {
4017 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4018 if (pinfos != null && pinfos.Length > 0)
4019 { 4439 {
4020 foreach (PresenceInfo p in pinfos) 4440 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4441 if (pinfos != null && pinfos.Length > 0)
4021 { 4442 {
4022 if (p.RegionID != UUID.Zero) 4443 foreach (PresenceInfo p in pinfos)
4023 { 4444 {
4024 pinfo = p; 4445 if (p.RegionID != UUID.Zero)
4446 {
4447 pinfo = p;
4448 }
4025 } 4449 }
4026 } 4450 }
4027 } 4451 else
4028 else 4452 pinfo = null;
4029 pinfo = null;
4030 4453
4031 ce.time = Util.EnvironmentTickCount(); 4454 ce.time = Util.EnvironmentTickCount();
4032 ce.pinfo = pinfo; 4455 ce.pinfo = pinfo;
4033 } 4456 }
4034 4457
4035 string reply = String.Empty; 4458 string reply = String.Empty;
4036 4459
4037 switch (data) 4460 switch (data)
4038 { 4461 {
4039 case 1: // DATA_ONLINE (0|1) 4462 case 1: // DATA_ONLINE (0|1)
4040 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4463 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4041 reply = "1"; 4464 reply = "1";
4042 else 4465 else
4043 reply = "0"; 4466 reply = "0";
4044 break; 4467 break;
4045 case 2: // DATA_NAME (First Last) 4468 case 2: // DATA_NAME (First Last)
4046 reply = account.FirstName + " " + account.LastName; 4469 reply = account.FirstName + " " + account.LastName;
4047 break; 4470 break;
4048 case 3: // DATA_BORN (YYYY-MM-DD) 4471 case 3: // DATA_BORN (YYYY-MM-DD)
4049 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4472 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4050 born = born.AddSeconds(account.Created); 4473 born = born.AddSeconds(account.Created);
4051 reply = born.ToString("yyyy-MM-dd"); 4474 reply = born.ToString("yyyy-MM-dd");
4052 break; 4475 break;
4053 case 4: // DATA_RATING (0,0,0,0,0,0) 4476 case 4: // DATA_RATING (0,0,0,0,0,0)
4054 reply = "0,0,0,0,0,0"; 4477 reply = "0,0,0,0,0,0";
4055 break; 4478 break;
4056 case 7: // DATA_USERLEVEL (integer) 4479 case 8: // DATA_PAYINFO (0|1|2|3)
4057 reply = account.UserLevel.ToString(); 4480 reply = "0";
4058 break; 4481 break;
4059 case 8: // DATA_PAYINFO (0|1|2|3) 4482 default:
4060 reply = "0"; 4483 return UUID.Zero.ToString(); // Raise no event
4061 break; 4484 }
4062 default:
4063 return UUID.Zero.ToString(); // Raise no event
4064 }
4065 4485
4066 UUID rq = UUID.Random(); 4486 UUID rq = UUID.Random();
4067 4487
4068 UUID tid = AsyncCommands. 4488 UUID tid = AsyncCommands.
4069 DataserverPlugin.RegisterRequest(m_host.LocalId, 4489 DataserverPlugin.RegisterRequest(m_host.LocalId,
4070 m_item.ItemID, rq.ToString()); 4490 m_item.ItemID, rq.ToString());
4071 4491
4072 AsyncCommands. 4492 AsyncCommands.
4073 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4493 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4074 4494
4075 ScriptSleep(100); 4495 ScriptSleep(100);
4076 return tid.ToString(); 4496 return tid.ToString();
4497 }
4498 else
4499 {
4500 ShoutError("Invalid UUID passed to llRequestAgentData.");
4501 }
4502 return "";
4077 } 4503 }
4078 4504
4079 public LSL_String llRequestInventoryData(string name) 4505 public LSL_String llRequestInventoryData(string name)
@@ -4130,13 +4556,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4130 if (UUID.TryParse(agent, out agentId)) 4556 if (UUID.TryParse(agent, out agentId))
4131 { 4557 {
4132 ScenePresence presence = World.GetScenePresence(agentId); 4558 ScenePresence presence = World.GetScenePresence(agentId);
4133 if (presence != null) 4559 if (presence != null && presence.PresenceType != PresenceType.Npc)
4134 { 4560 {
4561 // agent must not be a god
4562 if (presence.UserLevel >= 200) return;
4563
4135 // agent must be over the owners land 4564 // agent must be over the owners land
4136 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4565 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4137 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4566 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4138 { 4567 {
4139 World.TeleportClientHome(agentId, presence.ControllingClient); 4568 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4569 {
4570 // They can't be teleported home for some reason
4571 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4572 if (regionInfo != null)
4573 {
4574 World.RequestTeleportLocation(
4575 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4576 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4577 }
4578 }
4140 } 4579 }
4141 } 4580 }
4142 } 4581 }
@@ -4248,7 +4687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4248 UUID av = new UUID(); 4687 UUID av = new UUID();
4249 if (!UUID.TryParse(agent,out av)) 4688 if (!UUID.TryParse(agent,out av))
4250 { 4689 {
4251 LSLError("First parameter to llDialog needs to be a key"); 4690 //LSLError("First parameter to llDialog needs to be a key");
4252 return; 4691 return;
4253 } 4692 }
4254 4693
@@ -4280,7 +4719,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 public void llCollisionSound(string impact_sound, double impact_volume) 4719 public void llCollisionSound(string impact_sound, double impact_volume)
4281 { 4720 {
4282 m_host.AddScriptLPS(1); 4721 m_host.AddScriptLPS(1);
4283 4722
4723 if(impact_sound == "")
4724 {
4725 m_host.CollisionSoundVolume = (float)impact_volume;
4726 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4727 m_host.CollisionSoundType = 0;
4728 return;
4729 }
4284 // TODO: Parameter check logic required. 4730 // TODO: Parameter check logic required.
4285 UUID soundId = UUID.Zero; 4731 UUID soundId = UUID.Zero;
4286 if (!UUID.TryParse(impact_sound, out soundId)) 4732 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4293,6 +4739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4293 4739
4294 m_host.CollisionSound = soundId; 4740 m_host.CollisionSound = soundId;
4295 m_host.CollisionSoundVolume = (float)impact_volume; 4741 m_host.CollisionSoundVolume = (float)impact_volume;
4742 m_host.CollisionSoundType = 1;
4296 } 4743 }
4297 4744
4298 public LSL_String llGetAnimation(string id) 4745 public LSL_String llGetAnimation(string id)
@@ -4306,14 +4753,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4306 4753
4307 if (m_host.RegionHandle == presence.RegionHandle) 4754 if (m_host.RegionHandle == presence.RegionHandle)
4308 { 4755 {
4309 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4310
4311 if (presence != null) 4756 if (presence != null)
4312 { 4757 {
4313 AnimationSet currentAnims = presence.Animator.Animations; 4758 if (presence.SitGround)
4314 string currentAnimationState = String.Empty; 4759 return "Sitting on Ground";
4315 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4760 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4316 return currentAnimationState; 4761 return "Sitting";
4762
4763 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4764 string lslMovementAnimation;
4765
4766 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4767 return lslMovementAnimation;
4317 } 4768 }
4318 } 4769 }
4319 4770
@@ -4460,7 +4911,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4460 { 4911 {
4461 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4912 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4462 float distance_term = distance * distance * distance; // Script Energy 4913 float distance_term = distance * distance * distance; // Script Energy
4463 float pusher_mass = m_host.GetMass(); 4914 // use total object mass and not part
4915 float pusher_mass = m_host.ParentGroup.GetMass();
4464 4916
4465 float PUSH_ATTENUATION_DISTANCE = 17f; 4917 float PUSH_ATTENUATION_DISTANCE = 17f;
4466 float PUSH_ATTENUATION_SCALE = 5f; 4918 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4710,6 +5162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4710 { 5162 {
4711 return item.AssetID.ToString(); 5163 return item.AssetID.ToString();
4712 } 5164 }
5165 m_host.TaskInventory.LockItemsForRead(false);
4713 5166
4714 return UUID.Zero.ToString(); 5167 return UUID.Zero.ToString();
4715 } 5168 }
@@ -4843,7 +5296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4843 public LSL_Vector llGetCenterOfMass() 5296 public LSL_Vector llGetCenterOfMass()
4844 { 5297 {
4845 m_host.AddScriptLPS(1); 5298 m_host.AddScriptLPS(1);
4846 Vector3 center = m_host.GetGeometricCenter(); 5299 Vector3 center = m_host.GetCenterOfMass();
4847 return new LSL_Vector(center.X,center.Y,center.Z); 5300 return new LSL_Vector(center.X,center.Y,center.Z);
4848 } 5301 }
4849 5302
@@ -4862,14 +5315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4862 { 5315 {
4863 m_host.AddScriptLPS(1); 5316 m_host.AddScriptLPS(1);
4864 5317
4865 if (src == null) 5318 return src.Length;
4866 {
4867 return 0;
4868 }
4869 else
4870 {
4871 return src.Length;
4872 }
4873 } 5319 }
4874 5320
4875 public LSL_Integer llList2Integer(LSL_List src, int index) 5321 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4915,7 +5361,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4915 else if (src.Data[index] is LSL_Float) 5361 else if (src.Data[index] is LSL_Float)
4916 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5362 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4917 else if (src.Data[index] is LSL_String) 5363 else if (src.Data[index] is LSL_String)
4918 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5364 {
5365 string str = ((LSL_String) src.Data[index]).m_string;
5366 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5367 if (m != Match.Empty)
5368 {
5369 str = m.Value;
5370 double d = 0.0;
5371 if (!Double.TryParse(str, out d))
5372 return 0.0;
5373
5374 return d;
5375 }
5376 return 0.0;
5377 }
4919 return Convert.ToDouble(src.Data[index]); 5378 return Convert.ToDouble(src.Data[index]);
4920 } 5379 }
4921 catch (FormatException) 5380 catch (FormatException)
@@ -5188,7 +5647,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5188 } 5647 }
5189 } 5648 }
5190 } 5649 }
5191 else { 5650 else
5651 {
5192 object[] array = new object[src.Length]; 5652 object[] array = new object[src.Length];
5193 Array.Copy(src.Data, 0, array, 0, src.Length); 5653 Array.Copy(src.Data, 0, array, 0, src.Length);
5194 result = new LSL_List(array); 5654 result = new LSL_List(array);
@@ -5295,7 +5755,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5295 public LSL_Integer llGetRegionAgentCount() 5755 public LSL_Integer llGetRegionAgentCount()
5296 { 5756 {
5297 m_host.AddScriptLPS(1); 5757 m_host.AddScriptLPS(1);
5298 return new LSL_Integer(World.GetRootAgentCount()); 5758
5759 int count = 0;
5760 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5761 count++;
5762 });
5763
5764 return new LSL_Integer(count);
5299 } 5765 }
5300 5766
5301 public LSL_Vector llGetRegionCorner() 5767 public LSL_Vector llGetRegionCorner()
@@ -5575,6 +6041,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5575 flags |= ScriptBaseClass.AGENT_SITTING; 6041 flags |= ScriptBaseClass.AGENT_SITTING;
5576 } 6042 }
5577 6043
6044 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6045 {
6046 flags |= ScriptBaseClass.AGENT_MALE;
6047 }
6048
5578 return flags; 6049 return flags;
5579 } 6050 }
5580 6051
@@ -5721,10 +6192,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5721 m_host.AddScriptLPS(1); 6192 m_host.AddScriptLPS(1);
5722 6193
5723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6194 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5724 6195 if (parts.Count > 0)
5725 foreach (var part in parts)
5726 { 6196 {
5727 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6197 try
6198 {
6199 parts[0].ParentGroup.areUpdatesSuspended = true;
6200 foreach (var part in parts)
6201 {
6202 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6203 }
6204 }
6205 finally
6206 {
6207 parts[0].ParentGroup.areUpdatesSuspended = false;
6208 }
5728 } 6209 }
5729 } 6210 }
5730 6211
@@ -5776,13 +6257,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5776 6257
5777 if (m_host.OwnerID == land.LandData.OwnerID) 6258 if (m_host.OwnerID == land.LandData.OwnerID)
5778 { 6259 {
5779 World.TeleportClientHome(agentID, presence.ControllingClient); 6260 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6261 presence.TeleportWithMomentum(pos, null);
6262 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5780 } 6263 }
5781 } 6264 }
5782 } 6265 }
5783 ScriptSleep(5000); 6266 ScriptSleep(5000);
5784 } 6267 }
5785 6268
6269 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6270 {
6271 return ParseString2List(str, separators, in_spacers, false);
6272 }
6273
5786 public LSL_Integer llOverMyLand(string id) 6274 public LSL_Integer llOverMyLand(string id)
5787 { 6275 {
5788 m_host.AddScriptLPS(1); 6276 m_host.AddScriptLPS(1);
@@ -5847,8 +6335,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5847 UUID agentId = new UUID(); 6335 UUID agentId = new UUID();
5848 if (!UUID.TryParse(agent, out agentId)) 6336 if (!UUID.TryParse(agent, out agentId))
5849 return new LSL_Integer(0); 6337 return new LSL_Integer(0);
6338 if (agentId == m_host.GroupID)
6339 return new LSL_Integer(1);
5850 ScenePresence presence = World.GetScenePresence(agentId); 6340 ScenePresence presence = World.GetScenePresence(agentId);
5851 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6341 if (presence == null || presence.IsChildAgent) // Return false for child agents
5852 return new LSL_Integer(0); 6342 return new LSL_Integer(0);
5853 IClientAPI client = presence.ControllingClient; 6343 IClientAPI client = presence.ControllingClient;
5854 if (m_host.GroupID == client.ActiveGroupId) 6344 if (m_host.GroupID == client.ActiveGroupId)
@@ -5983,7 +6473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5983 return m_host.ParentGroup.AttachmentPoint; 6473 return m_host.ParentGroup.AttachmentPoint;
5984 } 6474 }
5985 6475
5986 public LSL_Integer llGetFreeMemory() 6476 public virtual LSL_Integer llGetFreeMemory()
5987 { 6477 {
5988 m_host.AddScriptLPS(1); 6478 m_host.AddScriptLPS(1);
5989 // Make scripts designed for LSO happy 6479 // Make scripts designed for LSO happy
@@ -6100,7 +6590,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6100 SetParticleSystem(m_host, rules); 6590 SetParticleSystem(m_host, rules);
6101 } 6591 }
6102 6592
6103 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6593 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6594 {
6104 6595
6105 6596
6106 if (rules.Length == 0) 6597 if (rules.Length == 0)
@@ -6328,17 +6819,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6328 if (folderID == UUID.Zero) 6819 if (folderID == UUID.Zero)
6329 return; 6820 return;
6330 6821
6331 byte[] bucket = new byte[17]; 6822 byte[] bucket = new byte[1];
6332 bucket[0] = (byte)AssetType.Folder; 6823 bucket[0] = (byte)AssetType.Folder;
6333 byte[] objBytes = folderID.GetBytes(); 6824 //byte[] objBytes = folderID.GetBytes();
6334 Array.Copy(objBytes, 0, bucket, 1, 16); 6825 //Array.Copy(objBytes, 0, bucket, 1, 16);
6335 6826
6336 GridInstantMessage msg = new GridInstantMessage(World, 6827 GridInstantMessage msg = new GridInstantMessage(World,
6337 m_host.UUID, m_host.Name + ", an object owned by " + 6828 m_host.OwnerID, m_host.Name, destID,
6338 resolveName(m_host.OwnerID) + ",", destID, 6829 (byte)InstantMessageDialog.TaskInventoryOffered,
6339 (byte)InstantMessageDialog.InventoryOffered, 6830 false, category+". "+m_host.Name+" is located at "+
6340 false, category + "\n" + m_host.Name + " is located at " + 6831 World.RegionInfo.RegionName+" "+
6341 World.RegionInfo.RegionName + " " +
6342 m_host.AbsolutePosition.ToString(), 6832 m_host.AbsolutePosition.ToString(),
6343 folderID, true, m_host.AbsolutePosition, 6833 folderID, true, m_host.AbsolutePosition,
6344 bucket); 6834 bucket);
@@ -6418,7 +6908,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6418 { 6908 {
6419 // LSL quaternions can normalize to 0, normal Quaternions can't. 6909 // LSL quaternions can normalize to 0, normal Quaternions can't.
6420 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6910 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6421 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6911 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6422 6912
6423 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6913 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6424 part.SitTargetOrientation = Rot2Quaternion(rot); 6914 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6575,13 +7065,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6575 UUID av = new UUID(); 7065 UUID av = new UUID();
6576 if (!UUID.TryParse(avatar,out av)) 7066 if (!UUID.TryParse(avatar,out av))
6577 { 7067 {
6578 LSLError("First parameter to llDialog needs to be a key"); 7068 //LSLError("First parameter to llDialog needs to be a key");
6579 return; 7069 return;
6580 } 7070 }
6581 if (buttons.Length < 1) 7071 if (buttons.Length < 1)
6582 { 7072 {
6583 LSLError("No less than 1 button can be shown"); 7073 buttons.Add("OK");
6584 return;
6585 } 7074 }
6586 if (buttons.Length > 12) 7075 if (buttons.Length > 12)
6587 { 7076 {
@@ -6598,7 +7087,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6598 } 7087 }
6599 if (buttons.Data[i].ToString().Length > 24) 7088 if (buttons.Data[i].ToString().Length > 24)
6600 { 7089 {
6601 LSLError("button label cannot be longer than 24 characters"); 7090 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6602 return; 7091 return;
6603 } 7092 }
6604 buts[i] = buttons.Data[i].ToString(); 7093 buts[i] = buttons.Data[i].ToString();
@@ -6665,9 +7154,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6665 return; 7154 return;
6666 } 7155 }
6667 7156
6668 // the rest of the permission checks are done in RezScript, so check the pin there as well 7157 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6669 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7158 if (dest != null)
7159 {
7160 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7161 {
7162 // the rest of the permission checks are done in RezScript, so check the pin there as well
7163 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6670 7164
7165 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7166 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7167 }
7168 }
6671 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7169 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6672 ScriptSleep(3000); 7170 ScriptSleep(3000);
6673 } 7171 }
@@ -6730,19 +7228,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6730 public LSL_String llMD5String(string src, int nonce) 7228 public LSL_String llMD5String(string src, int nonce)
6731 { 7229 {
6732 m_host.AddScriptLPS(1); 7230 m_host.AddScriptLPS(1);
6733 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7231 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6734 } 7232 }
6735 7233
6736 public LSL_String llSHA1String(string src) 7234 public LSL_String llSHA1String(string src)
6737 { 7235 {
6738 m_host.AddScriptLPS(1); 7236 m_host.AddScriptLPS(1);
6739 return Util.SHA1Hash(src).ToLower(); 7237 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6740 } 7238 }
6741 7239
6742 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7240 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6743 { 7241 {
6744 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7242 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6745 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7243 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7244 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7245 return shapeBlock;
6746 7246
6747 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7247 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6748 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7248 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6847,6 +7347,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 // Prim type box, cylinder and prism. 7347 // Prim type box, cylinder and prism.
6848 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) 7348 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)
6849 { 7349 {
7350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7351 return;
7352
6850 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7353 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6851 ObjectShapePacket.ObjectDataBlock shapeBlock; 7354 ObjectShapePacket.ObjectDataBlock shapeBlock;
6852 7355
@@ -6900,6 +7403,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6900 // Prim type sphere. 7403 // Prim type sphere.
6901 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7404 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6902 { 7405 {
7406 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7407 return;
7408
6903 ObjectShapePacket.ObjectDataBlock shapeBlock; 7409 ObjectShapePacket.ObjectDataBlock shapeBlock;
6904 7410
6905 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7411 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6941,6 +7447,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 // Prim type torus, tube and ring. 7447 // Prim type torus, tube and ring.
6942 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) 7448 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)
6943 { 7449 {
7450 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7451 return;
7452
6944 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7453 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6945 ObjectShapePacket.ObjectDataBlock shapeBlock; 7454 ObjectShapePacket.ObjectDataBlock shapeBlock;
6946 7455
@@ -7076,6 +7585,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7076 // Prim type sculpt. 7585 // Prim type sculpt.
7077 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7586 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7078 { 7587 {
7588 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7589 return;
7590
7079 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7591 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7080 UUID sculptId; 7592 UUID sculptId;
7081 7593
@@ -7100,7 +7612,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7100 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7612 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7101 { 7613 {
7102 // default 7614 // default
7103 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7615 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7104 } 7616 }
7105 7617
7106 part.Shape.SetSculptProperties((byte)type, sculptId); 7618 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7116,34 +7628,315 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7116 ScriptSleep(200); 7628 ScriptSleep(200);
7117 } 7629 }
7118 7630
7119 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7631 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7120 { 7632 {
7121 m_host.AddScriptLPS(1); 7633 m_host.AddScriptLPS(1);
7122 7634
7123 setLinkPrimParams(linknumber, rules); 7635 setLinkPrimParams(linknumber, rules);
7636 }
7637
7638 private void setLinkPrimParams(int linknumber, LSL_List rules)
7639 {
7640 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7641 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7642 if (parts.Count>0)
7643 {
7644 try
7645 {
7646 parts[0].ParentGroup.areUpdatesSuspended = true;
7647 foreach (SceneObjectPart part in parts)
7648 SetPrimParams(part, rules);
7649 }
7650 finally
7651 {
7652 parts[0].ParentGroup.areUpdatesSuspended = false;
7653 }
7654 }
7655 if (avatars.Count > 0)
7656 {
7657 foreach (ScenePresence avatar in avatars)
7658 SetPrimParams(avatar, rules);
7659 }
7660 }
7661
7662 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7663 float material_density, float material_friction,
7664 float material_restitution, float material_gravity_modifier)
7665 {
7666 ExtraPhysicsData physdata = new ExtraPhysicsData();
7667 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7668 physdata.Density = part.Density;
7669 physdata.Friction = part.Friction;
7670 physdata.Bounce = part.Bounciness;
7671 physdata.GravitationModifier = part.GravityModifier;
7672
7673 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7674 physdata.Density = material_density;
7675 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7676 physdata.Friction = material_friction;
7677 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7678 physdata.Bounce = material_restitution;
7679 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7680 physdata.GravitationModifier = material_gravity_modifier;
7681
7682 part.UpdateExtraPhysics(physdata);
7683 }
7124 7684
7685 public void llSetPhysicsMaterial(int material_bits,
7686 float material_gravity_modifier, float material_restitution,
7687 float material_friction, float material_density)
7688 {
7689 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7690 }
7691
7692 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7693 {
7694 llSetLinkPrimitiveParamsFast(linknumber, rules);
7125 ScriptSleep(200); 7695 ScriptSleep(200);
7126 } 7696 }
7127 7697
7128 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7698 // vector up using libomv (c&p from sop )
7699 // vector up rotated by r
7700 private Vector3 Zrot(Quaternion r)
7129 { 7701 {
7130 m_host.AddScriptLPS(1); 7702 double x, y, z, m;
7131 7703
7132 setLinkPrimParams(linknumber, rules); 7704 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7705 if (Math.Abs(1.0 - m) > 0.000001)
7706 {
7707 m = 1.0 / Math.Sqrt(m);
7708 r.X *= (float)m;
7709 r.Y *= (float)m;
7710 r.Z *= (float)m;
7711 r.W *= (float)m;
7712 }
7713
7714 x = 2 * (r.X * r.Z + r.Y * r.W);
7715 y = 2 * (-r.X * r.W + r.Y * r.Z);
7716 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7717
7718 return new Vector3((float)x, (float)y, (float)z);
7133 } 7719 }
7134 7720
7135 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7721 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7136 { 7722 {
7137 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7723 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7138 7724
7139 foreach (SceneObjectPart part in parts) 7725 int idx = 0;
7140 SetPrimParams(part, rules); 7726 SceneObjectPart sitpart = World.GetSceneObjectPart(av.ParentID); // betting this will be used
7727
7728 bool positionChanged = false;
7729 Vector3 finalPos = Vector3.Zero;
7730
7731 try
7732 {
7733 while (idx < rules.Length)
7734 {
7735 int code = rules.GetLSLIntegerItem(idx++);
7736
7737 int remain = rules.Length - idx;
7738
7739 switch (code)
7740 {
7741 // a avatar is a child
7742 case (int)ScriptBaseClass.PRIM_POSITION:
7743 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7744 {
7745 if (remain < 1)
7746 return;
7747 LSL_Vector v;
7748 v = rules.GetVector3Item(idx++);
7749
7750 if (sitpart == null)
7751 break;
7752
7753 Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z); // requested absolute position
7754
7755 if (sitpart != sitpart.ParentGroup.RootPart)
7756 {
7757 pos -= sitpart.OffsetPosition; // remove sit part offset
7758 Quaternion rot = sitpart.RotationOffset;
7759 pos *= Quaternion.Conjugate(rot); // removed sit part rotation
7760 }
7761 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f * 2.0f);
7762 pos += sitOffset;
7763
7764 finalPos = pos;
7765 positionChanged = true;
7766 }
7767 break;
7768
7769 case (int)ScriptBaseClass.PRIM_ROTATION:
7770 {
7771 if (remain < 1)
7772 return;
7773
7774 if (sitpart == null)
7775 break;
7776
7777 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7778 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested world rotation
7779
7780// need to replicate SL bug
7781 SceneObjectGroup sitgrp = sitpart.ParentGroup;
7782 if (sitgrp != null && sitgrp.RootPart != sitpart)
7783 {
7784 rot = sitgrp.RootPart.RotationOffset * rot;
7785 }
7786
7787 Quaternion srot = sitpart.RotationOffset;
7788 rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation
7789 av.Rotation = rot;
7790// av.SendAvatarDataToAllAgents();
7791 av.SendTerseUpdateToAllClients();
7792 }
7793 break;
7794
7795 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7796 {
7797 if (remain < 1)
7798 return;
7799
7800 if (sitpart == null)
7801 break;
7802
7803 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7804 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested offset rotation
7805 if (sitpart != sitpart.ParentGroup.RootPart)
7806 {
7807 Quaternion srot = sitpart.RotationOffset;
7808 rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation
7809 }
7810 av.Rotation = rot;
7811// av.SendAvatarDataToAllAgents();
7812 av.SendTerseUpdateToAllClients();
7813 }
7814 break;
7815
7816 // parse rest doing nothing but number of parameters error check
7817 case (int)ScriptBaseClass.PRIM_SIZE:
7818 case (int)ScriptBaseClass.PRIM_MATERIAL:
7819 case (int)ScriptBaseClass.PRIM_PHANTOM:
7820 case (int)ScriptBaseClass.PRIM_PHYSICS:
7821 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7822 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7823 case (int)ScriptBaseClass.PRIM_NAME:
7824 case (int)ScriptBaseClass.PRIM_DESC:
7825 if (remain < 1)
7826 return;
7827 idx++;
7828 break;
7829
7830 case (int)ScriptBaseClass.PRIM_GLOW:
7831 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7832 case (int)ScriptBaseClass.PRIM_TEXGEN:
7833 if (remain < 2)
7834 return;
7835 idx += 2;
7836 break;
7837
7838 case (int)ScriptBaseClass.PRIM_TYPE:
7839 if (remain < 3)
7840 return;
7841 code = (int)rules.GetLSLIntegerItem(idx++);
7842 remain = rules.Length - idx;
7843 switch (code)
7844 {
7845 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7846 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7847 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7848 if (remain < 6)
7849 return;
7850 idx += 6;
7851 break;
7852
7853 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7854 if (remain < 5)
7855 return;
7856 idx += 5;
7857 break;
7858
7859 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7860 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7861 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7862 if (remain < 11)
7863 return;
7864 idx += 11;
7865 break;
7866
7867 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7868 if (remain < 2)
7869 return;
7870 idx += 2;
7871 break;
7872 }
7873 break;
7874
7875 case (int)ScriptBaseClass.PRIM_COLOR:
7876 case (int)ScriptBaseClass.PRIM_TEXT:
7877 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7878 case (int)ScriptBaseClass.PRIM_OMEGA:
7879 if (remain < 3)
7880 return;
7881 idx += 3;
7882 break;
7883
7884 case (int)ScriptBaseClass.PRIM_TEXTURE:
7885 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7886 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7887 if (remain < 5)
7888 return;
7889 idx += 5;
7890 break;
7891
7892 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7893 if (remain < 7)
7894 return;
7895
7896 idx += 7;
7897 break;
7898
7899 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7900 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7901 return;
7902
7903 if (positionChanged)
7904 {
7905 positionChanged = false;
7906 av.OffsetPosition = finalPos;
7907// av.SendAvatarDataToAllAgents();
7908 av.SendTerseUpdateToAllClients();
7909 }
7910
7911 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7912 LSL_List new_rules = rules.GetSublist(idx, -1);
7913 setLinkPrimParams((int)new_linknumber, new_rules);
7914 return;
7915 }
7916 }
7917 }
7918
7919 finally
7920 {
7921 if (positionChanged)
7922 {
7923 av.OffsetPosition = finalPos;
7924// av.SendAvatarDataToAllAgents();
7925 av.SendTerseUpdateToAllClients();
7926 positionChanged = false;
7927 }
7928 }
7141 } 7929 }
7142 7930
7143 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7931 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7144 { 7932 {
7933 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7934 return;
7935
7145 int idx = 0; 7936 int idx = 0;
7146 7937
7938 SceneObjectGroup parentgrp = part.ParentGroup;
7939
7147 bool positionChanged = false; 7940 bool positionChanged = false;
7148 LSL_Vector currentPosition = GetPartLocalPos(part); 7941 LSL_Vector currentPosition = GetPartLocalPos(part);
7149 7942
@@ -7166,8 +7959,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7166 return; 7959 return;
7167 7960
7168 v=rules.GetVector3Item(idx++); 7961 v=rules.GetVector3Item(idx++);
7169 positionChanged = true;
7170 currentPosition = GetSetPosTarget(part, v, currentPosition); 7962 currentPosition = GetSetPosTarget(part, v, currentPosition);
7963 positionChanged = true;
7171 7964
7172 break; 7965 break;
7173 case (int)ScriptBaseClass.PRIM_SIZE: 7966 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7183,8 +7976,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7183 return; 7976 return;
7184 7977
7185 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7978 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7979 SceneObjectPart rootPart = parentgrp.RootPart;
7186 // try to let this work as in SL... 7980 // try to let this work as in SL...
7187 if (part.ParentID == 0) 7981 if (rootPart == part)
7188 { 7982 {
7189 // special case: If we are root, rotate complete SOG to new rotation 7983 // special case: If we are root, rotate complete SOG to new rotation
7190 SetRot(part, Rot2Quaternion(q)); 7984 SetRot(part, Rot2Quaternion(q));
@@ -7192,7 +7986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7192 else 7986 else
7193 { 7987 {
7194 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7988 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7195 SceneObjectPart rootPart = part.ParentGroup.RootPart; 7989 // sounds like sl bug that we need to replicate
7196 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7990 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7197 } 7991 }
7198 7992
@@ -7445,7 +8239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7445 return; 8239 return;
7446 8240
7447 string ph = rules.Data[idx++].ToString(); 8241 string ph = rules.Data[idx++].ToString();
7448 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8242 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7449 8243
7450 break; 8244 break;
7451 8245
@@ -7463,12 +8257,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7463 part.ScriptSetPhysicsStatus(physics); 8257 part.ScriptSetPhysicsStatus(physics);
7464 break; 8258 break;
7465 8259
8260 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8261 if (remain < 1)
8262 return;
8263
8264 int shape_type = rules.GetLSLIntegerItem(idx++);
8265
8266 ExtraPhysicsData physdata = new ExtraPhysicsData();
8267 physdata.Density = part.Density;
8268 physdata.Bounce = part.Bounciness;
8269 physdata.GravitationModifier = part.GravityModifier;
8270 physdata.PhysShapeType = (PhysShapeType)shape_type;
8271
8272 part.UpdateExtraPhysics(physdata);
8273
8274 break;
8275
8276 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8277 if (remain < 5)
8278 return;
8279
8280 int material_bits = rules.GetLSLIntegerItem(idx++);
8281 float material_density = (float)rules.GetLSLFloatItem(idx++);
8282 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8283 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8284 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8285
8286 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8287
8288 break;
8289
7466 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8290 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7467 if (remain < 1) 8291 if (remain < 1)
7468 return; 8292 return;
7469 string temp = rules.Data[idx++].ToString(); 8293 string temp = rules.Data[idx++].ToString();
7470 8294
7471 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8295 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7472 8296
7473 break; 8297 break;
7474 8298
@@ -7507,6 +8331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7507 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8331 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7508 if (remain < 1) 8332 if (remain < 1)
7509 return; 8333 return;
8334
7510 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8335 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7511 SetRot(part, Rot2Quaternion(lr)); 8336 SetRot(part, Rot2Quaternion(lr));
7512 break; 8337 break;
@@ -7518,13 +8343,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7518 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8343 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7519 TargetOmega(part, axis, (double)spinrate, (double)gain); 8344 TargetOmega(part, axis, (double)spinrate, (double)gain);
7520 break; 8345 break;
8346
7521 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8347 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7522 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8348 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7523 return; 8349 return;
8350
8351 // do a pending position change before jumping to other part/avatar
8352 if (positionChanged)
8353 {
8354 positionChanged = false;
8355 if (parentgrp == null)
8356 return;
8357
8358 if (parentgrp.RootPart == part)
8359 {
8360
8361 Util.FireAndForget(delegate(object x)
8362 {
8363 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8364 });
8365 }
8366 else
8367 {
8368 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8369 parentgrp.HasGroupChanged = true;
8370 parentgrp.ScheduleGroupForTerseUpdate();
8371 }
8372 }
8373
7524 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8374 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7525 LSL_List new_rules = rules.GetSublist(idx, -1); 8375 LSL_List new_rules = rules.GetSublist(idx, -1);
7526 setLinkPrimParams((int)new_linknumber, new_rules); 8376 setLinkPrimParams((int)new_linknumber, new_rules);
7527
7528 return; 8377 return;
7529 } 8378 }
7530 } 8379 }
@@ -7536,7 +8385,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7536 if (part.ParentGroup.RootPart == part) 8385 if (part.ParentGroup.RootPart == part)
7537 { 8386 {
7538 SceneObjectGroup parent = part.ParentGroup; 8387 SceneObjectGroup parent = part.ParentGroup;
7539 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8388 Util.FireAndForget(delegate(object x) {
8389 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8390 });
7540 } 8391 }
7541 else 8392 else
7542 { 8393 {
@@ -7580,10 +8431,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7580 8431
7581 public LSL_String llXorBase64Strings(string str1, string str2) 8432 public LSL_String llXorBase64Strings(string str1, string str2)
7582 { 8433 {
7583 m_host.AddScriptLPS(1); 8434 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7584 Deprecated("llXorBase64Strings"); 8435
7585 ScriptSleep(300); 8436 ScriptSleep(300);
7586 return String.Empty; 8437 m_host.AddScriptLPS(1);
8438
8439 if (str1 == String.Empty)
8440 return String.Empty;
8441 if (str2 == String.Empty)
8442 return str1;
8443
8444 int len = str2.Length;
8445 if ((len % 4) != 0) // LL is EVIL!!!!
8446 {
8447 while (str2.EndsWith("="))
8448 str2 = str2.Substring(0, str2.Length - 1);
8449
8450 len = str2.Length;
8451 int mod = len % 4;
8452
8453 if (mod == 1)
8454 str2 = str2.Substring(0, str2.Length - 1);
8455 else if (mod == 2)
8456 str2 += "==";
8457 else if (mod == 3)
8458 str2 += "=";
8459 }
8460
8461 byte[] data1;
8462 byte[] data2;
8463 try
8464 {
8465 data1 = Convert.FromBase64String(str1);
8466 data2 = Convert.FromBase64String(str2);
8467 }
8468 catch (Exception)
8469 {
8470 return new LSL_String(String.Empty);
8471 }
8472
8473 // For cases where the decoded length of s2 is greater
8474 // than the decoded length of s1, simply perform a normal
8475 // decode and XOR
8476 //
8477 if (data2.Length >= data1.Length)
8478 {
8479 for (int pos = 0 ; pos < data1.Length ; pos++ )
8480 data1[pos] ^= data2[pos];
8481
8482 return Convert.ToBase64String(data1);
8483 }
8484
8485 // Remove padding
8486 while (str1.EndsWith("="))
8487 str1 = str1.Substring(0, str1.Length - 1);
8488 while (str2.EndsWith("="))
8489 str2 = str2.Substring(0, str2.Length - 1);
8490
8491 byte[] d1 = new byte[str1.Length];
8492 byte[] d2 = new byte[str2.Length];
8493
8494 for (int i = 0 ; i < str1.Length ; i++)
8495 {
8496 int idx = b64.IndexOf(str1.Substring(i, 1));
8497 if (idx == -1)
8498 idx = 0;
8499 d1[i] = (byte)idx;
8500 }
8501
8502 for (int i = 0 ; i < str2.Length ; i++)
8503 {
8504 int idx = b64.IndexOf(str2.Substring(i, 1));
8505 if (idx == -1)
8506 idx = 0;
8507 d2[i] = (byte)idx;
8508 }
8509
8510 string output = String.Empty;
8511
8512 for (int pos = 0 ; pos < d1.Length ; pos++)
8513 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8514
8515 while (output.Length % 3 > 0)
8516 output += "=";
8517
8518 return output;
7587 } 8519 }
7588 8520
7589 public void llRemoteDataSetRegion() 8521 public void llRemoteDataSetRegion()
@@ -7707,13 +8639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7707 public LSL_Integer llGetNumberOfPrims() 8639 public LSL_Integer llGetNumberOfPrims()
7708 { 8640 {
7709 m_host.AddScriptLPS(1); 8641 m_host.AddScriptLPS(1);
7710 int avatarCount = 0; 8642 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7711 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8643
7712 {
7713 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7714 avatarCount++;
7715 });
7716
7717 return m_host.ParentGroup.PrimCount + avatarCount; 8644 return m_host.ParentGroup.PrimCount + avatarCount;
7718 } 8645 }
7719 8646
@@ -7729,55 +8656,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7729 m_host.AddScriptLPS(1); 8656 m_host.AddScriptLPS(1);
7730 UUID objID = UUID.Zero; 8657 UUID objID = UUID.Zero;
7731 LSL_List result = new LSL_List(); 8658 LSL_List result = new LSL_List();
8659
8660 // If the ID is not valid, return null result
7732 if (!UUID.TryParse(obj, out objID)) 8661 if (!UUID.TryParse(obj, out objID))
7733 { 8662 {
7734 result.Add(new LSL_Vector()); 8663 result.Add(new LSL_Vector());
7735 result.Add(new LSL_Vector()); 8664 result.Add(new LSL_Vector());
7736 return result; 8665 return result;
7737 } 8666 }
8667
8668 // Check if this is an attached prim. If so, replace
8669 // the UUID with the avatar UUID and report it's bounding box
8670 SceneObjectPart part = World.GetSceneObjectPart(objID);
8671 if (part != null && part.ParentGroup.IsAttachment)
8672 objID = part.ParentGroup.AttachedAvatar;
8673
8674 // Find out if this is an avatar ID. If so, return it's box
7738 ScenePresence presence = World.GetScenePresence(objID); 8675 ScenePresence presence = World.GetScenePresence(objID);
7739 if (presence != null) 8676 if (presence != null)
7740 { 8677 {
7741 if (presence.ParentID == 0) // not sat on an object 8678 // As per LSL Wiki, there is no difference between sitting
8679 // and standing avatar since server 1.36
8680 LSL_Vector lower;
8681 LSL_Vector upper;
8682 if (presence.Animator.Animations.DefaultAnimation.AnimID
8683 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7742 { 8684 {
7743 LSL_Vector lower; 8685 // This is for ground sitting avatars
7744 LSL_Vector upper; 8686 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7745 if (presence.Animator.Animations.DefaultAnimation.AnimID 8687 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7746 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8688 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7747 {
7748 // This is for ground sitting avatars
7749 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7750 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7751 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7752 }
7753 else
7754 {
7755 // This is for standing/flying avatars
7756 float height = presence.Appearance.AvatarHeight / 2.0f;
7757 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7758 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7759 }
7760 result.Add(lower);
7761 result.Add(upper);
7762 return result;
7763 } 8689 }
7764 else 8690 else
7765 { 8691 {
7766 // sitting on an object so we need the bounding box of that 8692 // This is for standing/flying avatars
7767 // which should include the avatar so set the UUID to the 8693 float height = presence.Appearance.AvatarHeight / 2.0f;
7768 // UUID of the object the avatar is sat on and allow it to fall through 8694 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7769 // to processing an object 8695 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7770 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7771 objID = p.UUID;
7772 } 8696 }
8697
8698 // Adjust to the documented error offsets (see LSL Wiki)
8699 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8700 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8701
8702 if (lower.x > upper.x)
8703 lower.x = upper.x;
8704 if (lower.y > upper.y)
8705 lower.y = upper.y;
8706 if (lower.z > upper.z)
8707 lower.z = upper.z;
8708
8709 result.Add(lower);
8710 result.Add(upper);
8711 return result;
7773 } 8712 }
7774 SceneObjectPart part = World.GetSceneObjectPart(objID); 8713
8714 part = World.GetSceneObjectPart(objID);
7775 // Currently only works for single prims without a sitting avatar 8715 // Currently only works for single prims without a sitting avatar
7776 if (part != null) 8716 if (part != null)
7777 { 8717 {
7778 Vector3 halfSize = part.Scale / 2.0f; 8718 float minX;
7779 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8719 float maxX;
7780 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8720 float minY;
8721 float maxY;
8722 float minZ;
8723 float maxZ;
8724
8725 // This BBox is in sim coordinates, with the offset being
8726 // a contained point.
8727 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8728 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8729
8730 minX -= offsets[0].X;
8731 maxX -= offsets[0].X;
8732 minY -= offsets[0].Y;
8733 maxY -= offsets[0].Y;
8734 minZ -= offsets[0].Z;
8735 maxZ -= offsets[0].Z;
8736
8737 LSL_Vector lower;
8738 LSL_Vector upper;
8739
8740 // Adjust to the documented error offsets (see LSL Wiki)
8741 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8742 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8743
8744 if (lower.x > upper.x)
8745 lower.x = upper.x;
8746 if (lower.y > upper.y)
8747 lower.y = upper.y;
8748 if (lower.z > upper.z)
8749 lower.z = upper.z;
8750
7781 result.Add(lower); 8751 result.Add(lower);
7782 result.Add(upper); 8752 result.Add(upper);
7783 return result; 8753 return result;
@@ -7791,7 +8761,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7791 8761
7792 public LSL_Vector llGetGeometricCenter() 8762 public LSL_Vector llGetGeometricCenter()
7793 { 8763 {
7794 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8764 Vector3 tmp = m_host.GetGeometricCenter();
8765 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7795 } 8766 }
7796 8767
7797 public LSL_List llGetPrimitiveParams(LSL_List rules) 8768 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7804,16 +8775,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7804 { 8775 {
7805 m_host.AddScriptLPS(1); 8776 m_host.AddScriptLPS(1);
7806 8777
8778 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8779 // keep other options as before
8780
7807 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8781 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8782 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7808 8783
7809 LSL_List res = new LSL_List(); 8784 LSL_List res = new LSL_List();
7810 8785
7811 foreach (var part in parts) 8786 if (parts.Count > 0)
7812 { 8787 {
7813 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8788 foreach (var part in parts)
7814 res += partRes; 8789 {
8790 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8791 res += partRes;
8792 }
8793 }
8794 if (avatars.Count > 0)
8795 {
8796 foreach (ScenePresence avatar in avatars)
8797 {
8798 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8799 res += avaRes;
8800 }
7815 } 8801 }
8802 return res;
8803 }
8804
8805 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8806 {
8807 // avatars case
8808 // replies as SL wiki
8809
8810 LSL_List res = new LSL_List();
8811// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8812 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8813
8814 int idx = 0;
8815 while (idx < rules.Length)
8816 {
8817 int code = (int)rules.GetLSLIntegerItem(idx++);
8818 int remain = rules.Length - idx;
8819
8820 switch (code)
8821 {
8822 case (int)ScriptBaseClass.PRIM_MATERIAL:
8823 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8824 break;
8825
8826 case (int)ScriptBaseClass.PRIM_PHYSICS:
8827 res.Add(new LSL_Integer(0));
8828 break;
8829
8830 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8831 res.Add(new LSL_Integer(0));
8832 break;
8833
8834 case (int)ScriptBaseClass.PRIM_PHANTOM:
8835 res.Add(new LSL_Integer(0));
8836 break;
8837
8838 case (int)ScriptBaseClass.PRIM_POSITION:
8839
8840 Vector3 pos = avatar.OffsetPosition;
8841
8842 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8843 pos -= sitOffset;
8844
8845 if( sitPart != null)
8846 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8847
8848 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8849 break;
8850
8851 case (int)ScriptBaseClass.PRIM_SIZE:
8852 // as in llGetAgentSize above
8853 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8854 break;
8855
8856 case (int)ScriptBaseClass.PRIM_ROTATION:
8857 Quaternion rot = avatar.Rotation;
8858 if (sitPart != null)
8859 {
8860 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8861 }
8862
8863 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8864 break;
8865
8866 case (int)ScriptBaseClass.PRIM_TYPE:
8867 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8868 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8869 res.Add(new LSL_Vector(0f,1.0f,0f));
8870 res.Add(new LSL_Float(0.0f));
8871 res.Add(new LSL_Vector(0, 0, 0));
8872 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8873 res.Add(new LSL_Vector(0, 0, 0));
8874 break;
8875
8876 case (int)ScriptBaseClass.PRIM_TEXTURE:
8877 if (remain < 1)
8878 return res;
8879
8880 int face = (int)rules.GetLSLIntegerItem(idx++);
8881 if (face == ScriptBaseClass.ALL_SIDES)
8882 {
8883 for (face = 0; face < 21; face++)
8884 {
8885 res.Add(new LSL_String(""));
8886 res.Add(new LSL_Vector(0,0,0));
8887 res.Add(new LSL_Vector(0,0,0));
8888 res.Add(new LSL_Float(0.0));
8889 }
8890 }
8891 else
8892 {
8893 if (face >= 0 && face < 21)
8894 {
8895 res.Add(new LSL_String(""));
8896 res.Add(new LSL_Vector(0,0,0));
8897 res.Add(new LSL_Vector(0,0,0));
8898 res.Add(new LSL_Float(0.0));
8899 }
8900 }
8901 break;
8902
8903 case (int)ScriptBaseClass.PRIM_COLOR:
8904 if (remain < 1)
8905 return res;
8906
8907 face = (int)rules.GetLSLIntegerItem(idx++);
8908
8909 if (face == ScriptBaseClass.ALL_SIDES)
8910 {
8911 for (face = 0; face < 21; face++)
8912 {
8913 res.Add(new LSL_Vector(0,0,0));
8914 res.Add(new LSL_Float(0));
8915 }
8916 }
8917 else
8918 {
8919 res.Add(new LSL_Vector(0,0,0));
8920 res.Add(new LSL_Float(0));
8921 }
8922 break;
8923
8924 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8925 if (remain < 1)
8926 return res;
8927 face = (int)rules.GetLSLIntegerItem(idx++);
8928
8929 if (face == ScriptBaseClass.ALL_SIDES)
8930 {
8931 for (face = 0; face < 21; face++)
8932 {
8933 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8934 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8935 }
8936 }
8937 else
8938 {
8939 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8940 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8941 }
8942 break;
8943
8944 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8945 if (remain < 1)
8946 return res;
8947 face = (int)rules.GetLSLIntegerItem(idx++);
8948
8949 if (face == ScriptBaseClass.ALL_SIDES)
8950 {
8951 for (face = 0; face < 21; face++)
8952 {
8953 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8954 }
8955 }
8956 else
8957 {
8958 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8959 }
8960 break;
8961
8962 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8963 res.Add(new LSL_Integer(0));
8964 res.Add(new LSL_Integer(0));// softness
8965 res.Add(new LSL_Float(0.0f)); // gravity
8966 res.Add(new LSL_Float(0.0f)); // friction
8967 res.Add(new LSL_Float(0.0f)); // wind
8968 res.Add(new LSL_Float(0.0f)); // tension
8969 res.Add(new LSL_Vector(0f,0f,0f));
8970 break;
8971
8972 case (int)ScriptBaseClass.PRIM_TEXGEN:
8973 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8974 if (remain < 1)
8975 return res;
8976 face = (int)rules.GetLSLIntegerItem(idx++);
8977
8978 if (face == ScriptBaseClass.ALL_SIDES)
8979 {
8980 for (face = 0; face < 21; face++)
8981 {
8982 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8983 }
8984 }
8985 else
8986 {
8987 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8988 }
8989 break;
8990
8991 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8992 res.Add(new LSL_Integer(0));
8993 res.Add(new LSL_Vector(0f,0f,0f));
8994 res.Add(new LSL_Float(0f)); // intensity
8995 res.Add(new LSL_Float(0f)); // radius
8996 res.Add(new LSL_Float(0f)); // falloff
8997 break;
8998
8999 case (int)ScriptBaseClass.PRIM_GLOW:
9000 if (remain < 1)
9001 return res;
9002 face = (int)rules.GetLSLIntegerItem(idx++);
9003
9004 if (face == ScriptBaseClass.ALL_SIDES)
9005 {
9006 for (face = 0; face < 21; face++)
9007 {
9008 res.Add(new LSL_Float(0f));
9009 }
9010 }
9011 else
9012 {
9013 res.Add(new LSL_Float(0f));
9014 }
9015 break;
9016
9017 case (int)ScriptBaseClass.PRIM_TEXT:
9018 res.Add(new LSL_String(""));
9019 res.Add(new LSL_Vector(0f,0f,0f));
9020 res.Add(new LSL_Float(1.0f));
9021 break;
9022
9023 case (int)ScriptBaseClass.PRIM_NAME:
9024 res.Add(new LSL_String(avatar.Name));
9025 break;
9026
9027 case (int)ScriptBaseClass.PRIM_DESC:
9028 res.Add(new LSL_String(""));
9029 break;
7816 9030
9031 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9032 Quaternion lrot = avatar.Rotation;
9033
9034 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9035 {
9036 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9037 }
9038 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9039 break;
9040
9041 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9042 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9043 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9044 lpos -= lsitOffset;
9045
9046 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9047 {
9048 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9049 }
9050 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9051 break;
9052
9053 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9054 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9055 return res;
9056 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9057 LSL_List new_rules = rules.GetSublist(idx, -1);
9058
9059 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9060 return res;
9061 }
9062 }
7817 return res; 9063 return res;
7818 } 9064 }
7819 9065
@@ -7857,13 +9103,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9103 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7858 part.AbsolutePosition.Y, 9104 part.AbsolutePosition.Y,
7859 part.AbsolutePosition.Z); 9105 part.AbsolutePosition.Z);
7860 // For some reason, the part.AbsolutePosition.* values do not change if the
7861 // linkset is rotated; they always reflect the child prim's world position
7862 // as though the linkset is unrotated. This is incompatible behavior with SL's
7863 // implementation, so will break scripts imported from there (not to mention it
7864 // makes it more difficult to determine a child prim's actual inworld position).
7865 if (part.ParentID != 0)
7866 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7867 res.Add(v); 9106 res.Add(v);
7868 break; 9107 break;
7869 9108
@@ -8034,56 +9273,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8034 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9273 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8035 if (remain < 1) 9274 if (remain < 1)
8036 return res; 9275 return res;
8037 9276 face = (int)rules.GetLSLIntegerItem(idx++);
8038 face=(int)rules.GetLSLIntegerItem(idx++);
8039 9277
8040 tex = part.Shape.Textures; 9278 tex = part.Shape.Textures;
9279 int shiny;
8041 if (face == ScriptBaseClass.ALL_SIDES) 9280 if (face == ScriptBaseClass.ALL_SIDES)
8042 { 9281 {
8043 for (face = 0; face < GetNumberOfSides(part); face++) 9282 for (face = 0; face < GetNumberOfSides(part); face++)
8044 { 9283 {
8045 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9284 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8046 // Convert Shininess to PRIM_SHINY_* 9285 if (shinyness == Shininess.High)
8047 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9286 {
8048 // PRIM_BUMP_* 9287 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8049 res.Add(new LSL_Integer((int)texface.Bump)); 9288 }
9289 else if (shinyness == Shininess.Medium)
9290 {
9291 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9292 }
9293 else if (shinyness == Shininess.Low)
9294 {
9295 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9296 }
9297 else
9298 {
9299 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9300 }
9301 res.Add(new LSL_Integer(shiny));
9302 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8050 } 9303 }
8051 } 9304 }
8052 else 9305 else
8053 { 9306 {
8054 if (face >= 0 && face < GetNumberOfSides(part)) 9307 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9308 if (shinyness == Shininess.High)
8055 { 9309 {
8056 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9310 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8057 // Convert Shininess to PRIM_SHINY_*
8058 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8059 // PRIM_BUMP_*
8060 res.Add(new LSL_Integer((int)texface.Bump));
8061 } 9311 }
9312 else if (shinyness == Shininess.Medium)
9313 {
9314 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9315 }
9316 else if (shinyness == Shininess.Low)
9317 {
9318 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9319 }
9320 else
9321 {
9322 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9323 }
9324 res.Add(new LSL_Integer(shiny));
9325 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8062 } 9326 }
8063 break; 9327 break;
8064 9328
8065 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9329 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8066 if (remain < 1) 9330 if (remain < 1)
8067 return res; 9331 return res;
8068 9332 face = (int)rules.GetLSLIntegerItem(idx++);
8069 face=(int)rules.GetLSLIntegerItem(idx++);
8070 9333
8071 tex = part.Shape.Textures; 9334 tex = part.Shape.Textures;
9335 int fullbright;
8072 if (face == ScriptBaseClass.ALL_SIDES) 9336 if (face == ScriptBaseClass.ALL_SIDES)
8073 { 9337 {
8074 for (face = 0; face < GetNumberOfSides(part); face++) 9338 for (face = 0; face < GetNumberOfSides(part); face++)
8075 { 9339 {
8076 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9340 if (tex.GetFace((uint)face).Fullbright == true)
8077 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9341 {
9342 fullbright = ScriptBaseClass.TRUE;
9343 }
9344 else
9345 {
9346 fullbright = ScriptBaseClass.FALSE;
9347 }
9348 res.Add(new LSL_Integer(fullbright));
8078 } 9349 }
8079 } 9350 }
8080 else 9351 else
8081 { 9352 {
8082 if (face >= 0 && face < GetNumberOfSides(part)) 9353 if (tex.GetFace((uint)face).Fullbright == true)
8083 { 9354 {
8084 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9355 fullbright = ScriptBaseClass.TRUE;
8085 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9356 }
9357 else
9358 {
9359 fullbright = ScriptBaseClass.FALSE;
8086 } 9360 }
9361 res.Add(new LSL_Integer(fullbright));
8087 } 9362 }
8088 break; 9363 break;
8089 9364
@@ -8105,27 +9380,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8105 break; 9380 break;
8106 9381
8107 case (int)ScriptBaseClass.PRIM_TEXGEN: 9382 case (int)ScriptBaseClass.PRIM_TEXGEN:
9383 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8108 if (remain < 1) 9384 if (remain < 1)
8109 return res; 9385 return res;
8110 9386 face = (int)rules.GetLSLIntegerItem(idx++);
8111 face=(int)rules.GetLSLIntegerItem(idx++);
8112 9387
8113 tex = part.Shape.Textures; 9388 tex = part.Shape.Textures;
8114 if (face == ScriptBaseClass.ALL_SIDES) 9389 if (face == ScriptBaseClass.ALL_SIDES)
8115 { 9390 {
8116 for (face = 0; face < GetNumberOfSides(part); face++) 9391 for (face = 0; face < GetNumberOfSides(part); face++)
8117 { 9392 {
8118 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9393 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8119 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9394 {
8120 res.Add(new LSL_Integer((uint)texgen >> 1)); 9395 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9396 }
9397 else
9398 {
9399 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9400 }
8121 } 9401 }
8122 } 9402 }
8123 else 9403 else
8124 { 9404 {
8125 if (face >= 0 && face < GetNumberOfSides(part)) 9405 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9406 {
9407 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9408 }
9409 else
8126 { 9410 {
8127 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9411 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8128 res.Add(new LSL_Integer((uint)texgen >> 1));
8129 } 9412 }
8130 } 9413 }
8131 break; 9414 break;
@@ -8148,25 +9431,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8148 case (int)ScriptBaseClass.PRIM_GLOW: 9431 case (int)ScriptBaseClass.PRIM_GLOW:
8149 if (remain < 1) 9432 if (remain < 1)
8150 return res; 9433 return res;
8151 9434 face = (int)rules.GetLSLIntegerItem(idx++);
8152 face=(int)rules.GetLSLIntegerItem(idx++);
8153 9435
8154 tex = part.Shape.Textures; 9436 tex = part.Shape.Textures;
9437 float primglow;
8155 if (face == ScriptBaseClass.ALL_SIDES) 9438 if (face == ScriptBaseClass.ALL_SIDES)
8156 { 9439 {
8157 for (face = 0; face < GetNumberOfSides(part); face++) 9440 for (face = 0; face < GetNumberOfSides(part); face++)
8158 { 9441 {
8159 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9442 primglow = tex.GetFace((uint)face).Glow;
8160 res.Add(new LSL_Float(texface.Glow)); 9443 res.Add(new LSL_Float(primglow));
8161 } 9444 }
8162 } 9445 }
8163 else 9446 else
8164 { 9447 {
8165 if (face >= 0 && face < GetNumberOfSides(part)) 9448 primglow = tex.GetFace((uint)face).Glow;
8166 { 9449 res.Add(new LSL_Float(primglow));
8167 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8168 res.Add(new LSL_Float(texface.Glow));
8169 }
8170 } 9450 }
8171 break; 9451 break;
8172 9452
@@ -8178,18 +9458,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8178 textColor.B)); 9458 textColor.B));
8179 res.Add(new LSL_Float(textColor.A)); 9459 res.Add(new LSL_Float(textColor.A));
8180 break; 9460 break;
9461
8181 case (int)ScriptBaseClass.PRIM_NAME: 9462 case (int)ScriptBaseClass.PRIM_NAME:
8182 res.Add(new LSL_String(part.Name)); 9463 res.Add(new LSL_String(part.Name));
8183 break; 9464 break;
9465
8184 case (int)ScriptBaseClass.PRIM_DESC: 9466 case (int)ScriptBaseClass.PRIM_DESC:
8185 res.Add(new LSL_String(part.Description)); 9467 res.Add(new LSL_String(part.Description));
8186 break; 9468 break;
9469
8187 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9470 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8188 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9471 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8189 break; 9472 break;
9473
8190 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9474 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8191 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9475 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8192 break; 9476 break;
9477
9478 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9479 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9480 return res;
9481 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9482 LSL_List new_rules = rules.GetSublist(idx, -1);
9483 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9484 res += tres;
9485 return res;
8193 } 9486 }
8194 } 9487 }
8195 return res; 9488 return res;
@@ -8782,8 +10075,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8782 // The function returns an ordered list 10075 // The function returns an ordered list
8783 // representing the tokens found in the supplied 10076 // representing the tokens found in the supplied
8784 // sources string. If two successive tokenizers 10077 // sources string. If two successive tokenizers
8785 // are encountered, then a NULL entry is added 10078 // are encountered, then a null-string entry is
8786 // to the list. 10079 // added to the list.
8787 // 10080 //
8788 // It is a precondition that the source and 10081 // It is a precondition that the source and
8789 // toekizer lisst are non-null. If they are null, 10082 // toekizer lisst are non-null. If they are null,
@@ -8791,7 +10084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8791 // while their lengths are being determined. 10084 // while their lengths are being determined.
8792 // 10085 //
8793 // A small amount of working memoryis required 10086 // A small amount of working memoryis required
8794 // of approximately 8*#tokenizers. 10087 // of approximately 8*#tokenizers + 8*srcstrlen.
8795 // 10088 //
8796 // There are many ways in which this function 10089 // There are many ways in which this function
8797 // can be implemented, this implementation is 10090 // can be implemented, this implementation is
@@ -8807,155 +10100,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8807 // and eliminates redundant tokenizers as soon 10100 // and eliminates redundant tokenizers as soon
8808 // as is possible. 10101 // as is possible.
8809 // 10102 //
8810 // The implementation tries to avoid any copying 10103 // The implementation tries to minimize temporary
8811 // of arrays or other objects. 10104 // garbage generation.
8812 // </remarks> 10105 // </remarks>
8813 10106
8814 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10107 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8815 { 10108 {
8816 int beginning = 0; 10109 return ParseString2List(src, separators, spacers, true);
8817 int srclen = src.Length; 10110 }
8818 int seplen = separators.Length;
8819 object[] separray = separators.Data;
8820 int spclen = spacers.Length;
8821 object[] spcarray = spacers.Data;
8822 int mlen = seplen+spclen;
8823
8824 int[] offset = new int[mlen+1];
8825 bool[] active = new bool[mlen];
8826
8827 int best;
8828 int j;
8829
8830 // Initial capacity reduces resize cost
8831 10111
8832 LSL_List tokens = new LSL_List(); 10112 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10113 {
10114 int srclen = src.Length;
10115 int seplen = separators.Length;
10116 object[] separray = separators.Data;
10117 int spclen = spacers.Length;
10118 object[] spcarray = spacers.Data;
10119 int dellen = 0;
10120 string[] delarray = new string[seplen+spclen];
8833 10121
8834 // All entries are initially valid 10122 int outlen = 0;
10123 string[] outarray = new string[srclen*2+1];
8835 10124
8836 for (int i = 0; i < mlen; i++) 10125 int i, j;
8837 active[i] = true; 10126 string d;
8838 10127
8839 offset[mlen] = srclen; 10128 m_host.AddScriptLPS(1);
8840 10129
8841 while (beginning < srclen) 10130 /*
10131 * Convert separator and spacer lists to C# strings.
10132 * Also filter out null strings so we don't hang.
10133 */
10134 for (i = 0; i < seplen; i ++)
8842 { 10135 {
10136 d = separray[i].ToString();
10137 if (d.Length > 0)
10138 {
10139 delarray[dellen++] = d;
10140 }
10141 }
10142 seplen = dellen;
8843 10143
8844 best = mlen; // as bad as it gets 10144 for (i = 0; i < spclen; i ++)
10145 {
10146 d = spcarray[i].ToString();
10147 if (d.Length > 0)
10148 {
10149 delarray[dellen++] = d;
10150 }
10151 }
8845 10152
8846 // Scan for separators 10153 /*
10154 * Scan through source string from beginning to end.
10155 */
10156 for (i = 0;;)
10157 {
8847 10158
8848 for (j = 0; j < seplen; j++) 10159 /*
10160 * Find earliest delimeter in src starting at i (if any).
10161 */
10162 int earliestDel = -1;
10163 int earliestSrc = srclen;
10164 string earliestStr = null;
10165 for (j = 0; j < dellen; j ++)
8849 { 10166 {
8850 if (separray[j].ToString() == String.Empty) 10167 d = delarray[j];
8851 active[j] = false; 10168 if (d != null)
8852
8853 if (active[j])
8854 { 10169 {
8855 // scan all of the markers 10170 int index = src.IndexOf(d, i);
8856 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10171 if (index < 0)
8857 { 10172 {
8858 // not present at all 10173 delarray[j] = null; // delim nowhere in src, don't check it anymore
8859 active[j] = false;
8860 } 10174 }
8861 else 10175 else if (index < earliestSrc)
8862 { 10176 {
8863 // present and correct 10177 earliestSrc = index; // where delimeter starts in source string
8864 if (offset[j] < offset[best]) 10178 earliestDel = j; // where delimeter is in delarray[]
8865 { 10179 earliestStr = d; // the delimeter string from delarray[]
8866 // closest so far 10180 if (index == i) break; // can't do any better than found at beg of string
8867 best = j;
8868 if (offset[best] == beginning)
8869 break;
8870 }
8871 } 10181 }
8872 } 10182 }
8873 } 10183 }
8874 10184
8875 // Scan for spacers 10185 /*
8876 10186 * Output source string starting at i through start of earliest delimeter.
8877 if (offset[best] != beginning) 10187 */
10188 if (keepNulls || (earliestSrc > i))
8878 { 10189 {
8879 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10190 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8880 {
8881 if (spcarray[j-seplen].ToString() == String.Empty)
8882 active[j] = false;
8883
8884 if (active[j])
8885 {
8886 // scan all of the markers
8887 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8888 {
8889 // not present at all
8890 active[j] = false;
8891 }
8892 else
8893 {
8894 // present and correct
8895 if (offset[j] < offset[best])
8896 {
8897 // closest so far
8898 best = j;
8899 }
8900 }
8901 }
8902 }
8903 } 10191 }
8904 10192
8905 // This is the normal exit from the scanning loop 10193 /*
10194 * If no delimeter found at or after i, we're done scanning.
10195 */
10196 if (earliestDel < 0) break;
8906 10197
8907 if (best == mlen) 10198 /*
10199 * If delimeter was a spacer, output the spacer.
10200 */
10201 if (earliestDel >= seplen)
8908 { 10202 {
8909 // no markers were found on this pass 10203 outarray[outlen++] = earliestStr;
8910 // so we're pretty much done
8911 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8912 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8913 break;
8914 } 10204 }
8915 10205
8916 // Otherwise we just add the newly delimited token 10206 /*
8917 // and recalculate where the search should continue. 10207 * Look at rest of src string following delimeter.
8918 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10208 */
8919 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10209 i = earliestSrc + earliestStr.Length;
8920
8921 if (best < seplen)
8922 {
8923 beginning = offset[best] + (separray[best].ToString()).Length;
8924 }
8925 else
8926 {
8927 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8928 string str = spcarray[best - seplen].ToString();
8929 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8930 tokens.Add(new LSL_String(str));
8931 }
8932 } 10210 }
8933 10211
8934 // This an awkward an not very intuitive boundary case. If the 10212 /*
8935 // last substring is a tokenizer, then there is an implied trailing 10213 * Make up an exact-sized output array suitable for an LSL_List object.
8936 // null list entry. Hopefully the single comparison will not be too 10214 */
8937 // arduous. Alternatively the 'break' could be replced with a return 10215 object[] outlist = new object[outlen];
8938 // but that's shabby programming. 10216 for (i = 0; i < outlen; i ++)
8939
8940 if ((beginning == srclen) && (keepNulls))
8941 { 10217 {
8942 if (srclen != 0) 10218 outlist[i] = new LSL_String(outarray[i]);
8943 tokens.Add(new LSL_String(""));
8944 } 10219 }
8945 10220 return new LSL_List(outlist);
8946 return tokens;
8947 }
8948
8949 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8950 {
8951 m_host.AddScriptLPS(1);
8952 return this.ParseString(src, separators, spacers, false);
8953 }
8954
8955 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8956 {
8957 m_host.AddScriptLPS(1);
8958 return this.ParseString(src, separators, spacers, true);
8959 } 10221 }
8960 10222
8961 public LSL_Integer llGetObjectPermMask(int mask) 10223 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9050,6 +10312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9050 case 4: 10312 case 4:
9051 return (int)item.NextPermissions; 10313 return (int)item.NextPermissions;
9052 } 10314 }
10315 m_host.TaskInventory.LockItemsForRead(false);
9053 10316
9054 return -1; 10317 return -1;
9055 } 10318 }
@@ -9240,9 +10503,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9240 { 10503 {
9241 try 10504 try
9242 { 10505 {
10506 /*
9243 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10507 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9244 if (obj != null) 10508 if (obj != null)
9245 return (double)obj.GetMass(); 10509 return (double)obj.GetMass();
10510 */
10511 // return total object mass
10512 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10513 if (obj != null)
10514 return obj.GetMass();
10515
9246 // the object is null so the key is for an avatar 10516 // the object is null so the key is for an avatar
9247 ScenePresence avatar = World.GetScenePresence(key); 10517 ScenePresence avatar = World.GetScenePresence(key);
9248 if (avatar != null) 10518 if (avatar != null)
@@ -9262,7 +10532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9262 } 10532 }
9263 10533
9264 /// <summary> 10534 /// <summary>
9265 /// illListReplaceList removes the sub-list defined by the inclusive indices 10535 /// llListReplaceList removes the sub-list defined by the inclusive indices
9266 /// start and end and inserts the src list in its place. The inclusive 10536 /// start and end and inserts the src list in its place. The inclusive
9267 /// nature of the indices means that at least one element must be deleted 10537 /// nature of the indices means that at least one element must be deleted
9268 /// if the indices are within the bounds of the existing list. I.e. 2,2 10538 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9319,16 +10589,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9319 // based upon end. Note that if end exceeds the upper 10589 // based upon end. Note that if end exceeds the upper
9320 // bound in this case, the entire destination list 10590 // bound in this case, the entire destination list
9321 // is removed. 10591 // is removed.
9322 else 10592 else if (start == 0)
9323 { 10593 {
9324 if (end + 1 < dest.Length) 10594 if (end + 1 < dest.Length)
9325 {
9326 return src + dest.GetSublist(end + 1, -1); 10595 return src + dest.GetSublist(end + 1, -1);
9327 }
9328 else 10596 else
9329 {
9330 return src; 10597 return src;
9331 } 10598 }
10599 else // Start < 0
10600 {
10601 if (end + 1 < dest.Length)
10602 return dest.GetSublist(end + 1, -1);
10603 else
10604 return new LSL_List();
9332 } 10605 }
9333 } 10606 }
9334 // Finally, if start > end, we strip away a prefix and 10607 // Finally, if start > end, we strip away a prefix and
@@ -9379,17 +10652,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9379 int width = 0; 10652 int width = 0;
9380 int height = 0; 10653 int height = 0;
9381 10654
9382 ParcelMediaCommandEnum? commandToSend = null; 10655 uint commandToSend = 0;
9383 float time = 0.0f; // default is from start 10656 float time = 0.0f; // default is from start
9384 10657
9385 ScenePresence presence = null; 10658 ScenePresence presence = null;
9386 10659
9387 for (int i = 0; i < commandList.Data.Length; i++) 10660 for (int i = 0; i < commandList.Data.Length; i++)
9388 { 10661 {
9389 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10662 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9390 switch (command) 10663 switch (command)
9391 { 10664 {
9392 case ParcelMediaCommandEnum.Agent: 10665 case (uint)ParcelMediaCommandEnum.Agent:
9393 // we send only to one agent 10666 // we send only to one agent
9394 if ((i + 1) < commandList.Length) 10667 if ((i + 1) < commandList.Length)
9395 { 10668 {
@@ -9406,25 +10679,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9406 } 10679 }
9407 break; 10680 break;
9408 10681
9409 case ParcelMediaCommandEnum.Loop: 10682 case (uint)ParcelMediaCommandEnum.Loop:
9410 loop = 1; 10683 loop = 1;
9411 commandToSend = command; 10684 commandToSend = command;
9412 update = true; //need to send the media update packet to set looping 10685 update = true; //need to send the media update packet to set looping
9413 break; 10686 break;
9414 10687
9415 case ParcelMediaCommandEnum.Play: 10688 case (uint)ParcelMediaCommandEnum.Play:
9416 loop = 0; 10689 loop = 0;
9417 commandToSend = command; 10690 commandToSend = command;
9418 update = true; //need to send the media update packet to make sure it doesn't loop 10691 update = true; //need to send the media update packet to make sure it doesn't loop
9419 break; 10692 break;
9420 10693
9421 case ParcelMediaCommandEnum.Pause: 10694 case (uint)ParcelMediaCommandEnum.Pause:
9422 case ParcelMediaCommandEnum.Stop: 10695 case (uint)ParcelMediaCommandEnum.Stop:
9423 case ParcelMediaCommandEnum.Unload: 10696 case (uint)ParcelMediaCommandEnum.Unload:
9424 commandToSend = command; 10697 commandToSend = command;
9425 break; 10698 break;
9426 10699
9427 case ParcelMediaCommandEnum.Url: 10700 case (uint)ParcelMediaCommandEnum.Url:
9428 if ((i + 1) < commandList.Length) 10701 if ((i + 1) < commandList.Length)
9429 { 10702 {
9430 if (commandList.Data[i + 1] is LSL_String) 10703 if (commandList.Data[i + 1] is LSL_String)
@@ -9437,7 +10710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 } 10710 }
9438 break; 10711 break;
9439 10712
9440 case ParcelMediaCommandEnum.Texture: 10713 case (uint)ParcelMediaCommandEnum.Texture:
9441 if ((i + 1) < commandList.Length) 10714 if ((i + 1) < commandList.Length)
9442 { 10715 {
9443 if (commandList.Data[i + 1] is LSL_String) 10716 if (commandList.Data[i + 1] is LSL_String)
@@ -9450,7 +10723,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9450 } 10723 }
9451 break; 10724 break;
9452 10725
9453 case ParcelMediaCommandEnum.Time: 10726 case (uint)ParcelMediaCommandEnum.Time:
9454 if ((i + 1) < commandList.Length) 10727 if ((i + 1) < commandList.Length)
9455 { 10728 {
9456 if (commandList.Data[i + 1] is LSL_Float) 10729 if (commandList.Data[i + 1] is LSL_Float)
@@ -9462,7 +10735,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9462 } 10735 }
9463 break; 10736 break;
9464 10737
9465 case ParcelMediaCommandEnum.AutoAlign: 10738 case (uint)ParcelMediaCommandEnum.AutoAlign:
9466 if ((i + 1) < commandList.Length) 10739 if ((i + 1) < commandList.Length)
9467 { 10740 {
9468 if (commandList.Data[i + 1] is LSL_Integer) 10741 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9476,7 +10749,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9476 } 10749 }
9477 break; 10750 break;
9478 10751
9479 case ParcelMediaCommandEnum.Type: 10752 case (uint)ParcelMediaCommandEnum.Type:
9480 if ((i + 1) < commandList.Length) 10753 if ((i + 1) < commandList.Length)
9481 { 10754 {
9482 if (commandList.Data[i + 1] is LSL_String) 10755 if (commandList.Data[i + 1] is LSL_String)
@@ -9489,7 +10762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9489 } 10762 }
9490 break; 10763 break;
9491 10764
9492 case ParcelMediaCommandEnum.Desc: 10765 case (uint)ParcelMediaCommandEnum.Desc:
9493 if ((i + 1) < commandList.Length) 10766 if ((i + 1) < commandList.Length)
9494 { 10767 {
9495 if (commandList.Data[i + 1] is LSL_String) 10768 if (commandList.Data[i + 1] is LSL_String)
@@ -9502,7 +10775,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9502 } 10775 }
9503 break; 10776 break;
9504 10777
9505 case ParcelMediaCommandEnum.Size: 10778 case (uint)ParcelMediaCommandEnum.Size:
9506 if ((i + 2) < commandList.Length) 10779 if ((i + 2) < commandList.Length)
9507 { 10780 {
9508 if (commandList.Data[i + 1] is LSL_Integer) 10781 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9572,7 +10845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10845 }
9573 } 10846 }
9574 10847
9575 if (commandToSend != null) 10848 if (commandToSend != 0)
9576 { 10849 {
9577 // the commandList contained a start/stop/... command, too 10850 // the commandList contained a start/stop/... command, too
9578 if (presence == null) 10851 if (presence == null)
@@ -9609,7 +10882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 10882
9610 if (aList.Data[i] != null) 10883 if (aList.Data[i] != null)
9611 { 10884 {
9612 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10885 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9613 { 10886 {
9614 case ParcelMediaCommandEnum.Url: 10887 case ParcelMediaCommandEnum.Url:
9615 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10888 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9666,15 +10939,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9666 10939
9667 if (quick_pay_buttons.Data.Length < 4) 10940 if (quick_pay_buttons.Data.Length < 4)
9668 { 10941 {
9669 LSLError("List must have at least 4 elements"); 10942 int x;
9670 return; 10943 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10944 {
10945 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10946 }
9671 } 10947 }
9672 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10948 int[] nPrice = new int[5];
9673 10949 nPrice[0] = price;
9674 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10950 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9675 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10951 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9676 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10952 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9677 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10953 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10954 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9678 m_host.ParentGroup.HasGroupChanged = true; 10955 m_host.ParentGroup.HasGroupChanged = true;
9679 } 10956 }
9680 10957
@@ -9691,7 +10968,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9691 return new LSL_Vector(); 10968 return new LSL_Vector();
9692 } 10969 }
9693 10970
9694 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10971// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10972 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9695 if (presence != null) 10973 if (presence != null)
9696 { 10974 {
9697 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10975 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9713,7 +10991,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9713 return new LSL_Rotation(); 10991 return new LSL_Rotation();
9714 } 10992 }
9715 10993
9716 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10994// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10995 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9717 if (presence != null) 10996 if (presence != null)
9718 { 10997 {
9719 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10998 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9773,8 +11052,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9773 { 11052 {
9774 m_host.AddScriptLPS(1); 11053 m_host.AddScriptLPS(1);
9775 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11054 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9776 if (detectedParams == null) return; // only works on the first detected avatar 11055 if (detectedParams == null)
9777 11056 {
11057 if (m_host.ParentGroup.IsAttachment == true)
11058 {
11059 detectedParams = new DetectParams();
11060 detectedParams.Key = m_host.OwnerID;
11061 }
11062 else
11063 {
11064 return;
11065 }
11066 }
11067
9778 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11068 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9779 if (avatar != null) 11069 if (avatar != null)
9780 { 11070 {
@@ -9782,6 +11072,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11072 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9783 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11073 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9784 } 11074 }
11075
9785 ScriptSleep(1000); 11076 ScriptSleep(1000);
9786 } 11077 }
9787 11078
@@ -9905,12 +11196,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9905 11196
9906 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11197 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9907 object[] data = rules.Data; 11198 object[] data = rules.Data;
9908 for (int i = 0; i < data.Length; ++i) { 11199 for (int i = 0; i < data.Length; ++i)
11200 {
9909 int type = Convert.ToInt32(data[i++].ToString()); 11201 int type = Convert.ToInt32(data[i++].ToString());
9910 if (i >= data.Length) break; // odd number of entries => ignore the last 11202 if (i >= data.Length) break; // odd number of entries => ignore the last
9911 11203
9912 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11204 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9913 switch (type) { 11205 switch (type)
11206 {
9914 case ScriptBaseClass.CAMERA_FOCUS: 11207 case ScriptBaseClass.CAMERA_FOCUS:
9915 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11208 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9916 case ScriptBaseClass.CAMERA_POSITION: 11209 case ScriptBaseClass.CAMERA_POSITION:
@@ -10016,19 +11309,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10016 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11309 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10017 { 11310 {
10018 m_host.AddScriptLPS(1); 11311 m_host.AddScriptLPS(1);
10019 string ret = String.Empty; 11312
10020 string src1 = llBase64ToString(str1); 11313 if (str1 == String.Empty)
10021 string src2 = llBase64ToString(str2); 11314 return String.Empty;
10022 int c = 0; 11315 if (str2 == String.Empty)
10023 for (int i = 0; i < src1.Length; i++) 11316 return str1;
11317
11318 int len = str2.Length;
11319 if ((len % 4) != 0) // LL is EVIL!!!!
10024 { 11320 {
10025 ret += (char) (src1[i] ^ src2[c]); 11321 while (str2.EndsWith("="))
11322 str2 = str2.Substring(0, str2.Length - 1);
11323
11324 len = str2.Length;
11325 int mod = len % 4;
11326
11327 if (mod == 1)
11328 str2 = str2.Substring(0, str2.Length - 1);
11329 else if (mod == 2)
11330 str2 += "==";
11331 else if (mod == 3)
11332 str2 += "=";
11333 }
10026 11334
10027 c++; 11335 byte[] data1;
10028 if (c >= src2.Length) 11336 byte[] data2;
10029 c = 0; 11337 try
11338 {
11339 data1 = Convert.FromBase64String(str1);
11340 data2 = Convert.FromBase64String(str2);
10030 } 11341 }
10031 return llStringToBase64(ret); 11342 catch (Exception)
11343 {
11344 return new LSL_String(String.Empty);
11345 }
11346
11347 byte[] d2 = new Byte[data1.Length];
11348 int pos = 0;
11349
11350 if (data1.Length <= data2.Length)
11351 {
11352 Array.Copy(data2, 0, d2, 0, data1.Length);
11353 }
11354 else
11355 {
11356 while (pos < data1.Length)
11357 {
11358 len = data1.Length - pos;
11359 if (len > data2.Length)
11360 len = data2.Length;
11361
11362 Array.Copy(data2, 0, d2, pos, len);
11363 pos += len;
11364 }
11365 }
11366
11367 for (pos = 0 ; pos < data1.Length ; pos++ )
11368 data1[pos] ^= d2[pos];
11369
11370 return Convert.ToBase64String(data1);
10032 } 11371 }
10033 11372
10034 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11373 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10085,12 +11424,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 Regex r = new Regex(authregex); 11424 Regex r = new Regex(authregex);
10086 int[] gnums = r.GetGroupNumbers(); 11425 int[] gnums = r.GetGroupNumbers();
10087 Match m = r.Match(url); 11426 Match m = r.Match(url);
10088 if (m.Success) { 11427 if (m.Success)
10089 for (int i = 1; i < gnums.Length; i++) { 11428 {
11429 for (int i = 1; i < gnums.Length; i++)
11430 {
10090 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11431 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10091 //CaptureCollection cc = g.Captures; 11432 //CaptureCollection cc = g.Captures;
10092 } 11433 }
10093 if (m.Groups.Count == 5) { 11434 if (m.Groups.Count == 5)
11435 {
10094 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11436 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10095 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11437 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10096 } 11438 }
@@ -10293,6 +11635,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10293 11635
10294 LSL_List ret = new LSL_List(); 11636 LSL_List ret = new LSL_List();
10295 UUID key = new UUID(); 11637 UUID key = new UUID();
11638
11639
10296 if (UUID.TryParse(id, out key)) 11640 if (UUID.TryParse(id, out key))
10297 { 11641 {
10298 ScenePresence av = World.GetScenePresence(key); 11642 ScenePresence av = World.GetScenePresence(key);
@@ -10310,13 +11654,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10310 ret.Add(new LSL_String("")); 11654 ret.Add(new LSL_String(""));
10311 break; 11655 break;
10312 case ScriptBaseClass.OBJECT_POS: 11656 case ScriptBaseClass.OBJECT_POS:
10313 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11657 Vector3 avpos;
11658
11659 if (av.ParentID != 0 && av.ParentPart != null)
11660 {
11661 avpos = av.OffsetPosition;
11662
11663 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11664 avpos -= sitOffset;
11665
11666 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11667 }
11668 else
11669 avpos = av.AbsolutePosition;
11670
11671 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10314 break; 11672 break;
10315 case ScriptBaseClass.OBJECT_ROT: 11673 case ScriptBaseClass.OBJECT_ROT:
10316 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11674 Quaternion avrot = av.Rotation;
11675 if (av.ParentID != 0 && av.ParentPart != null)
11676 {
11677 avrot = av.ParentPart.GetWorldRotation() * avrot;
11678 }
11679 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10317 break; 11680 break;
10318 case ScriptBaseClass.OBJECT_VELOCITY: 11681 case ScriptBaseClass.OBJECT_VELOCITY:
10319 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11682 Vector3 avvel = av.Velocity;
11683 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10320 break; 11684 break;
10321 case ScriptBaseClass.OBJECT_OWNER: 11685 case ScriptBaseClass.OBJECT_OWNER:
10322 ret.Add(new LSL_String(id)); 11686 ret.Add(new LSL_String(id));
@@ -10372,17 +11736,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10372 case ScriptBaseClass.OBJECT_NAME: 11736 case ScriptBaseClass.OBJECT_NAME:
10373 ret.Add(new LSL_String(obj.Name)); 11737 ret.Add(new LSL_String(obj.Name));
10374 break; 11738 break;
10375 case ScriptBaseClass.OBJECT_DESC: 11739 case ScriptBaseClass.OBJECT_DESC:
10376 ret.Add(new LSL_String(obj.Description)); 11740 ret.Add(new LSL_String(obj.Description));
10377 break; 11741 break;
10378 case ScriptBaseClass.OBJECT_POS: 11742 case ScriptBaseClass.OBJECT_POS:
10379 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11743 Vector3 opos = obj.AbsolutePosition;
11744 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10380 break; 11745 break;
10381 case ScriptBaseClass.OBJECT_ROT: 11746 case ScriptBaseClass.OBJECT_ROT:
10382 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11747// Quaternion orot = obj.RotationOffset;
11748// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11749
11750 LSL_Rotation objrot = GetPartRot(obj);
11751 ret.Add(objrot);
10383 break; 11752 break;
10384 case ScriptBaseClass.OBJECT_VELOCITY: 11753 case ScriptBaseClass.OBJECT_VELOCITY:
10385 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11754 Vector3 ovel = obj.Velocity;
11755 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10386 break; 11756 break;
10387 case ScriptBaseClass.OBJECT_OWNER: 11757 case ScriptBaseClass.OBJECT_OWNER:
10388 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11758 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10416,9 +11786,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10416 // The value returned in SL for normal prims is prim count 11786 // The value returned in SL for normal prims is prim count
10417 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11787 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10418 break; 11788 break;
10419 // The following 3 costs I have intentionaly coded to return zero. They are part of 11789
10420 // "Land Impact" calculations. These calculations are probably not applicable 11790 // costs below may need to be diferent for root parts, need to check
10421 // to OpenSim and are not yet complete in SL
10422 case ScriptBaseClass.OBJECT_SERVER_COST: 11791 case ScriptBaseClass.OBJECT_SERVER_COST:
10423 // The linden calculation is here 11792 // The linden calculation is here
10424 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11793 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10426,16 +11795,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10426 ret.Add(new LSL_Float(0)); 11795 ret.Add(new LSL_Float(0));
10427 break; 11796 break;
10428 case ScriptBaseClass.OBJECT_STREAMING_COST: 11797 case ScriptBaseClass.OBJECT_STREAMING_COST:
10429 // The linden calculation is here 11798 // The value returned in SL for normal prims is prim count * 0.06
10430 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11799 ret.Add(new LSL_Float(obj.StreamingCost));
10431 // The value returned in SL for normal prims looks like the prim count * 0.06
10432 ret.Add(new LSL_Float(0));
10433 break; 11800 break;
10434 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11801 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10435 // The linden calculation is here 11802 // The value returned in SL for normal prims is prim count
10436 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11803 ret.Add(new LSL_Float(obj.PhysicsCost));
10437 // The value returned in SL for normal prims looks like the prim count
10438 ret.Add(new LSL_Float(0));
10439 break; 11804 break;
10440 default: 11805 default:
10441 // Invalid or unhandled constant. 11806 // Invalid or unhandled constant.
@@ -10628,15 +11993,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10628 return GetLinkPrimitiveParams(obj, rules); 11993 return GetLinkPrimitiveParams(obj, rules);
10629 } 11994 }
10630 11995
10631 public void print(string str) 11996 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10632 { 11997 {
10633 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11998 List<SceneObjectPart> parts = GetLinkParts(link);
10634 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11999 if (parts.Count < 1)
10635 if (ossl != null) 12000 return 0;
10636 { 12001
10637 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12002 return GetNumberOfSides(parts[0]);
10638 m_log.Info("LSL print():" + str);
10639 }
10640 } 12003 }
10641 12004
10642 private string Name2Username(string name) 12005 private string Name2Username(string name)
@@ -10682,6 +12045,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10682 return rq.ToString(); 12045 return rq.ToString();
10683 } 12046 }
10684 12047
12048 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12049 {
12050 m_SayShoutCount = 0;
12051 }
12052
10685 private struct Tri 12053 private struct Tri
10686 { 12054 {
10687 public Vector3 p1; 12055 public Vector3 p1;
@@ -10821,9 +12189,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10821 12189
10822 ContactResult result = new ContactResult (); 12190 ContactResult result = new ContactResult ();
10823 result.ConsumerID = group.LocalId; 12191 result.ConsumerID = group.LocalId;
10824 result.Depth = intersection.distance; 12192// result.Depth = intersection.distance;
10825 result.Normal = intersection.normal; 12193 result.Normal = intersection.normal;
10826 result.Pos = intersection.ipoint; 12194 result.Pos = intersection.ipoint;
12195 result.Depth = Vector3.Mag(rayStart - result.Pos);
10827 12196
10828 contacts.Add(result); 12197 contacts.Add(result);
10829 }); 12198 });
@@ -10956,6 +12325,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10956 12325
10957 return contacts[0]; 12326 return contacts[0];
10958 } 12327 }
12328/*
12329 // not done:
12330 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12331 {
12332 ContactResult[] contacts = null;
12333 World.ForEachSOG(delegate(SceneObjectGroup group)
12334 {
12335 if (m_host.ParentGroup == group)
12336 return;
12337
12338 if (group.IsAttachment)
12339 return;
12340
12341 if(group.RootPart.PhysActor != null)
12342 return;
12343
12344 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12345 });
12346 return contacts;
12347 }
12348*/
10959 12349
10960 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12350 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10961 { 12351 {
@@ -10997,32 +12387,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10997 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12387 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10998 12388
10999 12389
11000 if (checkTerrain) 12390 if (World.SuportsRayCastFiltered())
11001 { 12391 {
11002 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12392 if (dist == 0)
11003 if (groundContact != null) 12393 return list;
11004 results.Add((ContactResult)groundContact);
11005 }
11006 12394
11007 if (checkAgents) 12395 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11008 { 12396 if (checkTerrain)
11009 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12397 rayfilter |= RayFilterFlags.land;
11010 foreach (ContactResult r in agentHits) 12398// if (checkAgents)
11011 results.Add(r); 12399// rayfilter |= RayFilterFlags.agent;
11012 } 12400 if (checkPhysical)
12401 rayfilter |= RayFilterFlags.physical;
12402 if (checkNonPhysical)
12403 rayfilter |= RayFilterFlags.nonphysical;
12404 if (detectPhantom)
12405 rayfilter |= RayFilterFlags.LSLPhanton;
12406
12407 Vector3 direction = dir * ( 1/dist);
11013 12408
11014 if (checkPhysical || checkNonPhysical || detectPhantom) 12409 if(rayfilter == 0)
12410 {
12411 list.Add(new LSL_Integer(0));
12412 return list;
12413 }
12414
12415 // get some more contacts to sort ???
12416 int physcount = 4 * count;
12417 if (physcount > 20)
12418 physcount = 20;
12419
12420 object physresults;
12421 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12422
12423 if (physresults == null)
12424 {
12425 list.Add(new LSL_Integer(-3)); // timeout error
12426 return list;
12427 }
12428
12429 results = (List<ContactResult>)physresults;
12430
12431 // for now physics doesn't detect sitted avatars so do it outside physics
12432 if (checkAgents)
12433 {
12434 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12435 foreach (ContactResult r in agentHits)
12436 results.Add(r);
12437 }
12438
12439 // TODO: Replace this with a better solution. ObjectIntersection can only
12440 // detect nonphysical phantoms. They are detected by virtue of being
12441 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12442 // physicsl phantoms as done by the physics scene
12443 // We don't want anything else but phantoms here.
12444 if (detectPhantom)
12445 {
12446 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12447 foreach (ContactResult r in objectHits)
12448 results.Add(r);
12449 }
12450 }
12451 else
11015 { 12452 {
11016 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12453 if (checkTerrain)
11017 foreach (ContactResult r in objectHits) 12454 {
11018 results.Add(r); 12455 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12456 if (groundContact != null)
12457 results.Add((ContactResult)groundContact);
12458 }
12459
12460 if (checkAgents)
12461 {
12462 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12463 foreach (ContactResult r in agentHits)
12464 results.Add(r);
12465 }
12466
12467 if (checkPhysical || checkNonPhysical || detectPhantom)
12468 {
12469 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12470 foreach (ContactResult r in objectHits)
12471 results.Add(r);
12472 }
11019 } 12473 }
11020 12474
11021 results.Sort(delegate(ContactResult a, ContactResult b) 12475 results.Sort(delegate(ContactResult a, ContactResult b)
11022 { 12476 {
11023 return a.Depth.CompareTo(b.Depth); 12477 return a.Depth.CompareTo(b.Depth);
11024 }); 12478 });
11025 12479
11026 int values = 0; 12480 int values = 0;
11027 SceneObjectGroup thisgrp = m_host.ParentGroup; 12481 SceneObjectGroup thisgrp = m_host.ParentGroup;
11028 12482
@@ -11115,7 +12569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11115 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12569 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11116 if (!isAccount) return 0; 12570 if (!isAccount) return 0;
11117 if (estate.HasAccess(id)) return 1; 12571 if (estate.HasAccess(id)) return 1;
11118 if (estate.IsBanned(id)) 12572 if (estate.IsBanned(id, World.GetUserFlags(id)))
11119 estate.RemoveBan(id); 12573 estate.RemoveBan(id);
11120 estate.AddEstateUser(id); 12574 estate.AddEstateUser(id);
11121 break; 12575 break;
@@ -11134,14 +12588,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11134 break; 12588 break;
11135 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12589 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11136 if (!isAccount) return 0; 12590 if (!isAccount) return 0;
11137 if (estate.IsBanned(id)) return 1; 12591 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11138 EstateBan ban = new EstateBan(); 12592 EstateBan ban = new EstateBan();
11139 ban.EstateID = estate.EstateID; 12593 ban.EstateID = estate.EstateID;
11140 ban.BannedUserID = id; 12594 ban.BannedUserID = id;
11141 estate.AddBan(ban); 12595 estate.AddBan(ban);
11142 break; 12596 break;
11143 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12597 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11144 if (!isAccount || !estate.IsBanned(id)) return 0; 12598 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11145 estate.RemoveBan(id); 12599 estate.RemoveBan(id);
11146 break; 12600 break;
11147 default: return 0; 12601 default: return 0;
@@ -11170,7 +12624,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11170 return 16384; 12624 return 16384;
11171 } 12625 }
11172 12626
11173 public LSL_Integer llGetUsedMemory() 12627 public virtual LSL_Integer llGetUsedMemory()
11174 { 12628 {
11175 m_host.AddScriptLPS(1); 12629 m_host.AddScriptLPS(1);
11176 // The value returned for LSO scripts in SL 12630 // The value returned for LSO scripts in SL
@@ -11198,7 +12652,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11198 public void llSetSoundQueueing(int queue) 12652 public void llSetSoundQueueing(int queue)
11199 { 12653 {
11200 m_host.AddScriptLPS(1); 12654 m_host.AddScriptLPS(1);
11201 NotImplemented("llSetSoundQueueing");
11202 } 12655 }
11203 12656
11204 public void llCollisionSprite(string impact_sprite) 12657 public void llCollisionSprite(string impact_sprite)
@@ -11210,10 +12663,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11210 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12663 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11211 { 12664 {
11212 m_host.AddScriptLPS(1); 12665 m_host.AddScriptLPS(1);
11213 NotImplemented("llGodLikeRezObject"); 12666
12667 if (!World.Permissions.IsGod(m_host.OwnerID))
12668 NotImplemented("llGodLikeRezObject");
12669
12670 AssetBase rezAsset = World.AssetService.Get(inventory);
12671 if (rezAsset == null)
12672 {
12673 llSay(0, "Asset not found");
12674 return;
12675 }
12676
12677 SceneObjectGroup group = null;
12678
12679 try
12680 {
12681 string xmlData = Utils.BytesToString(rezAsset.Data);
12682 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12683 }
12684 catch
12685 {
12686 llSay(0, "Asset not found");
12687 return;
12688 }
12689
12690 if (group == null)
12691 {
12692 llSay(0, "Asset not found");
12693 return;
12694 }
12695
12696 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12697 group.RootPart.AttachOffset = group.AbsolutePosition;
12698
12699 group.ResetIDs();
12700
12701 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12702 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12703 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12704 group.ScheduleGroupForFullUpdate();
12705
12706 // objects rezzed with this method are die_at_edge by default.
12707 group.RootPart.SetDieAtEdge(true);
12708
12709 group.ResumeScripts();
12710
12711 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12712 "object_rez", new Object[] {
12713 new LSL_String(
12714 group.RootPart.UUID.ToString()) },
12715 new DetectParams[0]));
12716 }
12717
12718 public LSL_String llTransferLindenDollars(string destination, int amount)
12719 {
12720 UUID txn = UUID.Random();
12721
12722 Util.FireAndForget(delegate(object x)
12723 {
12724 int replycode = 0;
12725 string replydata = destination + "," + amount.ToString();
12726
12727 try
12728 {
12729 TaskInventoryItem item = m_item;
12730 if (item == null)
12731 {
12732 replydata = "SERVICE_ERROR";
12733 return;
12734 }
12735
12736 m_host.AddScriptLPS(1);
12737
12738 if (item.PermsGranter == UUID.Zero)
12739 {
12740 replydata = "MISSING_PERMISSION_DEBIT";
12741 return;
12742 }
12743
12744 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12745 {
12746 replydata = "MISSING_PERMISSION_DEBIT";
12747 return;
12748 }
12749
12750 UUID toID = new UUID();
12751
12752 if (!UUID.TryParse(destination, out toID))
12753 {
12754 replydata = "INVALID_AGENT";
12755 return;
12756 }
12757
12758 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12759
12760 if (money == null)
12761 {
12762 replydata = "TRANSFERS_DISABLED";
12763 return;
12764 }
12765
12766 bool result = money.ObjectGiveMoney(
12767 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12768
12769 if (result)
12770 {
12771 replycode = 1;
12772 return;
12773 }
12774
12775 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12776 }
12777 finally
12778 {
12779 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12780 "transaction_result", new Object[] {
12781 new LSL_String(txn.ToString()),
12782 new LSL_Integer(replycode),
12783 new LSL_String(replydata) },
12784 new DetectParams[0]));
12785 }
12786 });
12787
12788 return txn.ToString();
11214 } 12789 }
11215 12790
11216 #endregion 12791 #endregion
12792
12793 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12794 {
12795 SceneObjectGroup group = m_host.ParentGroup;
12796
12797 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12798 return;
12799 if (group.IsAttachment)
12800 return;
12801
12802 if (frames.Data.Length > 0) // We are getting a new motion
12803 {
12804 if (group.RootPart.KeyframeMotion != null)
12805 group.RootPart.KeyframeMotion.Stop();
12806 group.RootPart.KeyframeMotion = null;
12807
12808 int idx = 0;
12809
12810 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12811 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12812
12813 while (idx < options.Data.Length)
12814 {
12815 int option = (int)options.GetLSLIntegerItem(idx++);
12816 int remain = options.Data.Length - idx;
12817
12818 switch (option)
12819 {
12820 case ScriptBaseClass.KFM_MODE:
12821 if (remain < 1)
12822 break;
12823 int modeval = (int)options.GetLSLIntegerItem(idx++);
12824 switch(modeval)
12825 {
12826 case ScriptBaseClass.KFM_FORWARD:
12827 mode = KeyframeMotion.PlayMode.Forward;
12828 break;
12829 case ScriptBaseClass.KFM_REVERSE:
12830 mode = KeyframeMotion.PlayMode.Reverse;
12831 break;
12832 case ScriptBaseClass.KFM_LOOP:
12833 mode = KeyframeMotion.PlayMode.Loop;
12834 break;
12835 case ScriptBaseClass.KFM_PING_PONG:
12836 mode = KeyframeMotion.PlayMode.PingPong;
12837 break;
12838 }
12839 break;
12840 case ScriptBaseClass.KFM_DATA:
12841 if (remain < 1)
12842 break;
12843 int dataval = (int)options.GetLSLIntegerItem(idx++);
12844 data = (KeyframeMotion.DataFormat)dataval;
12845 break;
12846 }
12847 }
12848
12849 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12850
12851 idx = 0;
12852
12853 int elemLength = 2;
12854 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12855 elemLength = 3;
12856
12857 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12858 while (idx < frames.Data.Length)
12859 {
12860 int remain = frames.Data.Length - idx;
12861
12862 if (remain < elemLength)
12863 break;
12864
12865 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12866 frame.Position = null;
12867 frame.Rotation = null;
12868
12869 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12870 {
12871 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12872 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12873 }
12874 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12875 {
12876 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12877 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12878 }
12879
12880 float tempf = (float)frames.GetLSLFloatItem(idx++);
12881 frame.TimeMS = (int)(tempf * 1000.0f);
12882
12883 keyframes.Add(frame);
12884 }
12885
12886 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12887 group.RootPart.KeyframeMotion.Start();
12888 }
12889 else
12890 {
12891 if (group.RootPart.KeyframeMotion == null)
12892 return;
12893
12894 if (options.Data.Length == 0)
12895 {
12896 group.RootPart.KeyframeMotion.Stop();
12897 return;
12898 }
12899
12900 int code = (int)options.GetLSLIntegerItem(0);
12901
12902 int idx = 0;
12903
12904 while (idx < options.Data.Length)
12905 {
12906 int option = (int)options.GetLSLIntegerItem(idx++);
12907 int remain = options.Data.Length - idx;
12908
12909 switch (option)
12910 {
12911 case ScriptBaseClass.KFM_COMMAND:
12912 int cmd = (int)options.GetLSLIntegerItem(idx++);
12913 switch (cmd)
12914 {
12915 case ScriptBaseClass.KFM_CMD_PLAY:
12916 group.RootPart.KeyframeMotion.Start();
12917 break;
12918 case ScriptBaseClass.KFM_CMD_STOP:
12919 group.RootPart.KeyframeMotion.Stop();
12920 break;
12921 case ScriptBaseClass.KFM_CMD_PAUSE:
12922 group.RootPart.KeyframeMotion.Pause();
12923 break;
12924 }
12925 break;
12926 }
12927 }
12928 }
12929 }
11217 } 12930 }
11218 12931
11219 public class NotecardCache 12932 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 e90f577..b639d36 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>
@@ -920,18 +929,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
920 if (target != null) 929 if (target != null)
921 { 930 {
922 UUID animID=UUID.Zero; 931 UUID animID=UUID.Zero;
923 lock (m_host.TaskInventory) 932 m_host.TaskInventory.LockItemsForRead(true);
933 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
924 { 934 {
925 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 935 if (inv.Value.Name == animation)
926 { 936 {
927 if (inv.Value.Name == animation) 937 if (inv.Value.Type == (int)AssetType.Animation)
928 { 938 animID = inv.Value.AssetID;
929 if (inv.Value.Type == (int)AssetType.Animation) 939 continue;
930 animID = inv.Value.AssetID;
931 continue;
932 }
933 } 940 }
934 } 941 }
942 m_host.TaskInventory.LockItemsForRead(false);
935 if (animID == UUID.Zero) 943 if (animID == UUID.Zero)
936 target.Animator.AddAnimation(animation, m_host.UUID); 944 target.Animator.AddAnimation(animation, m_host.UUID);
937 else 945 else
@@ -972,6 +980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
972 else 980 else
973 animID = UUID.Zero; 981 animID = UUID.Zero;
974 } 982 }
983 m_host.TaskInventory.LockItemsForRead(false);
975 984
976 if (animID == UUID.Zero) 985 if (animID == UUID.Zero)
977 target.Animator.RemoveAnimation(animation); 986 target.Animator.RemoveAnimation(animation);
@@ -1792,6 +1801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1801
1793 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1794 { 1803 {
1804 m_host.TaskInventory.LockItemsForRead(true);
1795 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1805 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1796 { 1806 {
1797 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1807 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1799,6 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 assetID = item.AssetID; 1809 assetID = item.AssetID;
1800 } 1810 }
1801 } 1811 }
1812 m_host.TaskInventory.LockItemsForRead(false);
1802 } 1813 }
1803 1814
1804 if (assetID == UUID.Zero) 1815 if (assetID == UUID.Zero)
@@ -2271,7 +2282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2282 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2272 m_host.AddScriptLPS(1); 2283 m_host.AddScriptLPS(1);
2273 2284
2274 return NpcCreate(firstname, lastname, position, notecard, false, false); 2285 return NpcCreate(firstname, lastname, position, notecard, true, false);
2275 } 2286 }
2276 2287
2277 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2288 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2282,24 +2293,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2282 return NpcCreate( 2293 return NpcCreate(
2283 firstname, lastname, position, notecard, 2294 firstname, lastname, position, notecard,
2284 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2295 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2285 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2296 false);
2297// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2286 } 2298 }
2287 2299
2288 private LSL_Key NpcCreate( 2300 private LSL_Key NpcCreate(
2289 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2301 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2290 { 2302 {
2303 if (!owned)
2304 OSSLError("Unowned NPCs are unsupported");
2305
2306 string groupTitle = String.Empty;
2307
2308 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2309 return new LSL_Key(UUID.Zero.ToString());
2310
2311 if (firstname != String.Empty || lastname != String.Empty)
2312 {
2313 if (firstname != "Shown outfit:")
2314 groupTitle = "- NPC -";
2315 }
2316
2291 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2317 INPCModule module = World.RequestModuleInterface<INPCModule>();
2292 if (module != null) 2318 if (module != null)
2293 { 2319 {
2294 AvatarAppearance appearance = null; 2320 AvatarAppearance appearance = null;
2295 2321
2296 UUID id; 2322// UUID id;
2297 if (UUID.TryParse(notecard, out id)) 2323// if (UUID.TryParse(notecard, out id))
2298 { 2324// {
2299 ScenePresence clonePresence = World.GetScenePresence(id); 2325// ScenePresence clonePresence = World.GetScenePresence(id);
2300 if (clonePresence != null) 2326// if (clonePresence != null)
2301 appearance = clonePresence.Appearance; 2327// appearance = clonePresence.Appearance;
2302 } 2328// }
2303 2329
2304 if (appearance == null) 2330 if (appearance == null)
2305 { 2331 {
@@ -2327,6 +2353,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2327 World, 2353 World,
2328 appearance); 2354 appearance);
2329 2355
2356 ScenePresence sp;
2357 if (World.TryGetScenePresence(x, out sp))
2358 {
2359 sp.Grouptitle = groupTitle;
2360 sp.SendAvatarDataToAllAgents();
2361 }
2330 return new LSL_Key(x.ToString()); 2362 return new LSL_Key(x.ToString());
2331 } 2363 }
2332 2364
@@ -2618,16 +2650,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2618 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2650 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2619 m_host.AddScriptLPS(1); 2651 m_host.AddScriptLPS(1);
2620 2652
2621 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2653 ManualResetEvent ev = new ManualResetEvent(false);
2622 if (module != null)
2623 {
2624 UUID npcId = new UUID(npc.m_string);
2625 2654
2626 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2655 Util.FireAndForget(delegate(object x) {
2627 return; 2656 try
2657 {
2658 INPCModule module = World.RequestModuleInterface<INPCModule>();
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2628 2662
2629 module.DeleteNPC(npcId, World); 2663 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2630 } 2664 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2665 {
2666 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2667 return;
2668 }
2669
2670 module.DeleteNPC(npcId, World);
2671 }
2672 }
2673 finally
2674 {
2675 ev.Set();
2676 }
2677 });
2678 ev.WaitOne();
2631 } 2679 }
2632 2680
2633 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2681 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3267,4 +3315,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3267 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3315 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3268 } 3316 }
3269 } 3317 }
3270} \ No newline at end of file 3318}
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 d39b204..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,6 +358,7 @@ 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);
@@ -378,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
378 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
379 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
380 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
381 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
382 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
383 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -421,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
421 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
422 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
423 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
424 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);
425 431
426 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
427 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);
428 } 435 }
429} 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 a0b3bc8..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);
@@ -1713,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1713 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1714 } 1736 }
1715 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1716 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1717 { 1744 {
1718 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1963,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1963 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1964 } 1991 }
1965 1992
1966 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)
1967 { 2004 {
1968 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1969 } 2006 }
1970 } 2007 }
1971} 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 306090e..3797683 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -221,13 +222,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
221 222
222 if (part != null) 223 if (part != null)
223 { 224 {
224 lock (part.TaskInventory) 225 part.TaskInventory.LockItemsForRead(true);
226 if (part.TaskInventory.ContainsKey(ItemID))
225 { 227 {
226 if (part.TaskInventory.ContainsKey(ItemID)) 228 ScriptTask = part.TaskInventory[ItemID];
227 {
228 ScriptTask = part.TaskInventory[ItemID];
229 }
230 } 229 }
230 part.TaskInventory.LockItemsForRead(false);
231 } 231 }
232 232
233 ApiManager am = new ApiManager(); 233 ApiManager am = new ApiManager();
@@ -426,14 +426,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
426 { 426 {
427 int permsMask; 427 int permsMask;
428 UUID permsGranter; 428 UUID permsGranter;
429 lock (part.TaskInventory) 429 part.TaskInventory.LockItemsForRead(true);
430 if (!part.TaskInventory.ContainsKey(ItemID))
430 { 431 {
431 if (!part.TaskInventory.ContainsKey(ItemID)) 432 part.TaskInventory.LockItemsForRead(false);
432 return; 433 return;
433
434 permsGranter = part.TaskInventory[ItemID].PermsGranter;
435 permsMask = part.TaskInventory[ItemID].PermsMask;
436 } 434 }
435 permsGranter = part.TaskInventory[ItemID].PermsGranter;
436 permsMask = part.TaskInventory[ItemID].PermsMask;
437 part.TaskInventory.LockItemsForRead(false);
437 438
438 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 439 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
439 { 440 {
@@ -561,6 +562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 return true; 562 return true;
562 } 563 }
563 564
565 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
564 public void SetState(string state) 566 public void SetState(string state)
565 { 567 {
566 if (state == State) 568 if (state == State)
@@ -572,7 +574,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
572 new DetectParams[0])); 574 new DetectParams[0]));
573 PostEvent(new EventParams("state_entry", new Object[0], 575 PostEvent(new EventParams("state_entry", new Object[0],
574 new DetectParams[0])); 576 new DetectParams[0]));
575 577
576 throw new EventAbortException(); 578 throw new EventAbortException();
577 } 579 }
578 580
@@ -662,45 +664,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
662 /// <returns></returns> 664 /// <returns></returns>
663 public object EventProcessor() 665 public object EventProcessor()
664 { 666 {
667 EventParams data = null;
665 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 668 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
666 if (!Running) 669 if (!Running)
667 return 0; 670 return 0;
668 671
669 lock (m_Script)
670 {
671// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 672// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
672 673
673 if (Suspended) 674 if (Suspended)
674 return 0; 675 return 0;
675
676 EventParams data = null;
677 676
678 lock (EventQueue) 677 lock (EventQueue)
678 {
679 data = (EventParams) EventQueue.Dequeue();
680 if (data == null) // Shouldn't happen
679 { 681 {
680 data = (EventParams)EventQueue.Dequeue(); 682 if (EventQueue.Count > 0 && Running && !ShuttingDown)
681 if (data == null) // Shouldn't happen
682 { 683 {
683 if (EventQueue.Count > 0 && Running && !ShuttingDown) 684 m_CurrentWorkItem = Engine.QueueEventHandler(this);
684 {
685 m_CurrentWorkItem = Engine.QueueEventHandler(this);
686 }
687 else
688 {
689 m_CurrentWorkItem = null;
690 }
691 return 0;
692 } 685 }
693 686 else
694 if (data.EventName == "timer")
695 m_TimerQueued = false;
696 if (data.EventName == "control")
697 { 687 {
698 if (m_ControlEventsInQueue > 0) 688 m_CurrentWorkItem = null;
699 m_ControlEventsInQueue--;
700 } 689 }
701 if (data.EventName == "collision") 690 return 0;
702 m_CollisionInQueue = false;
703 } 691 }
692
693 if (data.EventName == "timer")
694 m_TimerQueued = false;
695 if (data.EventName == "control")
696 {
697 if (m_ControlEventsInQueue > 0)
698 m_ControlEventsInQueue--;
699 }
700 if (data.EventName == "collision")
701 m_CollisionInQueue = false;
702 }
703
704 lock(m_Script)
705 {
704 706
705// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 707// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
706 708
@@ -855,6 +857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
855 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 857 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
856 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 858 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
857 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 859 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
860 part.CollisionSound = UUID.Zero;
858 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 861 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
859 EventQueue.Clear(); 862 EventQueue.Clear();
860 m_Script.ResetVars(); 863 m_Script.ResetVars();
@@ -869,6 +872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
869 new Object[0], new DetectParams[0])); 872 new Object[0], new DetectParams[0]));
870 } 873 }
871 874
875 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
872 public void ApiResetScript() 876 public void ApiResetScript()
873 { 877 {
874 // bool running = Running; 878 // bool running = Running;
@@ -880,6 +884,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
880 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 884 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
881 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 885 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
882 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 886 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
887 part.CollisionSound = UUID.Zero;
883 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 888 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
884 889
885 EventQueue.Clear(); 890 EventQueue.Clear();
@@ -900,10 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
900 905
901 public Dictionary<string, object> GetVars() 906 public Dictionary<string, object> GetVars()
902 { 907 {
903 if (m_Script != null) 908 return m_Script.GetVars();
904 return m_Script.GetVars();
905 else
906 return new Dictionary<string, object>();
907 } 909 }
908 910
909 public void SetVars(Dictionary<string, object> vars) 911 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 efcae94..2886344 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;
@@ -120,6 +121,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
120 private Dictionary<UUID, IScriptInstance> m_Scripts = 121 private Dictionary<UUID, IScriptInstance> m_Scripts =
121 new Dictionary<UUID, IScriptInstance>(); 122 new Dictionary<UUID, IScriptInstance>();
122 123
124 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
125
123 // Maps the asset ID to the assembly 126 // Maps the asset ID to the assembly
124 127
125 private Dictionary<UUID, string> m_Assemblies = 128 private Dictionary<UUID, string> m_Assemblies =
@@ -142,6 +145,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
142 IWorkItemResult m_CurrentCompile = null; 145 IWorkItemResult m_CurrentCompile = null;
143 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 146 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
144 147
148 private void lockScriptsForRead(bool locked)
149 {
150 if (locked)
151 {
152 if (m_scriptsLock.RecursiveReadCount > 0)
153 {
154 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.");
155 m_scriptsLock.ExitReadLock();
156 }
157 if (m_scriptsLock.RecursiveWriteCount > 0)
158 {
159 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
160 m_scriptsLock.ExitWriteLock();
161 }
162
163 while (!m_scriptsLock.TryEnterReadLock(60000))
164 {
165 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.");
166 if (m_scriptsLock.IsWriteLockHeld)
167 {
168 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
169 }
170 }
171 }
172 else
173 {
174 if (m_scriptsLock.RecursiveReadCount > 0)
175 {
176 m_scriptsLock.ExitReadLock();
177 }
178 }
179 }
180 private void lockScriptsForWrite(bool locked)
181 {
182 if (locked)
183 {
184 if (m_scriptsLock.RecursiveReadCount > 0)
185 {
186 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.");
187 m_scriptsLock.ExitReadLock();
188 }
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
192 m_scriptsLock.ExitWriteLock();
193 }
194
195 while (!m_scriptsLock.TryEnterWriteLock(60000))
196 {
197 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.");
198 if (m_scriptsLock.IsWriteLockHeld)
199 {
200 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
201 }
202 }
203 }
204 else
205 {
206 if (m_scriptsLock.RecursiveWriteCount > 0)
207 {
208 m_scriptsLock.ExitWriteLock();
209 }
210 }
211 }
212
145 public string ScriptEngineName 213 public string ScriptEngineName
146 { 214 {
147 get { return "XEngine"; } 215 get { return "XEngine"; }
@@ -567,44 +635,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
567 { 635 {
568 if (!m_Enabled) 636 if (!m_Enabled)
569 return; 637 return;
570 638 lockScriptsForRead(true);
571 lock (m_Scripts) 639 foreach (IScriptInstance instance in m_Scripts.Values)
572 { 640 {
573 m_log.InfoFormat( 641 // Force a final state save
574 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 642 //
575 643 if (m_Assemblies.ContainsKey(instance.AssetID))
576 foreach (IScriptInstance instance in m_Scripts.Values)
577 { 644 {
578 // Force a final state save 645 string assembly = m_Assemblies[instance.AssetID];
579 // 646 instance.SaveState(assembly);
580 if (m_Assemblies.ContainsKey(instance.AssetID)) 647 }
581 {
582 string assembly = m_Assemblies[instance.AssetID];
583 instance.SaveState(assembly);
584 }
585 648
586 // Clear the event queue and abort the instance thread 649 // Clear the event queue and abort the instance thread
587 // 650 //
588 instance.ClearQueue(); 651 instance.ClearQueue();
589 instance.Stop(0); 652 instance.Stop(0);
590 653
591 // Release events, timer, etc 654 // Release events, timer, etc
592 // 655 //
593 instance.DestroyScriptInstance(); 656 instance.DestroyScriptInstance();
594 657
595 // Unload scripts and app domains. 658 // Unload scripts and app domains
596 // Must be done explicitly because they have infinite 659 // Must be done explicitly because they have infinite
597 // lifetime. 660 // lifetime
598 // However, don't bother to do this if the simulator is shutting 661 //
599 // down since it takes a long time with many scripts. 662 if (!m_SimulatorShuttingDown)
600 if (!m_SimulatorShuttingDown) 663 {
664 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
665 if (m_DomainScripts[instance.AppDomain].Count == 0)
601 { 666 {
602 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 667 m_DomainScripts.Remove(instance.AppDomain);
603 if (m_DomainScripts[instance.AppDomain].Count == 0) 668 UnloadAppDomain(instance.AppDomain);
604 {
605 m_DomainScripts.Remove(instance.AppDomain);
606 UnloadAppDomain(instance.AppDomain);
607 }
608 } 669 }
609 } 670 }
610 671
@@ -613,6 +674,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
613 m_Assemblies.Clear(); 674 m_Assemblies.Clear();
614 m_DomainScripts.Clear(); 675 m_DomainScripts.Clear();
615 } 676 }
677 lockScriptsForRead(false);
678 lockScriptsForWrite(true);
679 m_Scripts.Clear();
680 lockScriptsForWrite(false);
681 m_PrimObjects.Clear();
682 m_Assemblies.Clear();
683 m_DomainScripts.Clear();
684
616 lock (m_ScriptEngines) 685 lock (m_ScriptEngines)
617 { 686 {
618 m_ScriptEngines.Remove(this); 687 m_ScriptEngines.Remove(this);
@@ -677,22 +746,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
677 746
678 List<IScriptInstance> instances = new List<IScriptInstance>(); 747 List<IScriptInstance> instances = new List<IScriptInstance>();
679 748
680 lock (m_Scripts) 749 lockScriptsForRead(true);
681 { 750 foreach (IScriptInstance instance in m_Scripts.Values)
682 foreach (IScriptInstance instance in m_Scripts.Values)
683 instances.Add(instance); 751 instances.Add(instance);
684 } 752 lockScriptsForRead(false);
685 753
686 foreach (IScriptInstance i in instances) 754 foreach (IScriptInstance i in instances)
687 { 755 {
688 string assembly = String.Empty; 756 string assembly = String.Empty;
689 757
690 lock (m_Scripts) 758
691 {
692 if (!m_Assemblies.ContainsKey(i.AssetID)) 759 if (!m_Assemblies.ContainsKey(i.AssetID))
693 continue; 760 continue;
694 assembly = m_Assemblies[i.AssetID]; 761 assembly = m_Assemblies[i.AssetID];
695 } 762
696 763
697 i.SaveState(assembly); 764 i.SaveState(assembly);
698 } 765 }
@@ -1079,96 +1146,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1079 } 1146 }
1080 1147
1081 ScriptInstance instance = null; 1148 ScriptInstance instance = null;
1082 lock (m_Scripts) 1149 // Create the object record
1150 lockScriptsForRead(true);
1151 if ((!m_Scripts.ContainsKey(itemID)) ||
1152 (m_Scripts[itemID].AssetID != assetID))
1083 { 1153 {
1084 // Create the object record 1154 lockScriptsForRead(false);
1085 if ((!m_Scripts.ContainsKey(itemID)) ||
1086 (m_Scripts[itemID].AssetID != assetID))
1087 {
1088 UUID appDomain = assetID;
1089 1155
1090 if (part.ParentGroup.IsAttachment) 1156 UUID appDomain = assetID;
1091 appDomain = part.ParentGroup.RootPart.UUID;
1092 1157
1093 if (!m_AppDomains.ContainsKey(appDomain)) 1158 if (part.ParentGroup.IsAttachment)
1094 { 1159 appDomain = part.ParentGroup.RootPart.UUID;
1095 try
1096 {
1097 AppDomainSetup appSetup = new AppDomainSetup();
1098 appSetup.PrivateBinPath = Path.Combine(
1099 m_ScriptEnginesPath,
1100 m_Scene.RegionInfo.RegionID.ToString());
1101 1160
1102 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1161 if (!m_AppDomains.ContainsKey(appDomain))
1103 Evidence evidence = new Evidence(baseEvidence); 1162 {
1163 try
1164 {
1165 AppDomainSetup appSetup = new AppDomainSetup();
1166 appSetup.PrivateBinPath = Path.Combine(
1167 m_ScriptEnginesPath,
1168 m_Scene.RegionInfo.RegionID.ToString());
1104 1169
1105 AppDomain sandbox; 1170 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1106 if (m_AppDomainLoading) 1171 Evidence evidence = new Evidence(baseEvidence);
1107 {
1108 sandbox = AppDomain.CreateDomain(
1109 m_Scene.RegionInfo.RegionID.ToString(),
1110 evidence, appSetup);
1111 sandbox.AssemblyResolve +=
1112 new ResolveEventHandler(
1113 AssemblyResolver.OnAssemblyResolve);
1114 }
1115 else
1116 {
1117 sandbox = AppDomain.CurrentDomain;
1118 }
1119
1120 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1121 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1122 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1123 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1124 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1125 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1126 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1127
1128 m_AppDomains[appDomain] = sandbox;
1129 1172
1130 m_DomainScripts[appDomain] = new List<UUID>(); 1173 AppDomain sandbox;
1174 if (m_AppDomainLoading)
1175 {
1176 sandbox = AppDomain.CreateDomain(
1177 m_Scene.RegionInfo.RegionID.ToString(),
1178 evidence, appSetup);
1179 m_AppDomains[appDomain].AssemblyResolve +=
1180 new ResolveEventHandler(
1181 AssemblyResolver.OnAssemblyResolve);
1131 } 1182 }
1132 catch (Exception e) 1183 else
1133 { 1184 {
1134 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1185 sandbox = AppDomain.CurrentDomain;
1135 m_ScriptErrorMessage += "Exception creating app domain:\n";
1136 m_ScriptFailCount++;
1137 lock (m_AddingAssemblies)
1138 {
1139 m_AddingAssemblies[assembly]--;
1140 }
1141 return false;
1142 } 1186 }
1143 }
1144 m_DomainScripts[appDomain].Add(itemID);
1145
1146 instance = new ScriptInstance(this, part,
1147 itemID, assetID, assembly,
1148 m_AppDomains[appDomain],
1149 part.ParentGroup.RootPart.Name,
1150 item.Name, startParam, postOnRez,
1151 stateSource, m_MaxScriptQueue);
1152
1153// if (DebugLevel >= 1)
1154 m_log.DebugFormat(
1155 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1156 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1157 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1158 1187
1159 if (presence != null) 1188 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1189 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1190 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1191 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1192 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1193 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1194 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1195
1196 m_AppDomains[appDomain] = sandbox;
1197
1198 m_DomainScripts[appDomain] = new List<UUID>();
1199 }
1200 catch (Exception e)
1160 { 1201 {
1161 ShowScriptSaveResponse(item.OwnerID, 1202 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1162 assetID, "Compile successful", true); 1203 m_ScriptErrorMessage += "Exception creating app domain:\n";
1204 m_ScriptFailCount++;
1205 lock (m_AddingAssemblies)
1206 {
1207 m_AddingAssemblies[assembly]--;
1208 }
1209 return false;
1163 } 1210 }
1211 }
1212 m_DomainScripts[appDomain].Add(itemID);
1213
1214 instance = new ScriptInstance(this, part,
1215 itemID, assetID, assembly,
1216 m_AppDomains[appDomain],
1217 part.ParentGroup.RootPart.Name,
1218 item.Name, startParam, postOnRez,
1219 stateSource, m_MaxScriptQueue);
1220
1221 m_log.DebugFormat(
1222 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1223 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1224 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1164 1225
1165 instance.AppDomain = appDomain; 1226 if (presence != null)
1166 instance.LineMap = linemap; 1227 {
1167 1228 ShowScriptSaveResponse(item.OwnerID,
1168 m_Scripts[itemID] = instance; 1229 assetID, "Compile successful", true);
1169 } 1230 }
1170 }
1171 1231
1232 instance.AppDomain = appDomain;
1233 instance.LineMap = linemap;
1234 lockScriptsForWrite(true);
1235 m_Scripts[itemID] = instance;
1236 lockScriptsForWrite(false);
1237 }
1238 else
1239 {
1240 lockScriptsForRead(false);
1241 }
1172 lock (m_PrimObjects) 1242 lock (m_PrimObjects)
1173 { 1243 {
1174 if (!m_PrimObjects.ContainsKey(localID)) 1244 if (!m_PrimObjects.ContainsKey(localID))
@@ -1186,9 +1256,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1186 m_AddingAssemblies[assembly]--; 1256 m_AddingAssemblies[assembly]--;
1187 } 1257 }
1188 1258
1189 if (instance != null) 1259 if (instance!=null)
1190 instance.Init(); 1260 instance.Init();
1191 1261
1192 return true; 1262 return true;
1193 } 1263 }
1194 1264
@@ -1201,18 +1271,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1201 m_CompileDict.Remove(itemID); 1271 m_CompileDict.Remove(itemID);
1202 } 1272 }
1203 1273
1204 IScriptInstance instance = null; 1274 lockScriptsForRead(true);
1205 1275 // Do we even have it?
1206 lock (m_Scripts) 1276 if (!m_Scripts.ContainsKey(itemID))
1207 { 1277 {
1208 // Do we even have it? 1278 // Do we even have it?
1209 if (!m_Scripts.ContainsKey(itemID)) 1279 if (!m_Scripts.ContainsKey(itemID))
1210 return; 1280 return;
1211 1281
1212 instance = m_Scripts[itemID]; 1282 lockScriptsForRead(false);
1283 lockScriptsForWrite(true);
1213 m_Scripts.Remove(itemID); 1284 m_Scripts.Remove(itemID);
1285 lockScriptsForWrite(false);
1286
1287 return;
1214 } 1288 }
1289
1215 1290
1291 IScriptInstance instance=m_Scripts[itemID];
1292 lockScriptsForRead(false);
1293 lockScriptsForWrite(true);
1294 m_Scripts.Remove(itemID);
1295 lockScriptsForWrite(false);
1216 instance.ClearQueue(); 1296 instance.ClearQueue();
1217 1297
1218 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1298 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1251,8 +1331,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1251 1331
1252 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1332 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1253 if (handlerObjectRemoved != null) 1333 if (handlerObjectRemoved != null)
1254 handlerObjectRemoved(instance.ObjectID); 1334 {
1335 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1336 handlerObjectRemoved(part.UUID);
1337 }
1255 1338
1339 CleanAssemblies();
1340
1256 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1341 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1257 if (handlerScriptRemoved != null) 1342 if (handlerScriptRemoved != null)
1258 handlerScriptRemoved(itemID); 1343 handlerScriptRemoved(itemID);
@@ -1513,12 +1598,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1513 private IScriptInstance GetInstance(UUID itemID) 1598 private IScriptInstance GetInstance(UUID itemID)
1514 { 1599 {
1515 IScriptInstance instance; 1600 IScriptInstance instance;
1516 lock (m_Scripts) 1601 lockScriptsForRead(true);
1602 if (!m_Scripts.ContainsKey(itemID))
1517 { 1603 {
1518 if (!m_Scripts.ContainsKey(itemID)) 1604 lockScriptsForRead(false);
1519 return null; 1605 return null;
1520 instance = m_Scripts[itemID];
1521 } 1606 }
1607 instance = m_Scripts[itemID];
1608 lockScriptsForRead(false);
1522 return instance; 1609 return instance;
1523 } 1610 }
1524 1611
@@ -1549,6 +1636,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1549 return false; 1636 return false;
1550 } 1637 }
1551 1638
1639 [DebuggerNonUserCode]
1552 public void ApiResetScript(UUID itemID) 1640 public void ApiResetScript(UUID itemID)
1553 { 1641 {
1554 IScriptInstance instance = GetInstance(itemID); 1642 IScriptInstance instance = GetInstance(itemID);
@@ -1604,6 +1692,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1604 return UUID.Zero; 1692 return UUID.Zero;
1605 } 1693 }
1606 1694
1695 [DebuggerNonUserCode]
1607 public void SetState(UUID itemID, string newState) 1696 public void SetState(UUID itemID, string newState)
1608 { 1697 {
1609 IScriptInstance instance = GetInstance(itemID); 1698 IScriptInstance instance = GetInstance(itemID);
@@ -1626,11 +1715,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1626 1715
1627 List<IScriptInstance> instances = new List<IScriptInstance>(); 1716 List<IScriptInstance> instances = new List<IScriptInstance>();
1628 1717
1629 lock (m_Scripts) 1718 lockScriptsForRead(true);
1630 { 1719 foreach (IScriptInstance instance in m_Scripts.Values)
1631 foreach (IScriptInstance instance in m_Scripts.Values)
1632 instances.Add(instance); 1720 instances.Add(instance);
1633 } 1721 lockScriptsForRead(false);
1634 1722
1635 foreach (IScriptInstance i in instances) 1723 foreach (IScriptInstance i in instances)
1636 { 1724 {