aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3155
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs9
-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.cs8
-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.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs41
-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.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
18 files changed, 2767 insertions, 1033 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..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
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 uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c38a52e..a95dd63 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{
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -156,6 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
156 get { return m_ScriptEngine.World; } 170 get { return m_ScriptEngine.World; }
157 } 171 }
158 172
173 [DebuggerNonUserCode]
159 public void state(string newState) 174 public void state(string newState)
160 { 175 {
161 m_ScriptEngine.SetState(m_itemID, newState); 176 m_ScriptEngine.SetState(m_itemID, newState);
@@ -165,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
165 /// Reset the named script. The script must be present 180 /// Reset the named script. The script must be present
166 /// in the same prim. 181 /// in the same prim.
167 /// </summary> 182 /// </summary>
183 [DebuggerNonUserCode]
168 public void llResetScript() 184 public void llResetScript()
169 { 185 {
170 m_host.AddScriptLPS(1); 186 m_host.AddScriptLPS(1);
@@ -221,9 +237,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 } 237 }
222 } 238 }
223 239
240 public List<ScenePresence> GetLinkAvatars(int linkType)
241 {
242 List<ScenePresence> ret = new List<ScenePresence>();
243 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
244 return ret;
245
246 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
247
248 switch (linkType)
249 {
250 case ScriptBaseClass.LINK_SET:
251 return avs;
252
253 case ScriptBaseClass.LINK_ROOT:
254 return ret;
255
256 case ScriptBaseClass.LINK_ALL_OTHERS:
257 return avs;
258
259 case ScriptBaseClass.LINK_ALL_CHILDREN:
260 return avs;
261
262 case ScriptBaseClass.LINK_THIS:
263 return ret;
264
265 default:
266 if (linkType < 0)
267 return ret;
268
269 int partCount = m_host.ParentGroup.GetPartCount();
270
271 if (linkType <= partCount)
272 {
273 return ret;
274 }
275 else
276 {
277 linkType = linkType - partCount;
278 if (linkType > avs.Count)
279 {
280 return ret;
281 }
282 else
283 {
284 ret.Add(avs[linkType-1]);
285 return ret;
286 }
287 }
288 }
289 }
290
224 public List<SceneObjectPart> GetLinkParts(int linkType) 291 public List<SceneObjectPart> GetLinkParts(int linkType)
225 { 292 {
226 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 293 List<SceneObjectPart> ret = new List<SceneObjectPart>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
227 ret.Add(m_host); 296 ret.Add(m_host);
228 297
229 switch (linkType) 298 switch (linkType)
@@ -270,40 +339,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
270 protected UUID InventorySelf() 339 protected UUID InventorySelf()
271 { 340 {
272 UUID invItemID = new UUID(); 341 UUID invItemID = new UUID();
273 342 bool unlock = false;
274 lock (m_host.TaskInventory) 343 if (!m_host.TaskInventory.IsReadLockedByMe())
275 { 344 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
349 {
350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
277 { 351 {
278 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 352 invItemID = inv.Key;
279 { 353 break;
280 invItemID = inv.Key;
281 break;
282 }
283 } 354 }
284 } 355 }
285 356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
286 return invItemID; 360 return invItemID;
287 } 361 }
288 362
289 protected UUID InventoryKey(string name, int type) 363 protected UUID InventoryKey(string name, int type)
290 { 364 {
291 m_host.AddScriptLPS(1); 365 m_host.AddScriptLPS(1);
292 366 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 369 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 370 if (inv.Value.Name == name)
296 { 371 {
297 if (inv.Value.Name == name) 372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
298 { 375 {
299 if (inv.Value.Type != type) 376 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 377 }
378
379 return inv.Value.AssetID;
304 } 380 }
305 } 381 }
306 382
383 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 384 return UUID.Zero;
308 } 385 }
309 386
@@ -311,17 +388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 388 {
312 m_host.AddScriptLPS(1); 389 m_host.AddScriptLPS(1);
313 390
314 lock (m_host.TaskInventory) 391
392 m_host.TaskInventory.LockItemsForRead(true);
393
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 395 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 396 if (inv.Value.Name == name)
317 { 397 {
318 if (inv.Value.Name == name) 398 m_host.TaskInventory.LockItemsForRead(false);
319 { 399 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 400 }
323 } 401 }
324 402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
325 return UUID.Zero; 406 return UUID.Zero;
326 } 407 }
327 408
@@ -463,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 544
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 546
466 /// <summary> 547 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 548
468 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 550 protected double NormalizeAngle(double angle)
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
475 public LSL_Vector llRot2Euler(LSL_Rotation r)
476 { 551 {
477 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
478 554
479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 555 int numPis = (int)(Math.PI / angle);
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
481 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
482 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
483 double sin = v.x / m; 559 return remainder;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
485 double y = Math.Asin(sin);
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
487 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)));
488 double z = Math.Atan2(v.y, v.x);
489 561
490 return new LSL_Vector(x, y, z); 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
563 {
564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
566
567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
491 } 589 }
492 590
493 /* From wiki: 591 /* From wiki:
@@ -689,77 +787,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 787 {
690 //A and B should both be normalized 788 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 789 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 790 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 791 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 792
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 793 double dotProduct = LSL_Vector.Dot(a, b);
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
796 double angle = Math.Acos(dotProduct / magProduct);
797 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
798 double s = Math.Sin(angle / 2);
799
800 double x = axis.x * s;
801 double y = axis.y * s;
802 double z = axis.z * s;
803 double w = Math.Cos(angle / 2);
804
805 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
806 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
807
808 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
809 */
810
811 // This method mimics the 180 errors found in SL
812 // See www.euclideanspace.com... angleBetween
813 LSL_Vector vec_a = a;
814 LSL_Vector vec_b = b;
815
816 // Eliminate zero length
817 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
818 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
819 if (vec_a_mag < 0.00001 ||
820 vec_b_mag < 0.00001)
696 { 821 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 823 }
699 else 824
825 // Normalize
826 vec_a = llVecNorm(vec_a);
827 vec_b = llVecNorm(vec_b);
828
829 // Calculate axis and rotation angle
830 LSL_Vector axis = vec_a % vec_b;
831 LSL_Float cos_theta = vec_a * vec_b;
832
833 // Check if parallel
834 if (cos_theta > 0.99999)
700 { 835 {
701 a = LSL_Vector.Norm(a); 836 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 837 }
703 double dotProduct = LSL_Vector.Dot(a, b); 838
704 // There are two degenerate cases possible. These are for vectors 180 or 839 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 840 else if (cos_theta < -0.99999)
706 // 841 {
707 // Check for vectors 180 degrees apart. 842 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 843 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 844 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 845 }
711 // First assume X axis is orthogonal to the vectors. 846 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 847 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 848 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 849 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 850 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 851 s = Math.Cos(theta);
717 { 852 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 853 x = axis.x * t;
719 } 854 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 855 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 856 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 857 }
760 return rotBetween;
761 } 858 }
762 859
763 public void llWhisper(int channelID, string text) 860 public void llWhisper(int channelID, string text)
764 { 861 {
765 m_host.AddScriptLPS(1); 862 m_host.AddScriptLPS(1);
@@ -779,6 +876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 876 {
780 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
781 878
879 if (channelID == 0)
880 m_SayShoutCount++;
881
882 if (m_SayShoutCount >= 11)
883 ScriptSleep(2000);
884
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 885 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 886 {
784 Console.WriteLine(text); 887 Console.WriteLine(text);
@@ -801,6 +904,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 904 {
802 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
803 906
907 if (channelID == 0)
908 m_SayShoutCount++;
909
910 if (m_SayShoutCount >= 11)
911 ScriptSleep(2000);
912
804 if (text.Length > 1023) 913 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 914 text = text.Substring(0, 1023);
806 915
@@ -1101,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1102 } 1211 }
1103 1212
1213 [DebuggerNonUserCode]
1104 public virtual void llDie() 1214 public virtual void llDie()
1105 { 1215 {
1106 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1217 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1218 }
1109 1219
1110 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1287
1178 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1179 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1180 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1181 1293
1182 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -1408,6 +1520,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1408 { 1520 {
1409 m_host.AddScriptLPS(1); 1521 m_host.AddScriptLPS(1);
1410 1522
1523 SetColor(m_host, color, face);
1524 }
1525
1526 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1527 {
1528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1529 return;
1530
1531 Primitive.TextureEntry tex = part.Shape.Textures;
1532 Color4 texcolor;
1533 if (face >= 0 && face < GetNumberOfSides(part))
1534 {
1535 texcolor = tex.CreateFace((uint)face).RGBA;
1536 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1537 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1538 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1539 tex.FaceTextures[face].RGBA = texcolor;
1540 part.UpdateTextureEntry(tex.GetBytes());
1541 return;
1542 }
1543 else if (face == ScriptBaseClass.ALL_SIDES)
1544 {
1545 for (uint i = 0; i < GetNumberOfSides(part); i++)
1546 {
1547 if (tex.FaceTextures[i] != null)
1548 {
1549 texcolor = tex.FaceTextures[i].RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[i].RGBA = texcolor;
1554 }
1555 texcolor = tex.DefaultTexture.RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.DefaultTexture.RGBA = texcolor;
1560 }
1561 part.UpdateTextureEntry(tex.GetBytes());
1562 return;
1563 }
1564
1411 if (face == ScriptBaseClass.ALL_SIDES) 1565 if (face == ScriptBaseClass.ALL_SIDES)
1412 face = SceneObjectPart.ALL_SIDES; 1566 face = SceneObjectPart.ALL_SIDES;
1413 1567
@@ -1416,6 +1570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 1570
1417 public void SetTexGen(SceneObjectPart part, int face,int style) 1571 public void SetTexGen(SceneObjectPart part, int face,int style)
1418 { 1572 {
1573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1574 return;
1575
1419 Primitive.TextureEntry tex = part.Shape.Textures; 1576 Primitive.TextureEntry tex = part.Shape.Textures;
1420 MappingType textype; 1577 MappingType textype;
1421 textype = MappingType.Default; 1578 textype = MappingType.Default;
@@ -1446,6 +1603,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1446 1603
1447 public void SetGlow(SceneObjectPart part, int face, float glow) 1604 public void SetGlow(SceneObjectPart part, int face, float glow)
1448 { 1605 {
1606 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1607 return;
1608
1449 Primitive.TextureEntry tex = part.Shape.Textures; 1609 Primitive.TextureEntry tex = part.Shape.Textures;
1450 if (face >= 0 && face < GetNumberOfSides(part)) 1610 if (face >= 0 && face < GetNumberOfSides(part))
1451 { 1611 {
@@ -1471,6 +1631,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 1631
1472 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1632 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1473 { 1633 {
1634 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1635 return;
1474 1636
1475 Shininess sval = new Shininess(); 1637 Shininess sval = new Shininess();
1476 1638
@@ -1521,6 +1683,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 1683
1522 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1684 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1523 { 1685 {
1686 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1687 return;
1688
1524 Primitive.TextureEntry tex = part.Shape.Textures; 1689 Primitive.TextureEntry tex = part.Shape.Textures;
1525 if (face >= 0 && face < GetNumberOfSides(part)) 1690 if (face >= 0 && face < GetNumberOfSides(part))
1526 { 1691 {
@@ -1581,13 +1746,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1581 m_host.AddScriptLPS(1); 1746 m_host.AddScriptLPS(1);
1582 1747
1583 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1748 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1584 1749 if (parts.Count > 0)
1585 foreach (SceneObjectPart part in parts) 1750 {
1586 SetAlpha(part, alpha, face); 1751 try
1752 {
1753 parts[0].ParentGroup.areUpdatesSuspended = true;
1754 foreach (SceneObjectPart part in parts)
1755 SetAlpha(part, alpha, face);
1756 }
1757 finally
1758 {
1759 parts[0].ParentGroup.areUpdatesSuspended = false;
1760 }
1761 }
1587 } 1762 }
1588 1763
1589 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1764 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1590 { 1765 {
1766 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1767 return;
1768
1591 Primitive.TextureEntry tex = part.Shape.Textures; 1769 Primitive.TextureEntry tex = part.Shape.Textures;
1592 Color4 texcolor; 1770 Color4 texcolor;
1593 if (face >= 0 && face < GetNumberOfSides(part)) 1771 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1640,7 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1640 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1818 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1641 float wind, float tension, LSL_Vector Force) 1819 float wind, float tension, LSL_Vector Force)
1642 { 1820 {
1643 if (part == null) 1821 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return; 1822 return;
1645 1823
1646 if (flexi) 1824 if (flexi)
@@ -1674,7 +1852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1674 /// <param name="falloff"></param> 1852 /// <param name="falloff"></param>
1675 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1853 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1676 { 1854 {
1677 if (part == null) 1855 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1678 return; 1856 return;
1679 1857
1680 if (light) 1858 if (light)
@@ -1751,15 +1929,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1751 m_host.AddScriptLPS(1); 1929 m_host.AddScriptLPS(1);
1752 1930
1753 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1931 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1754 1932 if (parts.Count > 0)
1755 foreach (SceneObjectPart part in parts) 1933 {
1756 SetTexture(part, texture, face); 1934 try
1757 1935 {
1936 parts[0].ParentGroup.areUpdatesSuspended = true;
1937 foreach (SceneObjectPart part in parts)
1938 SetTexture(part, texture, face);
1939 }
1940 finally
1941 {
1942 parts[0].ParentGroup.areUpdatesSuspended = false;
1943 }
1944 }
1758 ScriptSleep(200); 1945 ScriptSleep(200);
1759 } 1946 }
1760 1947
1761 protected void SetTexture(SceneObjectPart part, string texture, int face) 1948 protected void SetTexture(SceneObjectPart part, string texture, int face)
1762 { 1949 {
1950 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1951 return;
1952
1763 UUID textureID = new UUID(); 1953 UUID textureID = new UUID();
1764 1954
1765 textureID = InventoryKey(texture, (int)AssetType.Texture); 1955 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1804,6 +1994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 1994
1805 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1995 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1806 { 1996 {
1997 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1998 return;
1999
1807 Primitive.TextureEntry tex = part.Shape.Textures; 2000 Primitive.TextureEntry tex = part.Shape.Textures;
1808 if (face >= 0 && face < GetNumberOfSides(part)) 2001 if (face >= 0 && face < GetNumberOfSides(part))
1809 { 2002 {
@@ -1840,6 +2033,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1840 2033
1841 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2034 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1842 { 2035 {
2036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2037 return;
2038
1843 Primitive.TextureEntry tex = part.Shape.Textures; 2039 Primitive.TextureEntry tex = part.Shape.Textures;
1844 if (face >= 0 && face < GetNumberOfSides(part)) 2040 if (face >= 0 && face < GetNumberOfSides(part))
1845 { 2041 {
@@ -1876,6 +2072,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1876 2072
1877 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2073 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1878 { 2074 {
2075 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2076 return;
2077
1879 Primitive.TextureEntry tex = part.Shape.Textures; 2078 Primitive.TextureEntry tex = part.Shape.Textures;
1880 if (face >= 0 && face < GetNumberOfSides(part)) 2079 if (face >= 0 && face < GetNumberOfSides(part))
1881 { 2080 {
@@ -1980,26 +2179,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 return real_vec; 2179 return real_vec;
1981 } 2180 }
1982 2181
2182 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2183 {
2184 return new LSL_Integer(SetRegionPos(m_host, pos));
2185 }
2186
2187 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2188 {
2189 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2190 return 0;
2191
2192 SceneObjectGroup grp = part.ParentGroup;
2193
2194 if (grp.IsAttachment)
2195 return 0;
2196
2197 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2198 return 0;
2199
2200 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)
2201 return 0;
2202
2203 float constrainedX = (float)targetPos.x;
2204 float constrainedY = (float)targetPos.y;
2205
2206 if (constrainedX < 0.0f)
2207 constrainedX = 0.0f;
2208 if (constrainedY < 0.0f)
2209 constrainedY = 0.0f;
2210 if (constrainedX >= (float)Constants.RegionSize)
2211 constrainedX = (float)Constants.RegionSize - 0.1f;
2212 if (constrainedY >= (float)Constants.RegionSize)
2213 constrainedY = (float)Constants.RegionSize -0.1f;
2214
2215 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2216
2217 if (targetPos.z < ground)
2218 targetPos.z = ground;
2219
2220 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2221
2222 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2223 return 0;
2224
2225 grp.UpdateGroupPosition(dest);
2226
2227 return 1;
2228 }
2229
1983 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2230 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1984 { 2231 {
1985 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2232 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2233 return;
2234
1986 LSL_Vector currentPos = GetPartLocalPos(part); 2235 LSL_Vector currentPos = GetPartLocalPos(part);
2236 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1987 2237
1988 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1989 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1990 2238
1991 if (part.ParentGroup.RootPart == part) 2239 if (part.ParentGroup.RootPart == part)
1992 { 2240 {
1993 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1994 targetPos.z = ground;
1995 SceneObjectGroup parent = part.ParentGroup; 2241 SceneObjectGroup parent = part.ParentGroup;
1996 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2242 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1997 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2243 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2244 return;
2245 Util.FireAndForget(delegate(object x) {
2246 parent.UpdateGroupPosition(dest);
2247 });
1998 } 2248 }
1999 else 2249 else
2000 { 2250 {
2001 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2251 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2002 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2003 SceneObjectGroup parent = part.ParentGroup; 2252 SceneObjectGroup parent = part.ParentGroup;
2004 parent.HasGroupChanged = true; 2253 parent.HasGroupChanged = true;
2005 parent.ScheduleGroupForTerseUpdate(); 2254 parent.ScheduleGroupForTerseUpdate();
@@ -2031,9 +2280,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2031 } 2280 }
2032 else 2281 else
2033 { 2282 {
2034 if (part.ParentGroup.IsAttachment) 2283 if (part.IsRoot)
2035 { 2284 {
2036 pos = part.AttachedPos; 2285 return new LSL_Vector(part.AttachedPos.X,
2286 part.AttachedPos.Y,
2287 part.AttachedPos.Z);
2037 } 2288 }
2038 else 2289 else
2039 { 2290 {
@@ -2051,9 +2302,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 m_host.AddScriptLPS(1); 2302 m_host.AddScriptLPS(1);
2052 2303
2053 // try to let this work as in SL... 2304 // try to let this work as in SL...
2054 if (m_host.ParentID == 0) 2305 if (m_host.LinkNum < 2)
2055 { 2306 {
2056 // special case: If we are root, rotate complete SOG to new rotation 2307 // Special case: If we are root, rotate complete SOG to new
2308 // rotation.
2309 // We are root if the link number is 0 (single prim) or 1
2310 // (root prim). ParentID may be nonzero in attachments and
2311 // using it would cause attachments and HUDs to rotate
2312 // to the wrong positions.
2057 SetRot(m_host, Rot2Quaternion(rot)); 2313 SetRot(m_host, Rot2Quaternion(rot));
2058 } 2314 }
2059 else 2315 else
@@ -2078,6 +2334,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2078 2334
2079 protected void SetRot(SceneObjectPart part, Quaternion rot) 2335 protected void SetRot(SceneObjectPart part, Quaternion rot)
2080 { 2336 {
2337 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2338 return;
2339
2081 part.UpdateRotation(rot); 2340 part.UpdateRotation(rot);
2082 // Update rotation does not move the object in the physics scene if it's a linkset. 2341 // Update rotation does not move the object in the physics scene if it's a linkset.
2083 2342
@@ -2232,13 +2491,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2491 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2233 { 2492 {
2234 m_host.AddScriptLPS(1); 2493 m_host.AddScriptLPS(1);
2235 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2494 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2236 } 2495 }
2237 2496
2238 public void llSetTorque(LSL_Vector torque, int local) 2497 public void llSetTorque(LSL_Vector torque, int local)
2239 { 2498 {
2240 m_host.AddScriptLPS(1); 2499 m_host.AddScriptLPS(1);
2241 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2500 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2242 } 2501 }
2243 2502
2244 public LSL_Vector llGetTorque() 2503 public LSL_Vector llGetTorque()
@@ -2703,12 +2962,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 2962
2704 m_host.AddScriptLPS(1); 2963 m_host.AddScriptLPS(1);
2705 2964
2965 m_host.TaskInventory.LockItemsForRead(true);
2706 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2966 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2707 2967 m_host.TaskInventory.LockItemsForRead(false);
2708 lock (m_host.TaskInventory)
2709 {
2710 item = m_host.TaskInventory[invItemID];
2711 }
2712 2968
2713 if (item.PermsGranter == UUID.Zero) 2969 if (item.PermsGranter == UUID.Zero)
2714 return 0; 2970 return 0;
@@ -2851,35 +3107,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2851 public void llLookAt(LSL_Vector target, double strength, double damping) 3107 public void llLookAt(LSL_Vector target, double strength, double damping)
2852 { 3108 {
2853 m_host.AddScriptLPS(1); 3109 m_host.AddScriptLPS(1);
2854 // Determine where we are looking from
2855 LSL_Vector from = llGetPos();
2856 3110
2857 // Work out the normalised vector from the source to the target 3111 // Get the normalized vector to the target
2858 LSL_Vector delta = llVecNorm(target - from); 3112 LSL_Vector d1 = llVecNorm(target - llGetPos());
2859 LSL_Vector angle = new LSL_Vector(0,0,0);
2860 3113
2861 // Calculate the yaw 3114 // Get the bearing (yaw)
2862 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3115 LSL_Vector a1 = new LSL_Vector(0,0,0);
2863 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3116 a1.z = llAtan2(d1.y, d1.x);
2864 3117
2865 // Calculate pitch 3118 // Get the elevation (pitch)
2866 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3119 LSL_Vector a2 = new LSL_Vector(0,0,0);
3120 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2867 3121
2868 // we need to convert from a vector describing 3122 LSL_Rotation r1 = llEuler2Rot(a1);
2869 // the angles of rotation in radians into rotation value 3123 LSL_Rotation r2 = llEuler2Rot(a2);
2870 LSL_Rotation rot = llEuler2Rot(angle); 3124 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2871
2872 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2873 // set the rotation of the object, copy that behavior
2874 PhysicsActor pa = m_host.PhysActor;
2875 3125
2876 if (strength == 0 || pa == null || !pa.IsPhysical) 3126 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2877 { 3127 {
2878 llSetRot(rot); 3128 // Do nothing if either value is 0 (this has been checked in SL)
3129 if (strength <= 0.0 || damping <= 0.0)
3130 return;
3131
3132 llSetRot(r3 * r2 * r1);
2879 } 3133 }
2880 else 3134 else
2881 { 3135 {
2882 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3136 if (strength == 0)
3137 {
3138 llSetRot(r3 * r2 * r1);
3139 return;
3140 }
3141
3142 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2883 } 3143 }
2884 } 3144 }
2885 3145
@@ -2953,13 +3213,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 { 3213 {
2954 TaskInventoryItem item; 3214 TaskInventoryItem item;
2955 3215
2956 lock (m_host.TaskInventory) 3216 m_host.TaskInventory.LockItemsForRead(true);
3217 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2957 { 3218 {
2958 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3219 m_host.TaskInventory.LockItemsForRead(false);
2959 return; 3220 return;
2960 else
2961 item = m_host.TaskInventory[InventorySelf()];
2962 } 3221 }
3222 else
3223 {
3224 item = m_host.TaskInventory[InventorySelf()];
3225 }
3226 m_host.TaskInventory.LockItemsForRead(false);
2963 3227
2964 if (item.PermsGranter != UUID.Zero) 3228 if (item.PermsGranter != UUID.Zero)
2965 { 3229 {
@@ -2981,13 +3245,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 { 3245 {
2982 TaskInventoryItem item; 3246 TaskInventoryItem item;
2983 3247
3248 m_host.TaskInventory.LockItemsForRead(true);
2984 lock (m_host.TaskInventory) 3249 lock (m_host.TaskInventory)
2985 { 3250 {
3251
2986 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3252 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3253 {
3254 m_host.TaskInventory.LockItemsForRead(false);
2987 return; 3255 return;
3256 }
2988 else 3257 else
3258 {
2989 item = m_host.TaskInventory[InventorySelf()]; 3259 item = m_host.TaskInventory[InventorySelf()];
3260 }
2990 } 3261 }
3262 m_host.TaskInventory.LockItemsForRead(false);
2991 3263
2992 m_host.AddScriptLPS(1); 3264 m_host.AddScriptLPS(1);
2993 3265
@@ -3019,19 +3291,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 { 3291 {
3020 m_host.AddScriptLPS(1); 3292 m_host.AddScriptLPS(1);
3021 3293
3022// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3023// return;
3024
3025 TaskInventoryItem item; 3294 TaskInventoryItem item;
3026 3295
3027 lock (m_host.TaskInventory) 3296 m_host.TaskInventory.LockItemsForRead(true);
3297
3298 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3028 { 3299 {
3029 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3300 m_host.TaskInventory.LockItemsForRead(false);
3030 return; 3301 return;
3031 else 3302 }
3032 item = m_host.TaskInventory[InventorySelf()]; 3303 else
3304 {
3305 item = m_host.TaskInventory[InventorySelf()];
3033 } 3306 }
3034 3307
3308 m_host.TaskInventory.LockItemsForRead(false);
3309
3035 if (item.PermsGranter != m_host.OwnerID) 3310 if (item.PermsGranter != m_host.OwnerID)
3036 return; 3311 return;
3037 3312
@@ -3056,13 +3331,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 3331
3057 TaskInventoryItem item; 3332 TaskInventoryItem item;
3058 3333
3059 lock (m_host.TaskInventory) 3334 m_host.TaskInventory.LockItemsForRead(true);
3335
3336 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3060 { 3337 {
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3338 m_host.TaskInventory.LockItemsForRead(false);
3062 return; 3339 return;
3063 else 3340 }
3064 item = m_host.TaskInventory[InventorySelf()]; 3341 else
3342 {
3343 item = m_host.TaskInventory[InventorySelf()];
3065 } 3344 }
3345 m_host.TaskInventory.LockItemsForRead(false);
3346
3066 3347
3067 if (item.PermsGranter != m_host.OwnerID) 3348 if (item.PermsGranter != m_host.OwnerID)
3068 return; 3349 return;
@@ -3109,6 +3390,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3109 3390
3110 public void llInstantMessage(string user, string message) 3391 public void llInstantMessage(string user, string message)
3111 { 3392 {
3393 UUID result;
3394 if (!UUID.TryParse(user, out result))
3395 {
3396 ShoutError("An invalid key was passed to llInstantMessage");
3397 ScriptSleep(2000);
3398 return;
3399 }
3400
3401
3112 m_host.AddScriptLPS(1); 3402 m_host.AddScriptLPS(1);
3113 3403
3114 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3404 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3123,14 +3413,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 UUID friendTransactionID = UUID.Random(); 3413 UUID friendTransactionID = UUID.Random();
3124 3414
3125 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3415 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3126 3416
3127 GridInstantMessage msg = new GridInstantMessage(); 3417 GridInstantMessage msg = new GridInstantMessage();
3128 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3418 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3129 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3419 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3130 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3420 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3131// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3421// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3132// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3422// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3133 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3423// DateTime dt = DateTime.UtcNow;
3424//
3425// // Ticks from UtcNow, but make it look like local. Evil, huh?
3426// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3427//
3428// try
3429// {
3430// // Convert that to the PST timezone
3431// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3432// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3433// }
3434// catch
3435// {
3436// // No logging here, as it could be VERY spammy
3437// }
3438//
3439// // And make it look local again to fool the unix time util
3440// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3441
3442 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3443
3134 //if (client != null) 3444 //if (client != null)
3135 //{ 3445 //{
3136 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3446 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3144,12 +3454,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3144 msg.message = message.Substring(0, 1024); 3454 msg.message = message.Substring(0, 1024);
3145 else 3455 else
3146 msg.message = message; 3456 msg.message = message;
3147 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3457 msg.dialog = (byte)19; // MessageFromObject
3148 msg.fromGroup = false;// fromGroup; 3458 msg.fromGroup = false;// fromGroup;
3149 msg.offline = (byte)0; //offline; 3459 msg.offline = (byte)0; //offline;
3150 msg.ParentEstateID = 0; //ParentEstateID; 3460 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3151 msg.Position = new Vector3(m_host.AbsolutePosition); 3461 msg.Position = new Vector3(m_host.AbsolutePosition);
3152 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3462 msg.RegionID = World.RegionInfo.RegionID.Guid;
3153 msg.binaryBucket 3463 msg.binaryBucket
3154 = Util.StringToBytes256( 3464 = Util.StringToBytes256(
3155 "{0}/{1}/{2}/{3}", 3465 "{0}/{1}/{2}/{3}",
@@ -3177,7 +3487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 } 3487 }
3178 3488
3179 emailModule.SendEmail(m_host.UUID, address, subject, message); 3489 emailModule.SendEmail(m_host.UUID, address, subject, message);
3180 ScriptSleep(20000); 3490 ScriptSleep(15000);
3181 } 3491 }
3182 3492
3183 public void llGetNextEmail(string address, string subject) 3493 public void llGetNextEmail(string address, string subject)
@@ -3319,14 +3629,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3319 3629
3320 TaskInventoryItem item; 3630 TaskInventoryItem item;
3321 3631
3322 lock (m_host.TaskInventory) 3632 m_host.TaskInventory.LockItemsForRead(true);
3633 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3323 { 3634 {
3324 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3635 m_host.TaskInventory.LockItemsForRead(false);
3325 return; 3636 return;
3326 else
3327 item = m_host.TaskInventory[InventorySelf()];
3328 } 3637 }
3329 3638 else
3639 {
3640 item = m_host.TaskInventory[InventorySelf()];
3641 }
3642 m_host.TaskInventory.LockItemsForRead(false);
3330 if (item.PermsGranter == UUID.Zero) 3643 if (item.PermsGranter == UUID.Zero)
3331 return; 3644 return;
3332 3645
@@ -3356,13 +3669,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3356 3669
3357 TaskInventoryItem item; 3670 TaskInventoryItem item;
3358 3671
3359 lock (m_host.TaskInventory) 3672 m_host.TaskInventory.LockItemsForRead(true);
3673 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3360 { 3674 {
3361 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3675 m_host.TaskInventory.LockItemsForRead(false);
3362 return; 3676 return;
3363 else
3364 item = m_host.TaskInventory[InventorySelf()];
3365 } 3677 }
3678 else
3679 {
3680 item = m_host.TaskInventory[InventorySelf()];
3681 }
3682 m_host.TaskInventory.LockItemsForRead(false);
3683
3366 3684
3367 if (item.PermsGranter == UUID.Zero) 3685 if (item.PermsGranter == UUID.Zero)
3368 return; 3686 return;
@@ -3429,10 +3747,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 3747
3430 TaskInventoryItem item; 3748 TaskInventoryItem item;
3431 3749
3432 lock (m_host.TaskInventory) 3750
3751 m_host.TaskInventory.LockItemsForRead(true);
3752 if (!m_host.TaskInventory.ContainsKey(invItemID))
3753 {
3754 m_host.TaskInventory.LockItemsForRead(false);
3755 return;
3756 }
3757 else
3433 { 3758 {
3434 item = m_host.TaskInventory[invItemID]; 3759 item = m_host.TaskInventory[invItemID];
3435 } 3760 }
3761 m_host.TaskInventory.LockItemsForRead(false);
3436 3762
3437 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3763 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3438 { 3764 {
@@ -3460,15 +3786,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3786 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3461 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3787 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3462 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3788 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3789 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3463 ScriptBaseClass.PERMISSION_ATTACH; 3790 ScriptBaseClass.PERMISSION_ATTACH;
3464 3791
3465 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3792 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3466 { 3793 {
3467 lock (m_host.TaskInventory) 3794 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3795 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3469 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3796 m_host.TaskInventory[invItemID].PermsMask = perm;
3470 m_host.TaskInventory[invItemID].PermsMask = perm; 3797 m_host.TaskInventory.LockItemsForWrite(false);
3471 }
3472 3798
3473 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3799 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3474 "run_time_permissions", new Object[] { 3800 "run_time_permissions", new Object[] {
@@ -3478,28 +3804,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 return; 3804 return;
3479 } 3805 }
3480 } 3806 }
3481 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3807 else
3482 { 3808 {
3483 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3809 bool sitting = false;
3484 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3810 if (m_host.SitTargetAvatar == agentID)
3485 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3811 {
3486 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3812 sitting = true;
3487 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3813 }
3814 else
3815 {
3816 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3817 {
3818 if (p.SitTargetAvatar == agentID)
3819 sitting = true;
3820 }
3821 }
3488 3822
3489 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3823 if (sitting)
3490 { 3824 {
3491 lock (m_host.TaskInventory) 3825 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3826 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3827 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3828 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3829 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3830
3831 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3492 { 3832 {
3833 m_host.TaskInventory.LockItemsForWrite(true);
3493 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3834 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3494 m_host.TaskInventory[invItemID].PermsMask = perm; 3835 m_host.TaskInventory[invItemID].PermsMask = perm;
3495 } 3836 m_host.TaskInventory.LockItemsForWrite(false);
3496 3837
3497 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3838 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3498 "run_time_permissions", new Object[] { 3839 "run_time_permissions", new Object[] {
3499 new LSL_Integer(perm) }, 3840 new LSL_Integer(perm) },
3500 new DetectParams[0])); 3841 new DetectParams[0]));
3501 3842
3502 return; 3843 return;
3844 }
3503 } 3845 }
3504 } 3846 }
3505 3847
@@ -3513,11 +3855,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3513 3855
3514 if (!m_waitingForScriptAnswer) 3856 if (!m_waitingForScriptAnswer)
3515 { 3857 {
3516 lock (m_host.TaskInventory) 3858 m_host.TaskInventory.LockItemsForWrite(true);
3517 { 3859 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3518 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3860 m_host.TaskInventory[invItemID].PermsMask = 0;
3519 m_host.TaskInventory[invItemID].PermsMask = 0; 3861 m_host.TaskInventory.LockItemsForWrite(false);
3520 }
3521 3862
3522 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3863 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3523 m_waitingForScriptAnswer=true; 3864 m_waitingForScriptAnswer=true;
@@ -3552,10 +3893,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3893 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3553 llReleaseControls(); 3894 llReleaseControls();
3554 3895
3555 lock (m_host.TaskInventory) 3896
3556 { 3897 m_host.TaskInventory.LockItemsForWrite(true);
3557 m_host.TaskInventory[invItemID].PermsMask = answer; 3898 m_host.TaskInventory[invItemID].PermsMask = answer;
3558 } 3899 m_host.TaskInventory.LockItemsForWrite(false);
3900
3559 3901
3560 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3902 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3561 "run_time_permissions", new Object[] { 3903 "run_time_permissions", new Object[] {
@@ -3567,16 +3909,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 { 3909 {
3568 m_host.AddScriptLPS(1); 3910 m_host.AddScriptLPS(1);
3569 3911
3570 lock (m_host.TaskInventory) 3912 m_host.TaskInventory.LockItemsForRead(true);
3913
3914 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3571 { 3915 {
3572 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3916 if (item.Type == 10 && item.ItemID == m_itemID)
3573 { 3917 {
3574 if (item.Type == 10 && item.ItemID == m_itemID) 3918 m_host.TaskInventory.LockItemsForRead(false);
3575 { 3919 return item.PermsGranter.ToString();
3576 return item.PermsGranter.ToString();
3577 }
3578 } 3920 }
3579 } 3921 }
3922 m_host.TaskInventory.LockItemsForRead(false);
3580 3923
3581 return UUID.Zero.ToString(); 3924 return UUID.Zero.ToString();
3582 } 3925 }
@@ -3585,19 +3928,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3585 { 3928 {
3586 m_host.AddScriptLPS(1); 3929 m_host.AddScriptLPS(1);
3587 3930
3588 lock (m_host.TaskInventory) 3931 m_host.TaskInventory.LockItemsForRead(true);
3932
3933 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3589 { 3934 {
3590 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3935 if (item.Type == 10 && item.ItemID == m_itemID)
3591 { 3936 {
3592 if (item.Type == 10 && item.ItemID == m_itemID) 3937 int perms = item.PermsMask;
3593 { 3938 if (m_automaticLinkPermission)
3594 int perms = item.PermsMask; 3939 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3595 if (m_automaticLinkPermission) 3940 m_host.TaskInventory.LockItemsForRead(false);
3596 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3941 return perms;
3597 return perms;
3598 }
3599 } 3942 }
3600 } 3943 }
3944 m_host.TaskInventory.LockItemsForRead(false);
3601 3945
3602 return 0; 3946 return 0;
3603 } 3947 }
@@ -3619,9 +3963,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3619 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3963 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3620 { 3964 {
3621 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3965 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3622 3966 if (parts.Count > 0)
3623 foreach (SceneObjectPart part in parts) 3967 {
3624 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3968 try
3969 {
3970 parts[0].ParentGroup.areUpdatesSuspended = true;
3971 foreach (SceneObjectPart part in parts)
3972 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3973 }
3974 finally
3975 {
3976 parts[0].ParentGroup.areUpdatesSuspended = false;
3977 }
3978 }
3625 } 3979 }
3626 3980
3627 public void llCreateLink(string target, int parent) 3981 public void llCreateLink(string target, int parent)
@@ -3634,11 +3988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 return; 3988 return;
3635 3989
3636 TaskInventoryItem item; 3990 TaskInventoryItem item;
3637 lock (m_host.TaskInventory) 3991 m_host.TaskInventory.LockItemsForRead(true);
3638 { 3992 item = m_host.TaskInventory[invItemID];
3639 item = m_host.TaskInventory[invItemID]; 3993 m_host.TaskInventory.LockItemsForRead(false);
3640 } 3994
3641
3642 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3995 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3643 && !m_automaticLinkPermission) 3996 && !m_automaticLinkPermission)
3644 { 3997 {
@@ -3655,11 +4008,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3655 4008
3656 if (targetPart.ParentGroup.AttachmentPoint != 0) 4009 if (targetPart.ParentGroup.AttachmentPoint != 0)
3657 return; // Fail silently if attached 4010 return; // Fail silently if attached
4011
4012 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
4013 return;
4014
3658 SceneObjectGroup parentPrim = null, childPrim = null; 4015 SceneObjectGroup parentPrim = null, childPrim = null;
3659 4016
3660 if (targetPart != null) 4017 if (targetPart != null)
3661 { 4018 {
3662 if (parent != 0) { 4019 if (parent != 0)
4020 {
3663 parentPrim = m_host.ParentGroup; 4021 parentPrim = m_host.ParentGroup;
3664 childPrim = targetPart.ParentGroup; 4022 childPrim = targetPart.ParentGroup;
3665 } 4023 }
@@ -3671,7 +4029,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3671 4029
3672 // Required for linking 4030 // Required for linking
3673 childPrim.RootPart.ClearUpdateSchedule(); 4031 childPrim.RootPart.ClearUpdateSchedule();
3674 parentPrim.LinkToGroup(childPrim); 4032 parentPrim.LinkToGroup(childPrim, true);
3675 } 4033 }
3676 4034
3677 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4035 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3690,16 +4048,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3690 m_host.AddScriptLPS(1); 4048 m_host.AddScriptLPS(1);
3691 UUID invItemID = InventorySelf(); 4049 UUID invItemID = InventorySelf();
3692 4050
3693 lock (m_host.TaskInventory) 4051 m_host.TaskInventory.LockItemsForRead(true);
3694 {
3695 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4052 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3696 && !m_automaticLinkPermission) 4053 && !m_automaticLinkPermission)
3697 { 4054 {
3698 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4055 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4056 m_host.TaskInventory.LockItemsForRead(false);
3699 return; 4057 return;
3700 } 4058 }
3701 } 4059 m_host.TaskInventory.LockItemsForRead(false);
3702 4060
3703 if (linknum < ScriptBaseClass.LINK_THIS) 4061 if (linknum < ScriptBaseClass.LINK_THIS)
3704 return; 4062 return;
3705 4063
@@ -3738,10 +4096,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 // Restructuring Multiple Prims. 4096 // Restructuring Multiple Prims.
3739 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4097 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3740 parts.Remove(parentPrim.RootPart); 4098 parts.Remove(parentPrim.RootPart);
3741 foreach (SceneObjectPart part in parts) 4099 if (parts.Count > 0)
3742 { 4100 {
3743 parentPrim.DelinkFromGroup(part.LocalId, true); 4101 try
4102 {
4103 parts[0].ParentGroup.areUpdatesSuspended = true;
4104 foreach (SceneObjectPart part in parts)
4105 {
4106 parentPrim.DelinkFromGroup(part.LocalId, true);
4107 }
4108 }
4109 finally
4110 {
4111 parts[0].ParentGroup.areUpdatesSuspended = false;
4112 }
3744 } 4113 }
4114
3745 parentPrim.HasGroupChanged = true; 4115 parentPrim.HasGroupChanged = true;
3746 parentPrim.ScheduleGroupForFullUpdate(); 4116 parentPrim.ScheduleGroupForFullUpdate();
3747 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4117 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3750,12 +4120,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 { 4120 {
3751 SceneObjectPart newRoot = parts[0]; 4121 SceneObjectPart newRoot = parts[0];
3752 parts.Remove(newRoot); 4122 parts.Remove(newRoot);
3753 foreach (SceneObjectPart part in parts) 4123
4124 try
3754 { 4125 {
3755 // Required for linking 4126 parts[0].ParentGroup.areUpdatesSuspended = true;
3756 part.ClearUpdateSchedule(); 4127 foreach (SceneObjectPart part in parts)
3757 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4128 {
4129 part.ClearUpdateSchedule();
4130 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4131 }
3758 } 4132 }
4133 finally
4134 {
4135 parts[0].ParentGroup.areUpdatesSuspended = false;
4136 }
4137
4138
3759 newRoot.ParentGroup.HasGroupChanged = true; 4139 newRoot.ParentGroup.HasGroupChanged = true;
3760 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4140 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3761 } 4141 }
@@ -3775,6 +4155,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3775 public void llBreakAllLinks() 4155 public void llBreakAllLinks()
3776 { 4156 {
3777 m_host.AddScriptLPS(1); 4157 m_host.AddScriptLPS(1);
4158
4159 UUID invItemID = InventorySelf();
4160
4161 TaskInventoryItem item;
4162 m_host.TaskInventory.LockItemsForRead(true);
4163 item = m_host.TaskInventory[invItemID];
4164 m_host.TaskInventory.LockItemsForRead(false);
4165
4166 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4167 && !m_automaticLinkPermission)
4168 {
4169 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4170 return;
4171 }
4172
3778 SceneObjectGroup parentPrim = m_host.ParentGroup; 4173 SceneObjectGroup parentPrim = m_host.ParentGroup;
3779 if (parentPrim.AttachmentPoint != 0) 4174 if (parentPrim.AttachmentPoint != 0)
3780 return; // Fail silently if attached 4175 return; // Fail silently if attached
@@ -3794,25 +4189,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3794 public LSL_String llGetLinkKey(int linknum) 4189 public LSL_String llGetLinkKey(int linknum)
3795 { 4190 {
3796 m_host.AddScriptLPS(1); 4191 m_host.AddScriptLPS(1);
3797 List<UUID> keytable = new List<UUID>();
3798 // parse for sitting avatare-uuids
3799 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3800 {
3801 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3802 keytable.Add(presence.UUID);
3803 });
3804
3805 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3806 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3807 {
3808 return keytable[totalprims - linknum].ToString();
3809 }
3810
3811 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3812 {
3813 return m_host.UUID.ToString();
3814 }
3815
3816 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4192 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3817 if (part != null) 4193 if (part != null)
3818 { 4194 {
@@ -3820,6 +4196,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3820 } 4196 }
3821 else 4197 else
3822 { 4198 {
4199 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4200 {
4201 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4202
4203 if (linknum < 0)
4204 return UUID.Zero.ToString();
4205
4206 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4207 if (avatars.Count > linknum)
4208 {
4209 return avatars[linknum].UUID.ToString();
4210 }
4211 }
3823 return UUID.Zero.ToString(); 4212 return UUID.Zero.ToString();
3824 } 4213 }
3825 } 4214 }
@@ -3919,17 +4308,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3919 m_host.AddScriptLPS(1); 4308 m_host.AddScriptLPS(1);
3920 int count = 0; 4309 int count = 0;
3921 4310
3922 lock (m_host.TaskInventory) 4311 m_host.TaskInventory.LockItemsForRead(true);
4312 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3923 { 4313 {
3924 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4314 if (inv.Value.Type == type || type == -1)
3925 { 4315 {
3926 if (inv.Value.Type == type || type == -1) 4316 count = count + 1;
3927 {
3928 count = count + 1;
3929 }
3930 } 4317 }
3931 } 4318 }
3932 4319
4320 m_host.TaskInventory.LockItemsForRead(false);
3933 return count; 4321 return count;
3934 } 4322 }
3935 4323
@@ -3938,16 +4326,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3938 m_host.AddScriptLPS(1); 4326 m_host.AddScriptLPS(1);
3939 ArrayList keys = new ArrayList(); 4327 ArrayList keys = new ArrayList();
3940 4328
3941 lock (m_host.TaskInventory) 4329 m_host.TaskInventory.LockItemsForRead(true);
4330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3942 { 4331 {
3943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4332 if (inv.Value.Type == type || type == -1)
3944 { 4333 {
3945 if (inv.Value.Type == type || type == -1) 4334 keys.Add(inv.Value.Name);
3946 {
3947 keys.Add(inv.Value.Name);
3948 }
3949 } 4335 }
3950 } 4336 }
4337 m_host.TaskInventory.LockItemsForRead(false);
3951 4338
3952 if (keys.Count == 0) 4339 if (keys.Count == 0)
3953 { 4340 {
@@ -3984,25 +4371,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3984 } 4371 }
3985 4372
3986 // move the first object found with this inventory name 4373 // move the first object found with this inventory name
3987 lock (m_host.TaskInventory) 4374 m_host.TaskInventory.LockItemsForRead(true);
4375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3988 { 4376 {
3989 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4377 if (inv.Value.Name == inventory)
3990 { 4378 {
3991 if (inv.Value.Name == inventory) 4379 found = true;
3992 { 4380 objId = inv.Key;
3993 found = true; 4381 assetType = inv.Value.Type;
3994 objId = inv.Key; 4382 objName = inv.Value.Name;
3995 assetType = inv.Value.Type; 4383 break;
3996 objName = inv.Value.Name;
3997 break;
3998 }
3999 } 4384 }
4000 } 4385 }
4386 m_host.TaskInventory.LockItemsForRead(false);
4001 4387
4002 if (!found) 4388 if (!found)
4003 { 4389 {
4004 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4390 llSay(0, String.Format("Could not find object '{0}'", inventory));
4005 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4391 return;
4392// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4006 } 4393 }
4007 4394
4008 // check if destination is an object 4395 // check if destination is an object
@@ -4028,48 +4415,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4028 return; 4415 return;
4029 } 4416 }
4030 } 4417 }
4418
4031 // destination is an avatar 4419 // destination is an avatar
4032 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4420 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4033 4421
4034 if (agentItem == null) 4422 if (agentItem == null)
4035 return; 4423 return;
4036 4424
4037 byte[] bucket = new byte[17]; 4425 byte[] bucket = new byte[1];
4038 bucket[0] = (byte)assetType; 4426 bucket[0] = (byte)assetType;
4039 byte[] objBytes = agentItem.ID.GetBytes(); 4427 //byte[] objBytes = agentItem.ID.GetBytes();
4040 Array.Copy(objBytes, 0, bucket, 1, 16); 4428 //Array.Copy(objBytes, 0, bucket, 1, 16);
4041 4429
4042 GridInstantMessage msg = new GridInstantMessage(World, 4430 GridInstantMessage msg = new GridInstantMessage(World,
4043 m_host.UUID, m_host.Name+", an object owned by "+ 4431 m_host.OwnerID, m_host.Name, destId,
4044 resolveName(m_host.OwnerID)+",", destId,
4045 (byte)InstantMessageDialog.TaskInventoryOffered, 4432 (byte)InstantMessageDialog.TaskInventoryOffered,
4046 false, objName+"\n"+m_host.Name+" is located at "+ 4433 false, objName+". "+m_host.Name+" is located at "+
4047 World.RegionInfo.RegionName+" "+ 4434 World.RegionInfo.RegionName+" "+
4048 m_host.AbsolutePosition.ToString(), 4435 m_host.AbsolutePosition.ToString(),
4049 agentItem.ID, true, m_host.AbsolutePosition, 4436 agentItem.ID, true, m_host.AbsolutePosition,
4050 bucket); 4437 bucket);
4051 if (m_TransferModule != null) 4438
4052 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4439 ScenePresence sp;
4440
4441 if (World.TryGetScenePresence(destId, out sp))
4442 {
4443 sp.ControllingClient.SendInstantMessage(msg);
4444 }
4445 else
4446 {
4447 if (m_TransferModule != null)
4448 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4449 }
4450
4451 //This delay should only occur when giving inventory to avatars.
4053 ScriptSleep(3000); 4452 ScriptSleep(3000);
4054 } 4453 }
4055 } 4454 }
4056 4455
4456 [DebuggerNonUserCode]
4057 public void llRemoveInventory(string name) 4457 public void llRemoveInventory(string name)
4058 { 4458 {
4059 m_host.AddScriptLPS(1); 4459 m_host.AddScriptLPS(1);
4060 4460
4061 lock (m_host.TaskInventory) 4461 List<TaskInventoryItem> inv;
4462 try
4062 { 4463 {
4063 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4464 m_host.TaskInventory.LockItemsForRead(true);
4465 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4466 }
4467 finally
4468 {
4469 m_host.TaskInventory.LockItemsForRead(false);
4470 }
4471 foreach (TaskInventoryItem item in inv)
4472 {
4473 if (item.Name == name)
4064 { 4474 {
4065 if (item.Name == name) 4475 if (item.ItemID == m_itemID)
4066 { 4476 throw new ScriptDeleteException();
4067 if (item.ItemID == m_itemID) 4477 else
4068 throw new ScriptDeleteException(); 4478 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4069 else 4479 return;
4070 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4071 return;
4072 }
4073 } 4480 }
4074 } 4481 }
4075 } 4482 }
@@ -4104,115 +4511,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 { 4511 {
4105 m_host.AddScriptLPS(1); 4512 m_host.AddScriptLPS(1);
4106 4513
4107 UUID uuid = (UUID)id; 4514 UUID uuid;
4108 PresenceInfo pinfo = null; 4515 if (UUID.TryParse(id, out uuid))
4109 UserAccount account;
4110
4111 UserInfoCacheEntry ce;
4112 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4113 { 4516 {
4114 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4517 PresenceInfo pinfo = null;
4115 if (account == null) 4518 UserAccount account;
4519
4520 UserInfoCacheEntry ce;
4521 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4116 { 4522 {
4117 m_userInfoCache[uuid] = null; // Cache negative 4523 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4118 return UUID.Zero.ToString(); 4524 if (account == null)
4119 } 4525 {
4526 m_userInfoCache[uuid] = null; // Cache negative
4527 return UUID.Zero.ToString();
4528 }
4120 4529
4121 4530
4122 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4531 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4123 if (pinfos != null && pinfos.Length > 0) 4532 if (pinfos != null && pinfos.Length > 0)
4124 {
4125 foreach (PresenceInfo p in pinfos)
4126 { 4533 {
4127 if (p.RegionID != UUID.Zero) 4534 foreach (PresenceInfo p in pinfos)
4128 { 4535 {
4129 pinfo = p; 4536 if (p.RegionID != UUID.Zero)
4537 {
4538 pinfo = p;
4539 }
4130 } 4540 }
4131 } 4541 }
4132 }
4133 4542
4134 ce = new UserInfoCacheEntry(); 4543 ce = new UserInfoCacheEntry();
4135 ce.time = Util.EnvironmentTickCount(); 4544 ce.time = Util.EnvironmentTickCount();
4136 ce.account = account; 4545 ce.account = account;
4137 ce.pinfo = pinfo; 4546 ce.pinfo = pinfo;
4138 } 4547 m_userInfoCache[uuid] = ce;
4139 else 4548 }
4140 { 4549 else
4141 if (ce == null) 4550 {
4142 return UUID.Zero.ToString(); 4551 if (ce == null)
4552 return UUID.Zero.ToString();
4143 4553
4144 account = ce.account; 4554 account = ce.account;
4145 pinfo = ce.pinfo; 4555 pinfo = ce.pinfo;
4146 } 4556 }
4147 4557
4148 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4558 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4149 {
4150 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4151 if (pinfos != null && pinfos.Length > 0)
4152 { 4559 {
4153 foreach (PresenceInfo p in pinfos) 4560 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4561 if (pinfos != null && pinfos.Length > 0)
4154 { 4562 {
4155 if (p.RegionID != UUID.Zero) 4563 foreach (PresenceInfo p in pinfos)
4156 { 4564 {
4157 pinfo = p; 4565 if (p.RegionID != UUID.Zero)
4566 {
4567 pinfo = p;
4568 }
4158 } 4569 }
4159 } 4570 }
4160 } 4571 else
4161 else 4572 pinfo = null;
4162 pinfo = null;
4163 4573
4164 ce.time = Util.EnvironmentTickCount(); 4574 ce.time = Util.EnvironmentTickCount();
4165 ce.pinfo = pinfo; 4575 ce.pinfo = pinfo;
4166 } 4576 }
4167 4577
4168 string reply = String.Empty; 4578 string reply = String.Empty;
4169 4579
4170 switch (data) 4580 switch (data)
4171 { 4581 {
4172 case 1: // DATA_ONLINE (0|1) 4582 case 1: // DATA_ONLINE (0|1)
4173 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4583 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4174 reply = "1"; 4584 reply = "1";
4175 else 4585 else
4176 reply = "0"; 4586 reply = "0";
4177 break; 4587 break;
4178 case 2: // DATA_NAME (First Last) 4588 case 2: // DATA_NAME (First Last)
4179 reply = account.FirstName + " " + account.LastName; 4589 reply = account.FirstName + " " + account.LastName;
4180 break; 4590 break;
4181 case 3: // DATA_BORN (YYYY-MM-DD) 4591 case 3: // DATA_BORN (YYYY-MM-DD)
4182 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4592 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4183 born = born.AddSeconds(account.Created); 4593 born = born.AddSeconds(account.Created);
4184 reply = born.ToString("yyyy-MM-dd"); 4594 reply = born.ToString("yyyy-MM-dd");
4185 break; 4595 break;
4186 case 4: // DATA_RATING (0,0,0,0,0,0) 4596 case 4: // DATA_RATING (0,0,0,0,0,0)
4187 reply = "0,0,0,0,0,0"; 4597 reply = "0,0,0,0,0,0";
4188 break; 4598 break;
4189 case 7: // DATA_USERLEVEL (integer) 4599 case 8: // DATA_PAYINFO (0|1|2|3)
4190 reply = account.UserLevel.ToString(); 4600 reply = "0";
4191 break; 4601 break;
4192 case 8: // DATA_PAYINFO (0|1|2|3) 4602 default:
4193 reply = "0"; 4603 return UUID.Zero.ToString(); // Raise no event
4194 break; 4604 }
4195 default:
4196 return UUID.Zero.ToString(); // Raise no event
4197 }
4198 4605
4199 UUID rq = UUID.Random(); 4606 UUID rq = UUID.Random();
4200 4607
4201 UUID tid = AsyncCommands. 4608 UUID tid = AsyncCommands.
4202 DataserverPlugin.RegisterRequest(m_localID, 4609 DataserverPlugin.RegisterRequest(m_localID,
4203 m_itemID, rq.ToString()); 4610 m_itemID, rq.ToString());
4204 4611
4205 AsyncCommands. 4612 AsyncCommands.
4206 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4613 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4207 4614
4208 ScriptSleep(100); 4615 ScriptSleep(100);
4209 return tid.ToString(); 4616 return tid.ToString();
4617 }
4618 else
4619 {
4620 ShoutError("Invalid UUID passed to llRequestAgentData.");
4621 }
4622 return "";
4210 } 4623 }
4211 4624
4212 public LSL_String llRequestInventoryData(string name) 4625 public LSL_String llRequestInventoryData(string name)
4213 { 4626 {
4214 m_host.AddScriptLPS(1); 4627 m_host.AddScriptLPS(1);
4215 4628
4629 //Clone is thread safe
4216 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4630 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4217 4631
4218 foreach (TaskInventoryItem item in itemDictionary.Values) 4632 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4264,19 +4678,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4264 if (UUID.TryParse(agent, out agentId)) 4678 if (UUID.TryParse(agent, out agentId))
4265 { 4679 {
4266 ScenePresence presence = World.GetScenePresence(agentId); 4680 ScenePresence presence = World.GetScenePresence(agentId);
4267 if (presence != null) 4681 if (presence != null && presence.PresenceType != PresenceType.Npc)
4268 { 4682 {
4683 // agent must not be a god
4684 if (presence.UserLevel >= 200) return;
4685
4269 // agent must be over the owners land 4686 // agent must be over the owners land
4270 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4687 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4271 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4688 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4272 { 4689 {
4273 World.TeleportClientHome(agentId, presence.ControllingClient); 4690 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4691 {
4692 // They can't be teleported home for some reason
4693 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4694 if (regionInfo != null)
4695 {
4696 World.RequestTeleportLocation(
4697 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4698 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4699 }
4700 }
4274 } 4701 }
4275 } 4702 }
4276 } 4703 }
4277 ScriptSleep(5000); 4704 ScriptSleep(5000);
4278 } 4705 }
4279 4706
4707 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4708 {
4709 m_host.AddScriptLPS(1);
4710 UUID agentId = new UUID();
4711 if (UUID.TryParse(agent, out agentId))
4712 {
4713 ScenePresence presence = World.GetScenePresence(agentId);
4714 if (presence != null && presence.PresenceType != PresenceType.Npc)
4715 {
4716 // agent must not be a god
4717 if (presence.GodLevel >= 200) return;
4718
4719 if (simname == String.Empty)
4720 simname = World.RegionInfo.RegionName;
4721
4722 // agent must be over the owners land
4723 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4724 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4725 {
4726 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4727 }
4728 else // or must be wearing the prim
4729 {
4730 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4731 {
4732 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4733 }
4734 }
4735 }
4736 }
4737 }
4738
4280 public void llTextBox(string agent, string message, int chatChannel) 4739 public void llTextBox(string agent, string message, int chatChannel)
4281 { 4740 {
4282 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4741 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4288,7 +4747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4288 UUID av = new UUID(); 4747 UUID av = new UUID();
4289 if (!UUID.TryParse(agent,out av)) 4748 if (!UUID.TryParse(agent,out av))
4290 { 4749 {
4291 LSLError("First parameter to llDialog needs to be a key"); 4750 //LSLError("First parameter to llDialog needs to be a key");
4292 return; 4751 return;
4293 } 4752 }
4294 4753
@@ -4325,17 +4784,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4325 UUID soundId = UUID.Zero; 4784 UUID soundId = UUID.Zero;
4326 if (!UUID.TryParse(impact_sound, out soundId)) 4785 if (!UUID.TryParse(impact_sound, out soundId))
4327 { 4786 {
4328 lock (m_host.TaskInventory) 4787 m_host.TaskInventory.LockItemsForRead(true);
4788 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4329 { 4789 {
4330 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4790 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4331 { 4791 {
4332 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4792 soundId = item.AssetID;
4333 { 4793 break;
4334 soundId = item.AssetID;
4335 break;
4336 }
4337 } 4794 }
4338 } 4795 }
4796 m_host.TaskInventory.LockItemsForRead(false);
4339 } 4797 }
4340 m_host.CollisionSound = soundId; 4798 m_host.CollisionSound = soundId;
4341 m_host.CollisionSoundVolume = (float)impact_volume; 4799 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4375,6 +4833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4375 UUID partItemID; 4833 UUID partItemID;
4376 foreach (SceneObjectPart part in parts) 4834 foreach (SceneObjectPart part in parts)
4377 { 4835 {
4836 //Clone is thread safe
4378 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4837 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4379 4838
4380 foreach (TaskInventoryItem item in itemsDictionary.Values) 4839 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4578,17 +5037,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4578 5037
4579 m_host.AddScriptLPS(1); 5038 m_host.AddScriptLPS(1);
4580 5039
4581 lock (m_host.TaskInventory) 5040 m_host.TaskInventory.LockItemsForRead(true);
5041 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4582 { 5042 {
4583 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5043 if (item.Type == 10 && item.ItemID == m_itemID)
4584 { 5044 {
4585 if (item.Type == 10 && item.ItemID == m_itemID) 5045 result = item.Name!=null?item.Name:String.Empty;
4586 { 5046 break;
4587 result = item.Name != null ? item.Name : String.Empty;
4588 break;
4589 }
4590 } 5047 }
4591 } 5048 }
5049 m_host.TaskInventory.LockItemsForRead(false);
4592 5050
4593 return result; 5051 return result;
4594 } 5052 }
@@ -4761,23 +5219,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5219 {
4762 m_host.AddScriptLPS(1); 5220 m_host.AddScriptLPS(1);
4763 5221
4764 lock (m_host.TaskInventory) 5222 m_host.TaskInventory.LockItemsForRead(true);
5223 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4765 { 5224 {
4766 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5225 if (inv.Value.Name == name)
4767 { 5226 {
4768 if (inv.Value.Name == name) 5227 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4769 { 5228 {
4770 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5229 m_host.TaskInventory.LockItemsForRead(false);
4771 { 5230 return inv.Value.AssetID.ToString();
4772 return inv.Value.AssetID.ToString(); 5231 }
4773 } 5232 else
4774 else 5233 {
4775 { 5234 m_host.TaskInventory.LockItemsForRead(false);
4776 return UUID.Zero.ToString(); 5235 return UUID.Zero.ToString();
4777 }
4778 } 5236 }
4779 } 5237 }
4780 } 5238 }
5239 m_host.TaskInventory.LockItemsForRead(false);
4781 5240
4782 return UUID.Zero.ToString(); 5241 return UUID.Zero.ToString();
4783 } 5242 }
@@ -4930,14 +5389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 { 5389 {
4931 m_host.AddScriptLPS(1); 5390 m_host.AddScriptLPS(1);
4932 5391
4933 if (src == null) 5392 return src.Length;
4934 {
4935 return 0;
4936 }
4937 else
4938 {
4939 return src.Length;
4940 }
4941 } 5393 }
4942 5394
4943 public LSL_Integer llList2Integer(LSL_List src, int index) 5395 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4983,7 +5435,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4983 else if (src.Data[index] is LSL_Float) 5435 else if (src.Data[index] is LSL_Float)
4984 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5436 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4985 else if (src.Data[index] is LSL_String) 5437 else if (src.Data[index] is LSL_String)
4986 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5438 {
5439 string str = ((LSL_String) src.Data[index]).m_string;
5440 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5441 if (m != Match.Empty)
5442 {
5443 str = m.Value;
5444 double d = 0.0;
5445 if (!Double.TryParse(str, out d))
5446 return 0.0;
5447
5448 return d;
5449 }
5450 return 0.0;
5451 }
4987 return Convert.ToDouble(src.Data[index]); 5452 return Convert.ToDouble(src.Data[index]);
4988 } 5453 }
4989 catch (FormatException) 5454 catch (FormatException)
@@ -5256,7 +5721,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5256 } 5721 }
5257 } 5722 }
5258 } 5723 }
5259 else { 5724 else
5725 {
5260 object[] array = new object[src.Length]; 5726 object[] array = new object[src.Length];
5261 Array.Copy(src.Data, 0, array, 0, src.Length); 5727 Array.Copy(src.Data, 0, array, 0, src.Length);
5262 result = new LSL_List(array); 5728 result = new LSL_List(array);
@@ -5363,7 +5829,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5363 public LSL_Integer llGetRegionAgentCount() 5829 public LSL_Integer llGetRegionAgentCount()
5364 { 5830 {
5365 m_host.AddScriptLPS(1); 5831 m_host.AddScriptLPS(1);
5366 return new LSL_Integer(World.GetRootAgentCount()); 5832
5833 int count = 0;
5834 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5835 count++;
5836 });
5837
5838 return new LSL_Integer(count);
5367 } 5839 }
5368 5840
5369 public LSL_Vector llGetRegionCorner() 5841 public LSL_Vector llGetRegionCorner()
@@ -5643,6 +6115,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5643 flags |= ScriptBaseClass.AGENT_SITTING; 6115 flags |= ScriptBaseClass.AGENT_SITTING;
5644 } 6116 }
5645 6117
6118 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6119 {
6120 flags |= ScriptBaseClass.AGENT_MALE;
6121 }
6122
5646 return flags; 6123 return flags;
5647 } 6124 }
5648 6125
@@ -5705,10 +6182,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5705 m_host.AddScriptLPS(1); 6182 m_host.AddScriptLPS(1);
5706 6183
5707 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6184 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5708 6185 if (parts.Count > 0)
5709 foreach (var part in parts)
5710 { 6186 {
5711 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6187 try
6188 {
6189 parts[0].ParentGroup.areUpdatesSuspended = true;
6190 foreach (var part in parts)
6191 {
6192 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6193 }
6194 }
6195 finally
6196 {
6197 parts[0].ParentGroup.areUpdatesSuspended = false;
6198 }
5712 } 6199 }
5713 } 6200 }
5714 6201
@@ -5760,13 +6247,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5760 6247
5761 if (m_host.OwnerID == land.LandData.OwnerID) 6248 if (m_host.OwnerID == land.LandData.OwnerID)
5762 { 6249 {
5763 World.TeleportClientHome(agentID, presence.ControllingClient); 6250 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6251 presence.TeleportWithMomentum(pos);
6252 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5764 } 6253 }
5765 } 6254 }
5766 } 6255 }
5767 ScriptSleep(5000); 6256 ScriptSleep(5000);
5768 } 6257 }
5769 6258
6259 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6260 {
6261 return ParseString2List(str, separators, in_spacers, false);
6262 }
6263
5770 public LSL_Integer llOverMyLand(string id) 6264 public LSL_Integer llOverMyLand(string id)
5771 { 6265 {
5772 m_host.AddScriptLPS(1); 6266 m_host.AddScriptLPS(1);
@@ -5831,8 +6325,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5831 UUID agentId = new UUID(); 6325 UUID agentId = new UUID();
5832 if (!UUID.TryParse(agent, out agentId)) 6326 if (!UUID.TryParse(agent, out agentId))
5833 return new LSL_Integer(0); 6327 return new LSL_Integer(0);
6328 if (agentId == m_host.GroupID)
6329 return new LSL_Integer(1);
5834 ScenePresence presence = World.GetScenePresence(agentId); 6330 ScenePresence presence = World.GetScenePresence(agentId);
5835 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6331 if (presence == null || presence.IsChildAgent) // Return false for child agents
5836 return new LSL_Integer(0); 6332 return new LSL_Integer(0);
5837 IClientAPI client = presence.ControllingClient; 6333 IClientAPI client = presence.ControllingClient;
5838 if (m_host.GroupID == client.ActiveGroupId) 6334 if (m_host.GroupID == client.ActiveGroupId)
@@ -5967,7 +6463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5967 return m_host.ParentGroup.AttachmentPoint; 6463 return m_host.ParentGroup.AttachmentPoint;
5968 } 6464 }
5969 6465
5970 public LSL_Integer llGetFreeMemory() 6466 public virtual LSL_Integer llGetFreeMemory()
5971 { 6467 {
5972 m_host.AddScriptLPS(1); 6468 m_host.AddScriptLPS(1);
5973 // Make scripts designed for LSO happy 6469 // Make scripts designed for LSO happy
@@ -6084,7 +6580,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6084 SetParticleSystem(m_host, rules); 6580 SetParticleSystem(m_host, rules);
6085 } 6581 }
6086 6582
6087 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6583 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6584 {
6088 6585
6089 6586
6090 if (rules.Length == 0) 6587 if (rules.Length == 0)
@@ -6278,14 +6775,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6278 6775
6279 protected UUID GetTaskInventoryItem(string name) 6776 protected UUID GetTaskInventoryItem(string name)
6280 { 6777 {
6281 lock (m_host.TaskInventory) 6778 m_host.TaskInventory.LockItemsForRead(true);
6779 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6282 { 6780 {
6283 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6781 if (inv.Value.Name == name)
6284 { 6782 {
6285 if (inv.Value.Name == name) 6783 m_host.TaskInventory.LockItemsForRead(false);
6286 return inv.Key; 6784 return inv.Key;
6287 } 6785 }
6288 } 6786 }
6787 m_host.TaskInventory.LockItemsForRead(false);
6289 6788
6290 return UUID.Zero; 6789 return UUID.Zero;
6291 } 6790 }
@@ -6323,16 +6822,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6323 if (folderID == UUID.Zero) 6822 if (folderID == UUID.Zero)
6324 return; 6823 return;
6325 6824
6326 byte[] bucket = new byte[17]; 6825 byte[] bucket = new byte[1];
6327 bucket[0] = (byte)AssetType.Folder; 6826 bucket[0] = (byte)AssetType.Folder;
6328 byte[] objBytes = folderID.GetBytes(); 6827 //byte[] objBytes = folderID.GetBytes();
6329 Array.Copy(objBytes, 0, bucket, 1, 16); 6828 //Array.Copy(objBytes, 0, bucket, 1, 16);
6330 6829
6331 GridInstantMessage msg = new GridInstantMessage(World, 6830 GridInstantMessage msg = new GridInstantMessage(World,
6332 m_host.UUID, m_host.Name+", an object owned by "+ 6831 m_host.OwnerID, m_host.Name, destID,
6333 resolveName(m_host.OwnerID)+",", destID, 6832 (byte)InstantMessageDialog.TaskInventoryOffered,
6334 (byte)InstantMessageDialog.InventoryOffered, 6833 false, category+". "+m_host.Name+" is located at "+
6335 false, category+"\n"+m_host.Name+" is located at "+
6336 World.RegionInfo.RegionName+" "+ 6834 World.RegionInfo.RegionName+" "+
6337 m_host.AbsolutePosition.ToString(), 6835 m_host.AbsolutePosition.ToString(),
6338 folderID, true, m_host.AbsolutePosition, 6836 folderID, true, m_host.AbsolutePosition,
@@ -6570,13 +7068,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6570 UUID av = new UUID(); 7068 UUID av = new UUID();
6571 if (!UUID.TryParse(avatar,out av)) 7069 if (!UUID.TryParse(avatar,out av))
6572 { 7070 {
6573 LSLError("First parameter to llDialog needs to be a key"); 7071 //LSLError("First parameter to llDialog needs to be a key");
6574 return; 7072 return;
6575 } 7073 }
6576 if (buttons.Length < 1) 7074 if (buttons.Length < 1)
6577 { 7075 {
6578 LSLError("No less than 1 button can be shown"); 7076 buttons.Add("OK");
6579 return;
6580 } 7077 }
6581 if (buttons.Length > 12) 7078 if (buttons.Length > 12)
6582 { 7079 {
@@ -6593,7 +7090,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6593 } 7090 }
6594 if (buttons.Data[i].ToString().Length > 24) 7091 if (buttons.Data[i].ToString().Length > 24)
6595 { 7092 {
6596 LSLError("button label cannot be longer than 24 characters"); 7093 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6597 return; 7094 return;
6598 } 7095 }
6599 buts[i] = buttons.Data[i].ToString(); 7096 buts[i] = buttons.Data[i].ToString();
@@ -6652,22 +7149,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6652 } 7149 }
6653 7150
6654 // copy the first script found with this inventory name 7151 // copy the first script found with this inventory name
6655 lock (m_host.TaskInventory) 7152 TaskInventoryItem scriptItem = null;
7153 m_host.TaskInventory.LockItemsForRead(true);
7154 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6656 { 7155 {
6657 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7156 if (inv.Value.Name == name)
6658 { 7157 {
6659 if (inv.Value.Name == name) 7158 // make sure the object is a script
7159 if (10 == inv.Value.Type)
6660 { 7160 {
6661 // make sure the object is a script 7161 found = true;
6662 if (10 == inv.Value.Type) 7162 srcId = inv.Key;
6663 { 7163 scriptItem = inv.Value;
6664 found = true; 7164 break;
6665 srcId = inv.Key;
6666 break;
6667 }
6668 } 7165 }
6669 } 7166 }
6670 } 7167 }
7168 m_host.TaskInventory.LockItemsForRead(false);
6671 7169
6672 if (!found) 7170 if (!found)
6673 { 7171 {
@@ -6675,9 +7173,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6675 return; 7173 return;
6676 } 7174 }
6677 7175
6678 // the rest of the permission checks are done in RezScript, so check the pin there as well 7176 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6679 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7177 if (dest != null)
7178 {
7179 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7180 {
7181 // the rest of the permission checks are done in RezScript, so check the pin there as well
7182 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6680 7183
7184 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7185 m_host.Inventory.RemoveInventoryItem(srcId);
7186 }
7187 }
6681 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7188 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6682 ScriptSleep(3000); 7189 ScriptSleep(3000);
6683 } 7190 }
@@ -6740,19 +7247,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6740 public LSL_String llMD5String(string src, int nonce) 7247 public LSL_String llMD5String(string src, int nonce)
6741 { 7248 {
6742 m_host.AddScriptLPS(1); 7249 m_host.AddScriptLPS(1);
6743 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7250 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6744 } 7251 }
6745 7252
6746 public LSL_String llSHA1String(string src) 7253 public LSL_String llSHA1String(string src)
6747 { 7254 {
6748 m_host.AddScriptLPS(1); 7255 m_host.AddScriptLPS(1);
6749 return Util.SHA1Hash(src).ToLower(); 7256 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6750 } 7257 }
6751 7258
6752 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7259 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6753 { 7260 {
6754 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7261 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6755 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7262 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7263 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7264 return shapeBlock;
6756 7265
6757 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7266 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6758 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7267 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6857,6 +7366,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6857 // Prim type box, cylinder and prism. 7366 // Prim type box, cylinder and prism.
6858 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) 7367 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)
6859 { 7368 {
7369 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7370 return;
7371
6860 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7372 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6861 ObjectShapePacket.ObjectDataBlock shapeBlock; 7373 ObjectShapePacket.ObjectDataBlock shapeBlock;
6862 7374
@@ -6910,6 +7422,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6910 // Prim type sphere. 7422 // Prim type sphere.
6911 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7423 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6912 { 7424 {
7425 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7426 return;
7427
6913 ObjectShapePacket.ObjectDataBlock shapeBlock; 7428 ObjectShapePacket.ObjectDataBlock shapeBlock;
6914 7429
6915 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7430 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6951,6 +7466,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type torus, tube and ring. 7466 // Prim type torus, tube and ring.
6952 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) 7467 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)
6953 { 7468 {
7469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7470 return;
7471
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7472 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7473 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7474
@@ -7086,6 +7604,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7086 // Prim type sculpt. 7604 // Prim type sculpt.
7087 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7605 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7088 { 7606 {
7607 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7608 return;
7609
7089 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7610 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7090 UUID sculptId; 7611 UUID sculptId;
7091 7612
@@ -7110,7 +7631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7110 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7631 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7111 { 7632 {
7112 // default 7633 // default
7113 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7634 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7114 } 7635 }
7115 7636
7116 part.Shape.SetSculptProperties((byte)type, sculptId); 7637 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7126,32 +7647,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7126 ScriptSleep(200); 7647 ScriptSleep(200);
7127 } 7648 }
7128 7649
7129 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7650 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7130 { 7651 {
7131 m_host.AddScriptLPS(1); 7652 m_host.AddScriptLPS(1);
7132 7653
7133 setLinkPrimParams(linknumber, rules); 7654 setLinkPrimParams(linknumber, rules);
7655 }
7134 7656
7135 ScriptSleep(200); 7657 private void setLinkPrimParams(int linknumber, LSL_List rules)
7658 {
7659 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7660 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7661 if (parts.Count>0)
7662 {
7663 try
7664 {
7665 parts[0].ParentGroup.areUpdatesSuspended = true;
7666 foreach (SceneObjectPart part in parts)
7667 SetPrimParams(part, rules);
7668 }
7669 finally
7670 {
7671 parts[0].ParentGroup.areUpdatesSuspended = false;
7672 }
7673 }
7674 if (avatars.Count > 0)
7675 {
7676 foreach (ScenePresence avatar in avatars)
7677 SetPrimParams(avatar, rules);
7678 }
7136 } 7679 }
7137 7680
7138 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7681 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7682 float material_density, float material_friction,
7683 float material_restitution, float material_gravity_modifier)
7139 { 7684 {
7140 m_host.AddScriptLPS(1); 7685 ExtraPhysicsData physdata = new ExtraPhysicsData();
7686 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7687 physdata.Density = part.Density;
7688 physdata.Friction = part.Friction;
7689 physdata.Bounce = part.Bounciness;
7690 physdata.GravitationModifier = part.GravityModifier;
7141 7691
7142 setLinkPrimParams(linknumber, rules); 7692 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7693 physdata.Density = material_density;
7694 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7695 physdata.Friction = material_friction;
7696 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7697 physdata.Bounce = material_restitution;
7698 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7699 physdata.GravitationModifier = material_gravity_modifier;
7700
7701 part.UpdateExtraPhysics(physdata);
7143 } 7702 }
7144 7703
7145 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7704 public void llSetPhysicsMaterial(int material_bits,
7705 float material_gravity_modifier, float material_restitution,
7706 float material_friction, float material_density)
7146 { 7707 {
7147 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7708 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7709 }
7148 7710
7149 foreach (SceneObjectPart part in parts) 7711 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7150 SetPrimParams(part, rules); 7712 {
7713 llSetLinkPrimitiveParamsFast(linknumber, rules);
7714 ScriptSleep(200);
7715 }
7716
7717 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7718 {
7719 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7720 //We only support PRIM_POSITION and PRIM_ROTATION
7721
7722 int idx = 0;
7723
7724 while (idx < rules.Length)
7725 {
7726 int code = rules.GetLSLIntegerItem(idx++);
7727
7728 int remain = rules.Length - idx;
7729
7730 switch (code)
7731 {
7732 case (int)ScriptBaseClass.PRIM_POSITION:
7733 {
7734 if (remain < 1)
7735 return;
7736 LSL_Vector v;
7737 v = rules.GetVector3Item(idx++);
7738
7739 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7740 if (part == null)
7741 break;
7742
7743 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7744 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7745 if (llGetLinkNumber() > 1)
7746 {
7747 localRot = llGetLocalRot();
7748 localPos = llGetLocalPos();
7749 }
7750
7751 v -= localPos;
7752 v /= localRot;
7753
7754 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7755
7756 v = v + 2 * sitOffset;
7757
7758 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7759 av.SendAvatarDataToAllAgents();
7760
7761 }
7762 break;
7763
7764 case (int)ScriptBaseClass.PRIM_ROTATION:
7765 {
7766 if (remain < 1)
7767 return;
7768
7769 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7770 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7771 if (llGetLinkNumber() > 1)
7772 {
7773 localRot = llGetLocalRot();
7774 localPos = llGetLocalPos();
7775 }
7776
7777 LSL_Rotation r;
7778 r = rules.GetQuaternionItem(idx++);
7779 r = r * llGetRootRotation() / localRot;
7780 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7781 av.SendAvatarDataToAllAgents();
7782 }
7783 break;
7784 }
7785 }
7151 } 7786 }
7152 7787
7153 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7788 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7154 { 7789 {
7790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7791 return;
7792
7155 int idx = 0; 7793 int idx = 0;
7156 7794
7157 bool positionChanged = false; 7795 bool positionChanged = false;
@@ -7473,6 +8111,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7473 part.ScriptSetPhysicsStatus(physics); 8111 part.ScriptSetPhysicsStatus(physics);
7474 break; 8112 break;
7475 8113
8114 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8115 if (remain < 1)
8116 return;
8117
8118 int shape_type = rules.GetLSLIntegerItem(idx++);
8119
8120 ExtraPhysicsData physdata = new ExtraPhysicsData();
8121 physdata.Density = part.Density;
8122 physdata.Bounce = part.Bounciness;
8123 physdata.GravitationModifier = part.GravityModifier;
8124 physdata.PhysShapeType = (PhysShapeType)shape_type;
8125
8126 part.UpdateExtraPhysics(physdata);
8127
8128 break;
8129
8130 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8131 if (remain < 5)
8132 return;
8133
8134 int material_bits = rules.GetLSLIntegerItem(idx++);
8135 float material_density = (float)rules.GetLSLFloatItem(idx++);
8136 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8137 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8138 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8139
8140 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8141
8142 break;
8143
7476 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8144 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7477 if (remain < 1) 8145 if (remain < 1)
7478 return; 8146 return;
@@ -7546,7 +8214,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 if (part.ParentGroup.RootPart == part) 8214 if (part.ParentGroup.RootPart == part)
7547 { 8215 {
7548 SceneObjectGroup parent = part.ParentGroup; 8216 SceneObjectGroup parent = part.ParentGroup;
7549 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8217 Util.FireAndForget(delegate(object x) {
8218 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8219 });
7550 } 8220 }
7551 else 8221 else
7552 { 8222 {
@@ -7557,6 +8227,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7557 } 8227 }
7558 } 8228 }
7559 } 8229 }
8230
8231 if (positionChanged)
8232 {
8233 if (part.ParentGroup.RootPart == part)
8234 {
8235 SceneObjectGroup parent = part.ParentGroup;
8236 Util.FireAndForget(delegate(object x) {
8237 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8238 });
8239 }
8240 else
8241 {
8242 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8243 SceneObjectGroup parent = part.ParentGroup;
8244 parent.HasGroupChanged = true;
8245 parent.ScheduleGroupForTerseUpdate();
8246 }
8247 }
7560 } 8248 }
7561 8249
7562 public LSL_String llStringToBase64(string str) 8250 public LSL_String llStringToBase64(string str)
@@ -7717,13 +8405,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7717 public LSL_Integer llGetNumberOfPrims() 8405 public LSL_Integer llGetNumberOfPrims()
7718 { 8406 {
7719 m_host.AddScriptLPS(1); 8407 m_host.AddScriptLPS(1);
7720 int avatarCount = 0; 8408 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7721 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8409
7722 {
7723 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7724 avatarCount++;
7725 });
7726
7727 return m_host.ParentGroup.PrimCount + avatarCount; 8410 return m_host.ParentGroup.PrimCount + avatarCount;
7728 } 8411 }
7729 8412
@@ -7739,55 +8422,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 m_host.AddScriptLPS(1); 8422 m_host.AddScriptLPS(1);
7740 UUID objID = UUID.Zero; 8423 UUID objID = UUID.Zero;
7741 LSL_List result = new LSL_List(); 8424 LSL_List result = new LSL_List();
8425
8426 // If the ID is not valid, return null result
7742 if (!UUID.TryParse(obj, out objID)) 8427 if (!UUID.TryParse(obj, out objID))
7743 { 8428 {
7744 result.Add(new LSL_Vector()); 8429 result.Add(new LSL_Vector());
7745 result.Add(new LSL_Vector()); 8430 result.Add(new LSL_Vector());
7746 return result; 8431 return result;
7747 } 8432 }
8433
8434 // Check if this is an attached prim. If so, replace
8435 // the UUID with the avatar UUID and report it's bounding box
8436 SceneObjectPart part = World.GetSceneObjectPart(objID);
8437 if (part != null && part.ParentGroup.IsAttachment)
8438 objID = part.ParentGroup.AttachedAvatar;
8439
8440 // Find out if this is an avatar ID. If so, return it's box
7748 ScenePresence presence = World.GetScenePresence(objID); 8441 ScenePresence presence = World.GetScenePresence(objID);
7749 if (presence != null) 8442 if (presence != null)
7750 { 8443 {
7751 if (presence.ParentID == 0) // not sat on an object 8444 // As per LSL Wiki, there is no difference between sitting
8445 // and standing avatar since server 1.36
8446 LSL_Vector lower;
8447 LSL_Vector upper;
8448 if (presence.Animator.Animations.DefaultAnimation.AnimID
8449 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7752 { 8450 {
7753 LSL_Vector lower; 8451 // This is for ground sitting avatars
7754 LSL_Vector upper; 8452 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7755 if (presence.Animator.Animations.DefaultAnimation.AnimID 8453 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7756 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8454 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7757 {
7758 // This is for ground sitting avatars
7759 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7760 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7761 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7762 }
7763 else
7764 {
7765 // This is for standing/flying avatars
7766 float height = presence.Appearance.AvatarHeight / 2.0f;
7767 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7768 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7769 }
7770 result.Add(lower);
7771 result.Add(upper);
7772 return result;
7773 } 8455 }
7774 else 8456 else
7775 { 8457 {
7776 // sitting on an object so we need the bounding box of that 8458 // This is for standing/flying avatars
7777 // which should include the avatar so set the UUID to the 8459 float height = presence.Appearance.AvatarHeight / 2.0f;
7778 // UUID of the object the avatar is sat on and allow it to fall through 8460 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7779 // to processing an object 8461 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7780 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7781 objID = p.UUID;
7782 } 8462 }
8463
8464 // Adjust to the documented error offsets (see LSL Wiki)
8465 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8466 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8467
8468 if (lower.x > upper.x)
8469 lower.x = upper.x;
8470 if (lower.y > upper.y)
8471 lower.y = upper.y;
8472 if (lower.z > upper.z)
8473 lower.z = upper.z;
8474
8475 result.Add(lower);
8476 result.Add(upper);
8477 return result;
7783 } 8478 }
7784 SceneObjectPart part = World.GetSceneObjectPart(objID); 8479
8480 part = World.GetSceneObjectPart(objID);
7785 // Currently only works for single prims without a sitting avatar 8481 // Currently only works for single prims without a sitting avatar
7786 if (part != null) 8482 if (part != null)
7787 { 8483 {
7788 Vector3 halfSize = part.Scale / 2.0f; 8484 float minX;
7789 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8485 float maxX;
7790 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8486 float minY;
8487 float maxY;
8488 float minZ;
8489 float maxZ;
8490
8491 // This BBox is in sim coordinates, with the offset being
8492 // a contained point.
8493 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8494 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8495
8496 minX -= offsets[0].X;
8497 maxX -= offsets[0].X;
8498 minY -= offsets[0].Y;
8499 maxY -= offsets[0].Y;
8500 minZ -= offsets[0].Z;
8501 maxZ -= offsets[0].Z;
8502
8503 LSL_Vector lower;
8504 LSL_Vector upper;
8505
8506 // Adjust to the documented error offsets (see LSL Wiki)
8507 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8508 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8509
8510 if (lower.x > upper.x)
8511 lower.x = upper.x;
8512 if (lower.y > upper.y)
8513 lower.y = upper.y;
8514 if (lower.z > upper.z)
8515 lower.z = upper.z;
8516
7791 result.Add(lower); 8517 result.Add(lower);
7792 result.Add(upper); 8518 result.Add(upper);
7793 return result; 8519 return result;
@@ -7867,13 +8593,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7867 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8593 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7868 part.AbsolutePosition.Y, 8594 part.AbsolutePosition.Y,
7869 part.AbsolutePosition.Z); 8595 part.AbsolutePosition.Z);
7870 // For some reason, the part.AbsolutePosition.* values do not change if the
7871 // linkset is rotated; they always reflect the child prim's world position
7872 // as though the linkset is unrotated. This is incompatible behavior with SL's
7873 // implementation, so will break scripts imported from there (not to mention it
7874 // makes it more difficult to determine a child prim's actual inworld position).
7875 if (part.ParentID != 0)
7876 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7877 res.Add(v); 8596 res.Add(v);
7878 break; 8597 break;
7879 8598
@@ -8044,56 +8763,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8044 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8763 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8045 if (remain < 1) 8764 if (remain < 1)
8046 return res; 8765 return res;
8047 8766 face = (int)rules.GetLSLIntegerItem(idx++);
8048 face=(int)rules.GetLSLIntegerItem(idx++);
8049 8767
8050 tex = part.Shape.Textures; 8768 tex = part.Shape.Textures;
8769 int shiny;
8051 if (face == ScriptBaseClass.ALL_SIDES) 8770 if (face == ScriptBaseClass.ALL_SIDES)
8052 { 8771 {
8053 for (face = 0; face < GetNumberOfSides(part); face++) 8772 for (face = 0; face < GetNumberOfSides(part); face++)
8054 { 8773 {
8055 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8774 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8056 // Convert Shininess to PRIM_SHINY_* 8775 if (shinyness == Shininess.High)
8057 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8776 {
8058 // PRIM_BUMP_* 8777 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8059 res.Add(new LSL_Integer((int)texface.Bump)); 8778 }
8779 else if (shinyness == Shininess.Medium)
8780 {
8781 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8782 }
8783 else if (shinyness == Shininess.Low)
8784 {
8785 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8786 }
8787 else
8788 {
8789 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8790 }
8791 res.Add(new LSL_Integer(shiny));
8792 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8060 } 8793 }
8061 } 8794 }
8062 else 8795 else
8063 { 8796 {
8064 if (face >= 0 && face < GetNumberOfSides(part)) 8797 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8798 if (shinyness == Shininess.High)
8065 { 8799 {
8066 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8800 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8067 // Convert Shininess to PRIM_SHINY_* 8801 }
8068 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8802 else if (shinyness == Shininess.Medium)
8069 // PRIM_BUMP_* 8803 {
8070 res.Add(new LSL_Integer((int)texface.Bump)); 8804 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8071 } 8805 }
8806 else if (shinyness == Shininess.Low)
8807 {
8808 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8809 }
8810 else
8811 {
8812 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8813 }
8814 res.Add(new LSL_Integer(shiny));
8815 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8072 } 8816 }
8073 break; 8817 break;
8074 8818
8075 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8819 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8076 if (remain < 1) 8820 if (remain < 1)
8077 return res; 8821 return res;
8078 8822 face = (int)rules.GetLSLIntegerItem(idx++);
8079 face=(int)rules.GetLSLIntegerItem(idx++);
8080 8823
8081 tex = part.Shape.Textures; 8824 tex = part.Shape.Textures;
8825 int fullbright;
8082 if (face == ScriptBaseClass.ALL_SIDES) 8826 if (face == ScriptBaseClass.ALL_SIDES)
8083 { 8827 {
8084 for (face = 0; face < GetNumberOfSides(part); face++) 8828 for (face = 0; face < GetNumberOfSides(part); face++)
8085 { 8829 {
8086 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8830 if (tex.GetFace((uint)face).Fullbright == true)
8087 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8831 {
8832 fullbright = ScriptBaseClass.TRUE;
8833 }
8834 else
8835 {
8836 fullbright = ScriptBaseClass.FALSE;
8837 }
8838 res.Add(new LSL_Integer(fullbright));
8088 } 8839 }
8089 } 8840 }
8090 else 8841 else
8091 { 8842 {
8092 if (face >= 0 && face < GetNumberOfSides(part)) 8843 if (tex.GetFace((uint)face).Fullbright == true)
8093 { 8844 {
8094 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8845 fullbright = ScriptBaseClass.TRUE;
8095 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8096 } 8846 }
8847 else
8848 {
8849 fullbright = ScriptBaseClass.FALSE;
8850 }
8851 res.Add(new LSL_Integer(fullbright));
8097 } 8852 }
8098 break; 8853 break;
8099 8854
@@ -8115,27 +8870,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 break; 8870 break;
8116 8871
8117 case (int)ScriptBaseClass.PRIM_TEXGEN: 8872 case (int)ScriptBaseClass.PRIM_TEXGEN:
8873 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8118 if (remain < 1) 8874 if (remain < 1)
8119 return res; 8875 return res;
8120 8876 face = (int)rules.GetLSLIntegerItem(idx++);
8121 face=(int)rules.GetLSLIntegerItem(idx++);
8122 8877
8123 tex = part.Shape.Textures; 8878 tex = part.Shape.Textures;
8124 if (face == ScriptBaseClass.ALL_SIDES) 8879 if (face == ScriptBaseClass.ALL_SIDES)
8125 { 8880 {
8126 for (face = 0; face < GetNumberOfSides(part); face++) 8881 for (face = 0; face < GetNumberOfSides(part); face++)
8127 { 8882 {
8128 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8883 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8129 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8884 {
8130 res.Add(new LSL_Integer((uint)texgen >> 1)); 8885 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8886 }
8887 else
8888 {
8889 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8890 }
8131 } 8891 }
8132 } 8892 }
8133 else 8893 else
8134 { 8894 {
8135 if (face >= 0 && face < GetNumberOfSides(part)) 8895 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8136 { 8896 {
8137 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8897 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8138 res.Add(new LSL_Integer((uint)texgen >> 1)); 8898 }
8899 else
8900 {
8901 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8139 } 8902 }
8140 } 8903 }
8141 break; 8904 break;
@@ -8158,28 +8921,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8158 case (int)ScriptBaseClass.PRIM_GLOW: 8921 case (int)ScriptBaseClass.PRIM_GLOW:
8159 if (remain < 1) 8922 if (remain < 1)
8160 return res; 8923 return res;
8161 8924 face = (int)rules.GetLSLIntegerItem(idx++);
8162 face=(int)rules.GetLSLIntegerItem(idx++);
8163 8925
8164 tex = part.Shape.Textures; 8926 tex = part.Shape.Textures;
8927 float primglow;
8165 if (face == ScriptBaseClass.ALL_SIDES) 8928 if (face == ScriptBaseClass.ALL_SIDES)
8166 { 8929 {
8167 for (face = 0; face < GetNumberOfSides(part); face++) 8930 for (face = 0; face < GetNumberOfSides(part); face++)
8168 { 8931 {
8169 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8932 primglow = tex.GetFace((uint)face).Glow;
8170 res.Add(new LSL_Float(texface.Glow)); 8933 res.Add(new LSL_Float(primglow));
8171 } 8934 }
8172 } 8935 }
8173 else 8936 else
8174 { 8937 {
8175 if (face >= 0 && face < GetNumberOfSides(part)) 8938 primglow = tex.GetFace((uint)face).Glow;
8176 { 8939 res.Add(new LSL_Float(primglow));
8177 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8178 res.Add(new LSL_Float(texface.Glow));
8179 }
8180 } 8940 }
8181 break; 8941 break;
8182
8183 case (int)ScriptBaseClass.PRIM_TEXT: 8942 case (int)ScriptBaseClass.PRIM_TEXT:
8184 Color4 textColor = part.GetTextColor(); 8943 Color4 textColor = part.GetTextColor();
8185 res.Add(new LSL_String(part.Text)); 8944 res.Add(new LSL_String(part.Text));
@@ -8791,8 +9550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8791 // The function returns an ordered list 9550 // The function returns an ordered list
8792 // representing the tokens found in the supplied 9551 // representing the tokens found in the supplied
8793 // sources string. If two successive tokenizers 9552 // sources string. If two successive tokenizers
8794 // are encountered, then a NULL entry is added 9553 // are encountered, then a null-string entry is
8795 // to the list. 9554 // added to the list.
8796 // 9555 //
8797 // It is a precondition that the source and 9556 // It is a precondition that the source and
8798 // toekizer lisst are non-null. If they are null, 9557 // toekizer lisst are non-null. If they are null,
@@ -8800,7 +9559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8800 // while their lengths are being determined. 9559 // while their lengths are being determined.
8801 // 9560 //
8802 // A small amount of working memoryis required 9561 // A small amount of working memoryis required
8803 // of approximately 8*#tokenizers. 9562 // of approximately 8*#tokenizers + 8*srcstrlen.
8804 // 9563 //
8805 // There are many ways in which this function 9564 // There are many ways in which this function
8806 // can be implemented, this implementation is 9565 // can be implemented, this implementation is
@@ -8816,155 +9575,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8816 // and eliminates redundant tokenizers as soon 9575 // and eliminates redundant tokenizers as soon
8817 // as is possible. 9576 // as is possible.
8818 // 9577 //
8819 // The implementation tries to avoid any copying 9578 // The implementation tries to minimize temporary
8820 // of arrays or other objects. 9579 // garbage generation.
8821 // </remarks> 9580 // </remarks>
8822 9581
8823 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9582 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8824 { 9583 {
8825 int beginning = 0; 9584 return ParseString2List(src, separators, spacers, true);
8826 int srclen = src.Length; 9585 }
8827 int seplen = separators.Length;
8828 object[] separray = separators.Data;
8829 int spclen = spacers.Length;
8830 object[] spcarray = spacers.Data;
8831 int mlen = seplen+spclen;
8832
8833 int[] offset = new int[mlen+1];
8834 bool[] active = new bool[mlen];
8835
8836 int best;
8837 int j;
8838
8839 // Initial capacity reduces resize cost
8840 9586
8841 LSL_List tokens = new LSL_List(); 9587 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9588 {
9589 int srclen = src.Length;
9590 int seplen = separators.Length;
9591 object[] separray = separators.Data;
9592 int spclen = spacers.Length;
9593 object[] spcarray = spacers.Data;
9594 int dellen = 0;
9595 string[] delarray = new string[seplen+spclen];
8842 9596
8843 // All entries are initially valid 9597 int outlen = 0;
9598 string[] outarray = new string[srclen*2+1];
8844 9599
8845 for (int i = 0; i < mlen; i++) 9600 int i, j;
8846 active[i] = true; 9601 string d;
8847 9602
8848 offset[mlen] = srclen; 9603 m_host.AddScriptLPS(1);
8849 9604
8850 while (beginning < srclen) 9605 /*
9606 * Convert separator and spacer lists to C# strings.
9607 * Also filter out null strings so we don't hang.
9608 */
9609 for (i = 0; i < seplen; i ++)
8851 { 9610 {
9611 d = separray[i].ToString();
9612 if (d.Length > 0)
9613 {
9614 delarray[dellen++] = d;
9615 }
9616 }
9617 seplen = dellen;
8852 9618
8853 best = mlen; // as bad as it gets 9619 for (i = 0; i < spclen; i ++)
9620 {
9621 d = spcarray[i].ToString();
9622 if (d.Length > 0)
9623 {
9624 delarray[dellen++] = d;
9625 }
9626 }
8854 9627
8855 // Scan for separators 9628 /*
9629 * Scan through source string from beginning to end.
9630 */
9631 for (i = 0;;)
9632 {
8856 9633
8857 for (j = 0; j < seplen; j++) 9634 /*
9635 * Find earliest delimeter in src starting at i (if any).
9636 */
9637 int earliestDel = -1;
9638 int earliestSrc = srclen;
9639 string earliestStr = null;
9640 for (j = 0; j < dellen; j ++)
8858 { 9641 {
8859 if (separray[j].ToString() == String.Empty) 9642 d = delarray[j];
8860 active[j] = false; 9643 if (d != null)
8861
8862 if (active[j])
8863 { 9644 {
8864 // scan all of the markers 9645 int index = src.IndexOf(d, i);
8865 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9646 if (index < 0)
8866 { 9647 {
8867 // not present at all 9648 delarray[j] = null; // delim nowhere in src, don't check it anymore
8868 active[j] = false;
8869 } 9649 }
8870 else 9650 else if (index < earliestSrc)
8871 { 9651 {
8872 // present and correct 9652 earliestSrc = index; // where delimeter starts in source string
8873 if (offset[j] < offset[best]) 9653 earliestDel = j; // where delimeter is in delarray[]
8874 { 9654 earliestStr = d; // the delimeter string from delarray[]
8875 // closest so far 9655 if (index == i) break; // can't do any better than found at beg of string
8876 best = j;
8877 if (offset[best] == beginning)
8878 break;
8879 }
8880 } 9656 }
8881 } 9657 }
8882 } 9658 }
8883 9659
8884 // Scan for spacers 9660 /*
8885 9661 * Output source string starting at i through start of earliest delimeter.
8886 if (offset[best] != beginning) 9662 */
9663 if (keepNulls || (earliestSrc > i))
8887 { 9664 {
8888 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9665 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8889 {
8890 if (spcarray[j-seplen].ToString() == String.Empty)
8891 active[j] = false;
8892
8893 if (active[j])
8894 {
8895 // scan all of the markers
8896 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8897 {
8898 // not present at all
8899 active[j] = false;
8900 }
8901 else
8902 {
8903 // present and correct
8904 if (offset[j] < offset[best])
8905 {
8906 // closest so far
8907 best = j;
8908 }
8909 }
8910 }
8911 }
8912 } 9666 }
8913 9667
8914 // This is the normal exit from the scanning loop 9668 /*
9669 * If no delimeter found at or after i, we're done scanning.
9670 */
9671 if (earliestDel < 0) break;
8915 9672
8916 if (best == mlen) 9673 /*
9674 * If delimeter was a spacer, output the spacer.
9675 */
9676 if (earliestDel >= seplen)
8917 { 9677 {
8918 // no markers were found on this pass 9678 outarray[outlen++] = earliestStr;
8919 // so we're pretty much done
8920 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8921 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8922 break;
8923 } 9679 }
8924 9680
8925 // Otherwise we just add the newly delimited token 9681 /*
8926 // and recalculate where the search should continue. 9682 * Look at rest of src string following delimeter.
8927 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9683 */
8928 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9684 i = earliestSrc + earliestStr.Length;
8929
8930 if (best < seplen)
8931 {
8932 beginning = offset[best] + (separray[best].ToString()).Length;
8933 }
8934 else
8935 {
8936 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8937 string str = spcarray[best - seplen].ToString();
8938 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8939 tokens.Add(new LSL_String(str));
8940 }
8941 } 9685 }
8942 9686
8943 // This an awkward an not very intuitive boundary case. If the 9687 /*
8944 // last substring is a tokenizer, then there is an implied trailing 9688 * Make up an exact-sized output array suitable for an LSL_List object.
8945 // null list entry. Hopefully the single comparison will not be too 9689 */
8946 // arduous. Alternatively the 'break' could be replced with a return 9690 object[] outlist = new object[outlen];
8947 // but that's shabby programming. 9691 for (i = 0; i < outlen; i ++)
8948
8949 if ((beginning == srclen) && (keepNulls))
8950 { 9692 {
8951 if (srclen != 0) 9693 outlist[i] = new LSL_String(outarray[i]);
8952 tokens.Add(new LSL_String(""));
8953 } 9694 }
8954 9695 return new LSL_List(outlist);
8955 return tokens;
8956 }
8957
8958 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8959 {
8960 m_host.AddScriptLPS(1);
8961 return this.ParseString(src, separators, spacers, false);
8962 }
8963
8964 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8965 {
8966 m_host.AddScriptLPS(1);
8967 return this.ParseString(src, separators, spacers, true);
8968 } 9696 }
8969 9697
8970 public LSL_Integer llGetObjectPermMask(int mask) 9698 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9041,28 +9769,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9041 { 9769 {
9042 m_host.AddScriptLPS(1); 9770 m_host.AddScriptLPS(1);
9043 9771
9044 lock (m_host.TaskInventory) 9772 m_host.TaskInventory.LockItemsForRead(true);
9773 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9045 { 9774 {
9046 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9775 if (inv.Value.Name == item)
9047 { 9776 {
9048 if (inv.Value.Name == item) 9777 m_host.TaskInventory.LockItemsForRead(false);
9778 switch (mask)
9049 { 9779 {
9050 switch (mask) 9780 case 0:
9051 { 9781 return (int)inv.Value.BasePermissions;
9052 case 0: 9782 case 1:
9053 return (int)inv.Value.BasePermissions; 9783 return (int)inv.Value.CurrentPermissions;
9054 case 1: 9784 case 2:
9055 return (int)inv.Value.CurrentPermissions; 9785 return (int)inv.Value.GroupPermissions;
9056 case 2: 9786 case 3:
9057 return (int)inv.Value.GroupPermissions; 9787 return (int)inv.Value.EveryonePermissions;
9058 case 3: 9788 case 4:
9059 return (int)inv.Value.EveryonePermissions; 9789 return (int)inv.Value.NextPermissions;
9060 case 4:
9061 return (int)inv.Value.NextPermissions;
9062 }
9063 } 9790 }
9064 } 9791 }
9065 } 9792 }
9793 m_host.TaskInventory.LockItemsForRead(false);
9066 9794
9067 return -1; 9795 return -1;
9068 } 9796 }
@@ -9109,16 +9837,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9109 { 9837 {
9110 m_host.AddScriptLPS(1); 9838 m_host.AddScriptLPS(1);
9111 9839
9112 lock (m_host.TaskInventory) 9840 m_host.TaskInventory.LockItemsForRead(true);
9841 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9113 { 9842 {
9114 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9843 if (inv.Value.Name == item)
9115 { 9844 {
9116 if (inv.Value.Name == item) 9845 m_host.TaskInventory.LockItemsForRead(false);
9117 { 9846 return inv.Value.CreatorID.ToString();
9118 return inv.Value.CreatorID.ToString();
9119 }
9120 } 9847 }
9121 } 9848 }
9849 m_host.TaskInventory.LockItemsForRead(false);
9122 9850
9123 llSay(0, "No item name '" + item + "'"); 9851 llSay(0, "No item name '" + item + "'");
9124 9852
@@ -9266,7 +9994,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 } 9994 }
9267 9995
9268 /// <summary> 9996 /// <summary>
9269 /// illListReplaceList removes the sub-list defined by the inclusive indices 9997 /// llListReplaceList removes the sub-list defined by the inclusive indices
9270 /// start and end and inserts the src list in its place. The inclusive 9998 /// start and end and inserts the src list in its place. The inclusive
9271 /// nature of the indices means that at least one element must be deleted 9999 /// nature of the indices means that at least one element must be deleted
9272 /// if the indices are within the bounds of the existing list. I.e. 2,2 10000 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9323,16 +10051,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 // based upon end. Note that if end exceeds the upper 10051 // based upon end. Note that if end exceeds the upper
9324 // bound in this case, the entire destination list 10052 // bound in this case, the entire destination list
9325 // is removed. 10053 // is removed.
9326 else 10054 else if (start == 0)
9327 { 10055 {
9328 if (end + 1 < dest.Length) 10056 if (end + 1 < dest.Length)
9329 {
9330 return src + dest.GetSublist(end + 1, -1); 10057 return src + dest.GetSublist(end + 1, -1);
9331 }
9332 else 10058 else
9333 {
9334 return src; 10059 return src;
9335 } 10060 }
10061 else // Start < 0
10062 {
10063 if (end + 1 < dest.Length)
10064 return dest.GetSublist(end + 1, -1);
10065 else
10066 return new LSL_List();
9336 } 10067 }
9337 } 10068 }
9338 // Finally, if start > end, we strip away a prefix and 10069 // Finally, if start > end, we strip away a prefix and
@@ -9383,17 +10114,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9383 int width = 0; 10114 int width = 0;
9384 int height = 0; 10115 int height = 0;
9385 10116
9386 ParcelMediaCommandEnum? commandToSend = null; 10117 uint commandToSend = 0;
9387 float time = 0.0f; // default is from start 10118 float time = 0.0f; // default is from start
9388 10119
9389 ScenePresence presence = null; 10120 ScenePresence presence = null;
9390 10121
9391 for (int i = 0; i < commandList.Data.Length; i++) 10122 for (int i = 0; i < commandList.Data.Length; i++)
9392 { 10123 {
9393 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10124 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9394 switch (command) 10125 switch (command)
9395 { 10126 {
9396 case ParcelMediaCommandEnum.Agent: 10127 case (uint)ParcelMediaCommandEnum.Agent:
9397 // we send only to one agent 10128 // we send only to one agent
9398 if ((i + 1) < commandList.Length) 10129 if ((i + 1) < commandList.Length)
9399 { 10130 {
@@ -9410,25 +10141,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9410 } 10141 }
9411 break; 10142 break;
9412 10143
9413 case ParcelMediaCommandEnum.Loop: 10144 case (uint)ParcelMediaCommandEnum.Loop:
9414 loop = 1; 10145 loop = 1;
9415 commandToSend = command; 10146 commandToSend = command;
9416 update = true; //need to send the media update packet to set looping 10147 update = true; //need to send the media update packet to set looping
9417 break; 10148 break;
9418 10149
9419 case ParcelMediaCommandEnum.Play: 10150 case (uint)ParcelMediaCommandEnum.Play:
9420 loop = 0; 10151 loop = 0;
9421 commandToSend = command; 10152 commandToSend = command;
9422 update = true; //need to send the media update packet to make sure it doesn't loop 10153 update = true; //need to send the media update packet to make sure it doesn't loop
9423 break; 10154 break;
9424 10155
9425 case ParcelMediaCommandEnum.Pause: 10156 case (uint)ParcelMediaCommandEnum.Pause:
9426 case ParcelMediaCommandEnum.Stop: 10157 case (uint)ParcelMediaCommandEnum.Stop:
9427 case ParcelMediaCommandEnum.Unload: 10158 case (uint)ParcelMediaCommandEnum.Unload:
9428 commandToSend = command; 10159 commandToSend = command;
9429 break; 10160 break;
9430 10161
9431 case ParcelMediaCommandEnum.Url: 10162 case (uint)ParcelMediaCommandEnum.Url:
9432 if ((i + 1) < commandList.Length) 10163 if ((i + 1) < commandList.Length)
9433 { 10164 {
9434 if (commandList.Data[i + 1] is LSL_String) 10165 if (commandList.Data[i + 1] is LSL_String)
@@ -9441,7 +10172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 } 10172 }
9442 break; 10173 break;
9443 10174
9444 case ParcelMediaCommandEnum.Texture: 10175 case (uint)ParcelMediaCommandEnum.Texture:
9445 if ((i + 1) < commandList.Length) 10176 if ((i + 1) < commandList.Length)
9446 { 10177 {
9447 if (commandList.Data[i + 1] is LSL_String) 10178 if (commandList.Data[i + 1] is LSL_String)
@@ -9454,7 +10185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 } 10185 }
9455 break; 10186 break;
9456 10187
9457 case ParcelMediaCommandEnum.Time: 10188 case (uint)ParcelMediaCommandEnum.Time:
9458 if ((i + 1) < commandList.Length) 10189 if ((i + 1) < commandList.Length)
9459 { 10190 {
9460 if (commandList.Data[i + 1] is LSL_Float) 10191 if (commandList.Data[i + 1] is LSL_Float)
@@ -9466,7 +10197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9466 } 10197 }
9467 break; 10198 break;
9468 10199
9469 case ParcelMediaCommandEnum.AutoAlign: 10200 case (uint)ParcelMediaCommandEnum.AutoAlign:
9470 if ((i + 1) < commandList.Length) 10201 if ((i + 1) < commandList.Length)
9471 { 10202 {
9472 if (commandList.Data[i + 1] is LSL_Integer) 10203 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9480,7 +10211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 } 10211 }
9481 break; 10212 break;
9482 10213
9483 case ParcelMediaCommandEnum.Type: 10214 case (uint)ParcelMediaCommandEnum.Type:
9484 if ((i + 1) < commandList.Length) 10215 if ((i + 1) < commandList.Length)
9485 { 10216 {
9486 if (commandList.Data[i + 1] is LSL_String) 10217 if (commandList.Data[i + 1] is LSL_String)
@@ -9493,7 +10224,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9493 } 10224 }
9494 break; 10225 break;
9495 10226
9496 case ParcelMediaCommandEnum.Desc: 10227 case (uint)ParcelMediaCommandEnum.Desc:
9497 if ((i + 1) < commandList.Length) 10228 if ((i + 1) < commandList.Length)
9498 { 10229 {
9499 if (commandList.Data[i + 1] is LSL_String) 10230 if (commandList.Data[i + 1] is LSL_String)
@@ -9506,7 +10237,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 } 10237 }
9507 break; 10238 break;
9508 10239
9509 case ParcelMediaCommandEnum.Size: 10240 case (uint)ParcelMediaCommandEnum.Size:
9510 if ((i + 2) < commandList.Length) 10241 if ((i + 2) < commandList.Length)
9511 { 10242 {
9512 if (commandList.Data[i + 1] is LSL_Integer) 10243 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9576,7 +10307,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9576 } 10307 }
9577 } 10308 }
9578 10309
9579 if (commandToSend != null) 10310 if (commandToSend != 0)
9580 { 10311 {
9581 // the commandList contained a start/stop/... command, too 10312 // the commandList contained a start/stop/... command, too
9582 if (presence == null) 10313 if (presence == null)
@@ -9613,7 +10344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9613 10344
9614 if (aList.Data[i] != null) 10345 if (aList.Data[i] != null)
9615 { 10346 {
9616 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10347 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9617 { 10348 {
9618 case ParcelMediaCommandEnum.Url: 10349 case ParcelMediaCommandEnum.Url:
9619 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10350 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9656,16 +10387,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 { 10387 {
9657 m_host.AddScriptLPS(1); 10388 m_host.AddScriptLPS(1);
9658 10389
9659 lock (m_host.TaskInventory) 10390 m_host.TaskInventory.LockItemsForRead(true);
10391 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9660 { 10392 {
9661 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10393 if (inv.Value.Name == name)
9662 { 10394 {
9663 if (inv.Value.Name == name) 10395 m_host.TaskInventory.LockItemsForRead(false);
9664 { 10396 return inv.Value.Type;
9665 return inv.Value.Type;
9666 }
9667 } 10397 }
9668 } 10398 }
10399 m_host.TaskInventory.LockItemsForRead(false);
9669 10400
9670 return -1; 10401 return -1;
9671 } 10402 }
@@ -9676,15 +10407,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9676 10407
9677 if (quick_pay_buttons.Data.Length < 4) 10408 if (quick_pay_buttons.Data.Length < 4)
9678 { 10409 {
9679 LSLError("List must have at least 4 elements"); 10410 int x;
9680 return; 10411 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10412 {
10413 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10414 }
9681 } 10415 }
9682 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10416 int[] nPrice = new int[5];
9683 10417 nPrice[0] = price;
9684 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10418 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9685 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10419 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9686 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10420 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9687 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10421 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10422 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9688 m_host.ParentGroup.HasGroupChanged = true; 10423 m_host.ParentGroup.HasGroupChanged = true;
9689 } 10424 }
9690 10425
@@ -9696,17 +10431,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9696 if (invItemID == UUID.Zero) 10431 if (invItemID == UUID.Zero)
9697 return new LSL_Vector(); 10432 return new LSL_Vector();
9698 10433
9699 lock (m_host.TaskInventory) 10434 m_host.TaskInventory.LockItemsForRead(true);
10435 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9700 { 10436 {
9701 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10437 m_host.TaskInventory.LockItemsForRead(false);
9702 return new LSL_Vector(); 10438 return new LSL_Vector();
10439 }
9703 10440
9704 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10441 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9705 { 10442 {
9706 ShoutError("No permissions to track the camera"); 10443 ShoutError("No permissions to track the camera");
9707 return new LSL_Vector(); 10444 m_host.TaskInventory.LockItemsForRead(false);
9708 } 10445 return new LSL_Vector();
9709 } 10446 }
10447 m_host.TaskInventory.LockItemsForRead(false);
9710 10448
9711 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10449 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9712 if (presence != null) 10450 if (presence != null)
@@ -9724,17 +10462,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 if (invItemID == UUID.Zero) 10462 if (invItemID == UUID.Zero)
9725 return new LSL_Rotation(); 10463 return new LSL_Rotation();
9726 10464
9727 lock (m_host.TaskInventory) 10465 m_host.TaskInventory.LockItemsForRead(true);
10466 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9728 { 10467 {
9729 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10468 m_host.TaskInventory.LockItemsForRead(false);
9730 return new LSL_Rotation(); 10469 return new LSL_Rotation();
9731 10470 }
9732 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10471 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9733 { 10472 {
9734 ShoutError("No permissions to track the camera"); 10473 ShoutError("No permissions to track the camera");
9735 return new LSL_Rotation(); 10474 m_host.TaskInventory.LockItemsForRead(false);
9736 } 10475 return new LSL_Rotation();
9737 } 10476 }
10477 m_host.TaskInventory.LockItemsForRead(false);
9738 10478
9739 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10479 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9740 if (presence != null) 10480 if (presence != null)
@@ -9796,8 +10536,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9796 { 10536 {
9797 m_host.AddScriptLPS(1); 10537 m_host.AddScriptLPS(1);
9798 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10538 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9799 if (detectedParams == null) return; // only works on the first detected avatar 10539 if (detectedParams == null)
9800 10540 {
10541 if (m_host.ParentGroup.IsAttachment == true)
10542 {
10543 detectedParams = new DetectParams();
10544 detectedParams.Key = m_host.OwnerID;
10545 }
10546 else
10547 {
10548 return;
10549 }
10550 }
10551
9801 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10552 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9802 if (avatar != null) 10553 if (avatar != null)
9803 { 10554 {
@@ -9805,6 +10556,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10556 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9806 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10557 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9807 } 10558 }
10559
9808 ScriptSleep(1000); 10560 ScriptSleep(1000);
9809 } 10561 }
9810 10562
@@ -9916,14 +10668,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9916 if (objectID == UUID.Zero) return; 10668 if (objectID == UUID.Zero) return;
9917 10669
9918 UUID agentID; 10670 UUID agentID;
9919 lock (m_host.TaskInventory) 10671 m_host.TaskInventory.LockItemsForRead(true);
9920 { 10672 // we need the permission first, to know which avatar we want to set the camera for
9921 // we need the permission first, to know which avatar we want to set the camera for 10673 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9922 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9923 10674
9924 if (agentID == UUID.Zero) return; 10675 if (agentID == UUID.Zero)
9925 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10676 {
10677 m_host.TaskInventory.LockItemsForRead(false);
10678 return;
10679 }
10680 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10681 {
10682 m_host.TaskInventory.LockItemsForRead(false);
10683 return;
9926 } 10684 }
10685 m_host.TaskInventory.LockItemsForRead(false);
9927 10686
9928 ScenePresence presence = World.GetScenePresence(agentID); 10687 ScenePresence presence = World.GetScenePresence(agentID);
9929 10688
@@ -9932,12 +10691,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9932 10691
9933 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10692 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9934 object[] data = rules.Data; 10693 object[] data = rules.Data;
9935 for (int i = 0; i < data.Length; ++i) { 10694 for (int i = 0; i < data.Length; ++i)
10695 {
9936 int type = Convert.ToInt32(data[i++].ToString()); 10696 int type = Convert.ToInt32(data[i++].ToString());
9937 if (i >= data.Length) break; // odd number of entries => ignore the last 10697 if (i >= data.Length) break; // odd number of entries => ignore the last
9938 10698
9939 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10699 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9940 switch (type) { 10700 switch (type)
10701 {
9941 case ScriptBaseClass.CAMERA_FOCUS: 10702 case ScriptBaseClass.CAMERA_FOCUS:
9942 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10703 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9943 case ScriptBaseClass.CAMERA_POSITION: 10704 case ScriptBaseClass.CAMERA_POSITION:
@@ -9973,12 +10734,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9973 10734
9974 // we need the permission first, to know which avatar we want to clear the camera for 10735 // we need the permission first, to know which avatar we want to clear the camera for
9975 UUID agentID; 10736 UUID agentID;
9976 lock (m_host.TaskInventory) 10737 m_host.TaskInventory.LockItemsForRead(true);
10738 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10739 if (agentID == UUID.Zero)
10740 {
10741 m_host.TaskInventory.LockItemsForRead(false);
10742 return;
10743 }
10744 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9977 { 10745 {
9978 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10746 m_host.TaskInventory.LockItemsForRead(false);
9979 if (agentID == UUID.Zero) return; 10747 return;
9980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9981 } 10748 }
10749 m_host.TaskInventory.LockItemsForRead(false);
9982 10750
9983 ScenePresence presence = World.GetScenePresence(agentID); 10751 ScenePresence presence = World.GetScenePresence(agentID);
9984 10752
@@ -10045,19 +10813,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10045 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10813 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10046 { 10814 {
10047 m_host.AddScriptLPS(1); 10815 m_host.AddScriptLPS(1);
10048 string ret = String.Empty; 10816
10049 string src1 = llBase64ToString(str1); 10817 if (str1 == String.Empty)
10050 string src2 = llBase64ToString(str2); 10818 return String.Empty;
10051 int c = 0; 10819 if (str2 == String.Empty)
10052 for (int i = 0; i < src1.Length; i++) 10820 return str1;
10821
10822 int len = str2.Length;
10823 if ((len % 4) != 0) // LL is EVIL!!!!
10053 { 10824 {
10054 ret += (char) (src1[i] ^ src2[c]); 10825 while (str2.EndsWith("="))
10826 str2 = str2.Substring(0, str2.Length - 1);
10827
10828 len = str2.Length;
10829 int mod = len % 4;
10055 10830
10056 c++; 10831 if (mod == 1)
10057 if (c >= src2.Length) 10832 str2 = str2.Substring(0, str2.Length - 1);
10058 c = 0; 10833 else if (mod == 2)
10834 str2 += "==";
10835 else if (mod == 3)
10836 str2 += "=";
10059 } 10837 }
10060 return llStringToBase64(ret); 10838
10839 byte[] data1;
10840 byte[] data2;
10841 try
10842 {
10843 data1 = Convert.FromBase64String(str1);
10844 data2 = Convert.FromBase64String(str2);
10845 }
10846 catch (Exception)
10847 {
10848 return new LSL_String(String.Empty);
10849 }
10850
10851 byte[] d2 = new Byte[data1.Length];
10852 int pos = 0;
10853
10854 if (data1.Length <= data2.Length)
10855 {
10856 Array.Copy(data2, 0, d2, 0, data1.Length);
10857 }
10858 else
10859 {
10860 while (pos < data1.Length)
10861 {
10862 len = data1.Length - pos;
10863 if (len > data2.Length)
10864 len = data2.Length;
10865
10866 Array.Copy(data2, 0, d2, pos, len);
10867 pos += len;
10868 }
10869 }
10870
10871 for (pos = 0 ; pos < data1.Length ; pos++ )
10872 data1[pos] ^= d2[pos];
10873
10874 return Convert.ToBase64String(data1);
10061 } 10875 }
10062 10876
10063 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10877 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10114,12 +10928,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10114 Regex r = new Regex(authregex); 10928 Regex r = new Regex(authregex);
10115 int[] gnums = r.GetGroupNumbers(); 10929 int[] gnums = r.GetGroupNumbers();
10116 Match m = r.Match(url); 10930 Match m = r.Match(url);
10117 if (m.Success) { 10931 if (m.Success)
10118 for (int i = 1; i < gnums.Length; i++) { 10932 {
10933 for (int i = 1; i < gnums.Length; i++)
10934 {
10119 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10935 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10120 //CaptureCollection cc = g.Captures; 10936 //CaptureCollection cc = g.Captures;
10121 } 10937 }
10122 if (m.Groups.Count == 5) { 10938 if (m.Groups.Count == 5)
10939 {
10123 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10940 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10124 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10941 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10125 } 10942 }
@@ -10483,15 +11300,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10483 11300
10484 internal UUID ScriptByName(string name) 11301 internal UUID ScriptByName(string name)
10485 { 11302 {
10486 lock (m_host.TaskInventory) 11303 m_host.TaskInventory.LockItemsForRead(true);
11304
11305 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10487 { 11306 {
10488 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11307 if (item.Type == 10 && item.Name == name)
10489 { 11308 {
10490 if (item.Type == 10 && item.Name == name) 11309 m_host.TaskInventory.LockItemsForRead(false);
10491 return item.ItemID; 11310 return item.ItemID;
10492 } 11311 }
10493 } 11312 }
10494 11313
11314 m_host.TaskInventory.LockItemsForRead(false);
11315
10495 return UUID.Zero; 11316 return UUID.Zero;
10496 } 11317 }
10497 11318
@@ -10532,6 +11353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10532 { 11353 {
10533 m_host.AddScriptLPS(1); 11354 m_host.AddScriptLPS(1);
10534 11355
11356 //Clone is thread safe
10535 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11357 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10536 11358
10537 UUID assetID = UUID.Zero; 11359 UUID assetID = UUID.Zero;
@@ -10594,6 +11416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10594 { 11416 {
10595 m_host.AddScriptLPS(1); 11417 m_host.AddScriptLPS(1);
10596 11418
11419 //Clone is thread safe
10597 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11420 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10598 11421
10599 UUID assetID = UUID.Zero; 11422 UUID assetID = UUID.Zero;
@@ -10674,15 +11497,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10674 return GetLinkPrimitiveParams(obj, rules); 11497 return GetLinkPrimitiveParams(obj, rules);
10675 } 11498 }
10676 11499
10677 public void print(string str) 11500 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10678 { 11501 {
10679 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11502 List<SceneObjectPart> parts = GetLinkParts(link);
10680 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11503 if (parts.Count < 1)
10681 if (ossl != null) 11504 return 0;
10682 { 11505
10683 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11506 return GetNumberOfSides(parts[0]);
10684 m_log.Info("LSL print():" + str);
10685 }
10686 } 11507 }
10687 11508
10688 private string Name2Username(string name) 11509 private string Name2Username(string name)
@@ -10728,155 +11549,397 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10728 return rq.ToString(); 11549 return rq.ToString();
10729 } 11550 }
10730 11551
11552 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11553 {
11554 m_SayShoutCount = 0;
11555 }
11556
11557 private struct Tri
11558 {
11559 public Vector3 p1;
11560 public Vector3 p2;
11561 public Vector3 p3;
11562 }
11563
11564 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11565 {
11566 float height = avatar.Appearance.AvatarHeight;
11567 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11568 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11569
11570 if (point.X > b1.X && point.X < b2.X &&
11571 point.Y > b1.Y && point.Y < b2.Y &&
11572 point.Z > b1.Z && point.Z < b2.Z)
11573 return true;
11574 return false;
11575 }
11576
11577 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11578 {
11579 List<ContactResult> contacts = new List<ContactResult>();
11580
11581 Vector3 ab = rayEnd - rayStart;
11582
11583 World.ForEachScenePresence(delegate(ScenePresence sp)
11584 {
11585 Vector3 ac = sp.AbsolutePosition - rayStart;
11586 Vector3 bc = sp.AbsolutePosition - rayEnd;
11587
11588 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11589
11590 if (d > 1.5)
11591 return;
11592
11593 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11594
11595 if (d2 > 0)
11596 return;
11597
11598 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11599 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11600
11601 if (!InBoundingBox(sp, p))
11602 return;
11603
11604 ContactResult result = new ContactResult ();
11605 result.ConsumerID = sp.LocalId;
11606 result.Depth = Vector3.Distance(rayStart, p);
11607 result.Normal = Vector3.Zero;
11608 result.Pos = p;
11609
11610 contacts.Add(result);
11611 });
11612
11613 return contacts.ToArray();
11614 }
11615
11616 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11617 {
11618 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11619 List<ContactResult> contacts = new List<ContactResult>();
11620
11621 Vector3 ab = rayEnd - rayStart;
11622
11623 World.ForEachSOG(delegate(SceneObjectGroup group)
11624 {
11625 if (m_host.ParentGroup == group)
11626 return;
11627
11628 if (group.IsAttachment)
11629 return;
11630
11631 if (group.RootPart.PhysActor == null)
11632 {
11633 if (!includePhantom)
11634 return;
11635 }
11636 else
11637 {
11638 if (group.RootPart.PhysActor.IsPhysical)
11639 {
11640 if (!includePhysical)
11641 return;
11642 }
11643 else
11644 {
11645 if (!includeNonPhysical)
11646 return;
11647 }
11648 }
11649
11650 // Find the radius ouside of which we don't even need to hit test
11651 float minX;
11652 float maxX;
11653 float minY;
11654 float maxY;
11655 float minZ;
11656 float maxZ;
11657
11658 float radius = 0.0f;
11659
11660 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11661
11662 if (Math.Abs(minX) > radius)
11663 radius = Math.Abs(minX);
11664 if (Math.Abs(minY) > radius)
11665 radius = Math.Abs(minY);
11666 if (Math.Abs(minZ) > radius)
11667 radius = Math.Abs(minZ);
11668 if (Math.Abs(maxX) > radius)
11669 radius = Math.Abs(maxX);
11670 if (Math.Abs(maxY) > radius)
11671 radius = Math.Abs(maxY);
11672 if (Math.Abs(maxZ) > radius)
11673 radius = Math.Abs(maxZ);
11674
11675 Vector3 ac = group.AbsolutePosition - rayStart;
11676 Vector3 bc = group.AbsolutePosition - rayEnd;
11677
11678 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11679
11680 // Too far off ray, don't bother
11681 if (d > radius)
11682 return;
11683
11684 // Behind ray, drop
11685 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11686 if (d2 > 0)
11687 return;
11688
11689 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11690 // Miss.
11691 if (!intersection.HitTF)
11692 return;
11693
11694 ContactResult result = new ContactResult ();
11695 result.ConsumerID = group.LocalId;
11696 result.Depth = intersection.distance;
11697 result.Normal = intersection.normal;
11698 result.Pos = intersection.ipoint;
11699
11700 contacts.Add(result);
11701 });
11702
11703 return contacts.ToArray();
11704 }
11705
11706 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11707 {
11708 double[,] heightfield = World.Heightmap.GetDoubles();
11709 List<ContactResult> contacts = new List<ContactResult>();
11710
11711 double min = 2048.0;
11712 double max = 0.0;
11713
11714 // Find the min and max of the heightfield
11715 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11716 {
11717 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11718 {
11719 if (heightfield[x, y] > max)
11720 max = heightfield[x, y];
11721 if (heightfield[x, y] < min)
11722 min = heightfield[x, y];
11723 }
11724 }
11725
11726
11727 // A ray extends past rayEnd, but doesn't go back before
11728 // rayStart. If the start is above the highest point of the ground
11729 // and the ray goes up, we can't hit the ground. Ever.
11730 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11731 return null;
11732
11733 // Same for going down
11734 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11735 return null;
11736
11737 List<Tri> trilist = new List<Tri>();
11738
11739 // Create our triangle list
11740 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11741 {
11742 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11743 {
11744 Tri t1 = new Tri();
11745 Tri t2 = new Tri();
11746
11747 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11748 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11749 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11750 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11751
11752 t1.p1 = p1;
11753 t1.p2 = p2;
11754 t1.p3 = p3;
11755
11756 t2.p1 = p3;
11757 t2.p2 = p4;
11758 t2.p3 = p1;
11759
11760 trilist.Add(t1);
11761 trilist.Add(t2);
11762 }
11763 }
11764
11765 // Ray direction
11766 Vector3 rayDirection = rayEnd - rayStart;
11767
11768 foreach (Tri t in trilist)
11769 {
11770 // Compute triangle plane normal and edges
11771 Vector3 u = t.p2 - t.p1;
11772 Vector3 v = t.p3 - t.p1;
11773 Vector3 n = Vector3.Cross(u, v);
11774
11775 if (n == Vector3.Zero)
11776 continue;
11777
11778 Vector3 w0 = rayStart - t.p1;
11779 double a = -Vector3.Dot(n, w0);
11780 double b = Vector3.Dot(n, rayDirection);
11781
11782 // Not intersecting the plane, or in plane (same thing)
11783 // Ignoring this MAY cause the ground to not be detected
11784 // sometimes
11785 if (Math.Abs(b) < 0.000001)
11786 continue;
11787
11788 double r = a / b;
11789
11790 // ray points away from plane
11791 if (r < 0.0)
11792 continue;
11793
11794 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11795
11796 float uu = Vector3.Dot(u, u);
11797 float uv = Vector3.Dot(u, v);
11798 float vv = Vector3.Dot(v, v);
11799 Vector3 w = ip - t.p1;
11800 float wu = Vector3.Dot(w, u);
11801 float wv = Vector3.Dot(w, v);
11802 float d = uv * uv - uu * vv;
11803
11804 float cs = (uv * wv - vv * wu) / d;
11805 if (cs < 0 || cs > 1.0)
11806 continue;
11807 float ct = (uv * wu - uu * wv) / d;
11808 if (ct < 0 || (cs + ct) > 1.0)
11809 continue;
11810
11811 // Add contact point
11812 ContactResult result = new ContactResult ();
11813 result.ConsumerID = 0;
11814 result.Depth = Vector3.Distance(rayStart, ip);
11815 result.Normal = n;
11816 result.Pos = ip;
11817
11818 contacts.Add(result);
11819 }
11820
11821 if (contacts.Count == 0)
11822 return null;
11823
11824 contacts.Sort(delegate(ContactResult a, ContactResult b)
11825 {
11826 return (int)(a.Depth - b.Depth);
11827 });
11828
11829 return contacts[0];
11830 }
11831
10731 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11832 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10732 { 11833 {
11834 LSL_List list = new LSL_List();
11835
10733 m_host.AddScriptLPS(1); 11836 m_host.AddScriptLPS(1);
10734 11837
10735 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11838 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10736 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11839 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10737 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11840 Vector3 dir = rayEnd - rayStart;
10738 11841
10739 int count = 0; 11842 float dist = Vector3.Mag(dir);
10740// int detectPhantom = 0; 11843
11844 int count = 1;
11845 bool detectPhantom = false;
10741 int dataFlags = 0; 11846 int dataFlags = 0;
10742 int rejectTypes = 0; 11847 int rejectTypes = 0;
10743 11848
10744 for (int i = 0; i < options.Length; i += 2) 11849 for (int i = 0; i < options.Length; i += 2)
10745 { 11850 {
10746 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11851 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10747 {
10748 count = options.GetLSLIntegerItem(i + 1); 11852 count = options.GetLSLIntegerItem(i + 1);
10749 } 11853 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10750// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11854 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10751// {
10752// detectPhantom = options.GetLSLIntegerItem(i + 1);
10753// }
10754 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11855 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10755 {
10756 dataFlags = options.GetLSLIntegerItem(i + 1); 11856 dataFlags = options.GetLSLIntegerItem(i + 1);
10757 }
10758 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11857 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10759 {
10760 rejectTypes = options.GetLSLIntegerItem(i + 1); 11858 rejectTypes = options.GetLSLIntegerItem(i + 1);
10761 }
10762 } 11859 }
10763 11860
10764 LSL_List list = new LSL_List(); 11861 if (count > 16)
10765 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11862 count = 16;
10766
10767 double distance = Util.GetDistanceTo(startvector, endvector);
10768
10769 if (distance == 0)
10770 distance = 0.001;
10771 11863
10772 Vector3 posToCheck = startvector; 11864 List<ContactResult> results = new List<ContactResult>();
10773 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10774 11865
10775 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11866 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10776 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11867 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10777 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11868 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10778 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11869 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10779 11870
10780 for (float i = 0; i <= distance; i += 0.1f) 11871 if (checkTerrain)
10781 { 11872 {
10782 posToCheck = startvector + (dir * (i / (float)distance)); 11873 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11874 if (groundContact != null)
11875 results.Add((ContactResult)groundContact);
11876 }
10783 11877
10784 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11878 if (checkAgents)
10785 { 11879 {
10786 ContactResult result = new ContactResult(); 11880 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10787 result.ConsumerID = 0; 11881 foreach (ContactResult r in agentHits)
10788 result.Depth = 0; 11882 results.Add(r);
10789 result.Normal = Vector3.Zero; 11883 }
10790 result.Pos = posToCheck;
10791 results.Add(result);
10792 checkTerrain = false;
10793 }
10794 11884
10795 if (checkAgents) 11885 if (checkPhysical || checkNonPhysical)
10796 { 11886 {
10797 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11887 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10798 { 11888 foreach (ContactResult r in objectHits)
10799 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11889 results.Add(r);
10800 {
10801 ContactResult result = new ContactResult ();
10802 result.ConsumerID = sp.LocalId;
10803 result.Depth = 0;
10804 result.Normal = Vector3.Zero;
10805 result.Pos = posToCheck;
10806 results.Add(result);
10807 }
10808 });
10809 }
10810 } 11890 }
10811 11891
10812 int refcount = 0; 11892 results.Sort(delegate(ContactResult a, ContactResult b)
11893 {
11894 return (int)(a.Depth - b.Depth);
11895 });
11896
11897 int values = 0;
10813 foreach (ContactResult result in results) 11898 foreach (ContactResult result in results)
10814 { 11899 {
10815 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11900 if (result.Depth > dist)
10816 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10817 continue; 11901 continue;
10818 11902
10819 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11903 UUID itemID = UUID.Zero;
10820 11904 int linkNum = 0;
10821 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10822 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10823 11905
10824 if (entity == null) 11906 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11907 // It's a prim!
11908 if (part != null)
10825 { 11909 {
10826 list.Add(UUID.Zero); 11910 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10827 11911 itemID = part.ParentGroup.UUID;
10828 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11912 else
10829 list.Add(0); 11913 itemID = part.UUID;
10830
10831 list.Add(result.Pos);
10832
10833 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10834 list.Add(result.Normal);
10835 11914
10836 continue; //Can't find it, so add UUID.Zero 11915 linkNum = part.LinkNum;
10837 } 11916 }
10838 11917 else
10839 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10840 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10841 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10842
10843 if (entity is SceneObjectPart)
10844 { 11918 {
10845 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11919 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10846 11920 /// It it a boy? a girl?
10847 if (pa != null && pa.IsPhysical) 11921 if (sp != null)
10848 { 11922 itemID = sp.UUID;
10849 if (!checkPhysical)
10850 continue;
10851 }
10852 else
10853 {
10854 if (!checkNonPhysical)
10855 continue;
10856 }
10857 } 11923 }
10858 11924
10859 refcount++; 11925 list.Add(new LSL_String(itemID.ToString()));
10860 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11926 list.Add(new LSL_String(result.Pos.ToString()));
10861 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10862 else
10863 list.Add(entity.UUID);
10864 11927
10865 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11928 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10866 { 11929 list.Add(new LSL_Integer(linkNum));
10867 if (entity is SceneObjectPart)
10868 list.Add(((SceneObjectPart)entity).LinkNum);
10869 else
10870 list.Add(0);
10871 }
10872 11930
10873 list.Add(result.Pos);
10874 11931
10875 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11932 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10876 list.Add(result.Normal); 11933 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11934
11935 values++;
11936 count--;
11937
11938 if (count == 0)
11939 break;
10877 } 11940 }
10878 11941
10879 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11942 list.Add(new LSL_Integer(values));
10880 11943
10881 return list; 11944 return list;
10882 } 11945 }
@@ -10916,7 +11979,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10916 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11979 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10917 if (!isAccount) return 0; 11980 if (!isAccount) return 0;
10918 if (estate.HasAccess(id)) return 1; 11981 if (estate.HasAccess(id)) return 1;
10919 if (estate.IsBanned(id)) 11982 if (estate.IsBanned(id, World.GetUserFlags(id)))
10920 estate.RemoveBan(id); 11983 estate.RemoveBan(id);
10921 estate.AddEstateUser(id); 11984 estate.AddEstateUser(id);
10922 break; 11985 break;
@@ -10935,14 +11998,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10935 break; 11998 break;
10936 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11999 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10937 if (!isAccount) return 0; 12000 if (!isAccount) return 0;
10938 if (estate.IsBanned(id)) return 1; 12001 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10939 EstateBan ban = new EstateBan(); 12002 EstateBan ban = new EstateBan();
10940 ban.EstateID = estate.EstateID; 12003 ban.EstateID = estate.EstateID;
10941 ban.BannedUserID = id; 12004 ban.BannedUserID = id;
10942 estate.AddBan(ban); 12005 estate.AddBan(ban);
10943 break; 12006 break;
10944 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12007 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10945 if (!isAccount || !estate.IsBanned(id)) return 0; 12008 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10946 estate.RemoveBan(id); 12009 estate.RemoveBan(id);
10947 break; 12010 break;
10948 default: return 0; 12011 default: return 0;
@@ -10968,22 +12031,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10968 NotImplemented("llGetSPMaxMemory"); 12031 NotImplemented("llGetSPMaxMemory");
10969 } 12032 }
10970 12033
10971 public void llGetUsedMemory() 12034 public virtual LSL_Integer llGetUsedMemory()
10972 { 12035 {
10973 m_host.AddScriptLPS(1); 12036 m_host.AddScriptLPS(1);
10974 NotImplemented("llGetUsedMemory"); 12037 NotImplemented("llGetUsedMemory");
12038 return 0;
10975 } 12039 }
10976 12040
10977 public void llScriptProfiler(LSL_Integer flags) 12041 public void llScriptProfiler(LSL_Integer flags)
10978 { 12042 {
10979 m_host.AddScriptLPS(1); 12043 m_host.AddScriptLPS(1);
10980 NotImplemented("llScriptProfiler"); 12044 //NotImplemented("llScriptProfiler");
10981 } 12045 }
10982 12046
10983 public void llSetSoundQueueing(int queue) 12047 public void llSetSoundQueueing(int queue)
10984 { 12048 {
10985 m_host.AddScriptLPS(1); 12049 m_host.AddScriptLPS(1);
10986 NotImplemented("llSetSoundQueueing");
10987 } 12050 }
10988 12051
10989 public void llCollisionSprite(string impact_sprite) 12052 public void llCollisionSprite(string impact_sprite)
@@ -10995,10 +12058,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10995 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12058 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10996 { 12059 {
10997 m_host.AddScriptLPS(1); 12060 m_host.AddScriptLPS(1);
10998 NotImplemented("llGodLikeRezObject"); 12061
12062 if (!World.Permissions.IsGod(m_host.OwnerID))
12063 NotImplemented("llGodLikeRezObject");
12064
12065 AssetBase rezAsset = World.AssetService.Get(inventory);
12066 if (rezAsset == null)
12067 {
12068 llSay(0, "Asset not found");
12069 return;
12070 }
12071
12072 SceneObjectGroup group = null;
12073
12074 try
12075 {
12076 string xmlData = Utils.BytesToString(rezAsset.Data);
12077 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12078 }
12079 catch
12080 {
12081 llSay(0, "Asset not found");
12082 return;
12083 }
12084
12085 if (group == null)
12086 {
12087 llSay(0, "Asset not found");
12088 return;
12089 }
12090
12091 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12092 group.RootPart.AttachOffset = group.AbsolutePosition;
12093
12094 group.ResetIDs();
12095
12096 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12097 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12098 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12099 group.ScheduleGroupForFullUpdate();
12100
12101 // objects rezzed with this method are die_at_edge by default.
12102 group.RootPart.SetDieAtEdge(true);
12103
12104 group.ResumeScripts();
12105
12106 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12107 "object_rez", new Object[] {
12108 new LSL_String(
12109 group.RootPart.UUID.ToString()) },
12110 new DetectParams[0]));
12111 }
12112
12113 public LSL_String llTransferLindenDollars(string destination, int amount)
12114 {
12115 UUID txn = UUID.Random();
12116
12117 Util.FireAndForget(delegate(object x)
12118 {
12119 int replycode = 0;
12120 string replydata = destination + "," + amount.ToString();
12121
12122 try
12123 {
12124 UUID invItemID=InventorySelf();
12125 if (invItemID == UUID.Zero)
12126 {
12127 replydata = "SERVICE_ERROR";
12128 return;
12129 }
12130
12131 m_host.AddScriptLPS(1);
12132
12133 m_host.TaskInventory.LockItemsForRead(true);
12134 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12135 m_host.TaskInventory.LockItemsForRead(false);
12136
12137 if (item.PermsGranter == UUID.Zero)
12138 {
12139 replydata = "MISSING_PERMISSION_DEBIT";
12140 return;
12141 }
12142
12143 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12144 {
12145 replydata = "MISSING_PERMISSION_DEBIT";
12146 return;
12147 }
12148
12149 UUID toID = new UUID();
12150
12151 if (!UUID.TryParse(destination, out toID))
12152 {
12153 replydata = "INVALID_AGENT";
12154 return;
12155 }
12156
12157 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12158
12159 if (money == null)
12160 {
12161 replydata = "TRANSFERS_DISABLED";
12162 return;
12163 }
12164
12165 bool result = money.ObjectGiveMoney(
12166 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12167
12168 if (result)
12169 {
12170 replycode = 1;
12171 return;
12172 }
12173
12174 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12175 }
12176 finally
12177 {
12178 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12179 "transaction_result", new Object[] {
12180 new LSL_String(txn.ToString()),
12181 new LSL_Integer(replycode),
12182 new LSL_String(replydata) },
12183 new DetectParams[0]));
12184 }
12185 });
12186
12187 return txn.ToString();
10999 } 12188 }
11000 12189
11001 #endregion 12190 #endregion
12191
12192 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12193 {
12194 SceneObjectGroup group = m_host.ParentGroup;
12195
12196 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12197 return;
12198 if (group.IsAttachment)
12199 return;
12200
12201 if (frames.Data.Length > 0) // We are getting a new motion
12202 {
12203 if (group.RootPart.KeyframeMotion != null)
12204 group.RootPart.KeyframeMotion.Stop();
12205 group.RootPart.KeyframeMotion = null;
12206
12207 int idx = 0;
12208
12209 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12210 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12211
12212 while (idx < options.Data.Length)
12213 {
12214 int option = (int)options.GetLSLIntegerItem(idx++);
12215 int remain = options.Data.Length - idx;
12216
12217 switch (option)
12218 {
12219 case ScriptBaseClass.KFM_MODE:
12220 if (remain < 1)
12221 break;
12222 int modeval = (int)options.GetLSLIntegerItem(idx++);
12223 switch(modeval)
12224 {
12225 case ScriptBaseClass.KFM_FORWARD:
12226 mode = KeyframeMotion.PlayMode.Forward;
12227 break;
12228 case ScriptBaseClass.KFM_REVERSE:
12229 mode = KeyframeMotion.PlayMode.Reverse;
12230 break;
12231 case ScriptBaseClass.KFM_LOOP:
12232 mode = KeyframeMotion.PlayMode.Loop;
12233 break;
12234 case ScriptBaseClass.KFM_PING_PONG:
12235 mode = KeyframeMotion.PlayMode.PingPong;
12236 break;
12237 }
12238 break;
12239 case ScriptBaseClass.KFM_DATA:
12240 if (remain < 1)
12241 break;
12242 int dataval = (int)options.GetLSLIntegerItem(idx++);
12243 data = (KeyframeMotion.DataFormat)dataval;
12244 break;
12245 }
12246 }
12247
12248 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12249
12250 idx = 0;
12251
12252 int elemLength = 2;
12253 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12254 elemLength = 3;
12255
12256 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12257 while (idx < frames.Data.Length)
12258 {
12259 int remain = frames.Data.Length - idx;
12260
12261 if (remain < elemLength)
12262 break;
12263
12264 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12265 frame.Position = null;
12266 frame.Rotation = null;
12267
12268 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12269 {
12270 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12271 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12272 }
12273 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12274 {
12275 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12276 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12277 }
12278
12279 float tempf = (float)frames.GetLSLFloatItem(idx++);
12280 frame.TimeMS = (int)(tempf * 1000.0f);
12281
12282 keyframes.Add(frame);
12283 }
12284
12285 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12286 group.RootPart.KeyframeMotion.Start();
12287 }
12288 else
12289 {
12290 if (group.RootPart.KeyframeMotion == null)
12291 return;
12292
12293 if (options.Data.Length == 0)
12294 {
12295 group.RootPart.KeyframeMotion.Stop();
12296 return;
12297 }
12298
12299 int code = (int)options.GetLSLIntegerItem(0);
12300
12301 int idx = 0;
12302
12303 while (idx < options.Data.Length)
12304 {
12305 int option = (int)options.GetLSLIntegerItem(idx++);
12306 int remain = options.Data.Length - idx;
12307
12308 switch (option)
12309 {
12310 case ScriptBaseClass.KFM_COMMAND:
12311 int cmd = (int)options.GetLSLIntegerItem(idx++);
12312 switch (cmd)
12313 {
12314 case ScriptBaseClass.KFM_CMD_PLAY:
12315 group.RootPart.KeyframeMotion.Start();
12316 break;
12317 case ScriptBaseClass.KFM_CMD_STOP:
12318 group.RootPart.KeyframeMotion.Stop();
12319 break;
12320 case ScriptBaseClass.KFM_CMD_PAUSE:
12321 group.RootPart.KeyframeMotion.Pause();
12322 break;
12323 }
12324 break;
12325 }
12326 }
12327 }
12328 }
11002 } 12329 }
11003 12330
11004 public class NotecardCache 12331 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 a5dcba4..0dc2aa2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
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 private void InitLSL() 221 private void InitLSL()
@@ -917,18 +926,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
917 if (target != null) 926 if (target != null)
918 { 927 {
919 UUID animID=UUID.Zero; 928 UUID animID=UUID.Zero;
920 lock (m_host.TaskInventory) 929 m_host.TaskInventory.LockItemsForRead(true);
930 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
921 { 931 {
922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 932 if (inv.Value.Name == animation)
923 { 933 {
924 if (inv.Value.Name == animation) 934 if (inv.Value.Type == (int)AssetType.Animation)
925 { 935 animID = inv.Value.AssetID;
926 if (inv.Value.Type == (int)AssetType.Animation) 936 continue;
927 animID = inv.Value.AssetID;
928 continue;
929 }
930 } 937 }
931 } 938 }
939 m_host.TaskInventory.LockItemsForRead(false);
932 if (animID == UUID.Zero) 940 if (animID == UUID.Zero)
933 target.Animator.AddAnimation(animation, m_host.UUID); 941 target.Animator.AddAnimation(animation, m_host.UUID);
934 else 942 else
@@ -955,18 +963,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
955 if (target != null) 963 if (target != null)
956 { 964 {
957 UUID animID = UUID.Zero; 965 UUID animID = UUID.Zero;
958 lock (m_host.TaskInventory) 966 m_host.TaskInventory.LockItemsForRead(true);
967 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
959 { 968 {
960 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 969 if (inv.Value.Name == animation)
961 { 970 {
962 if (inv.Value.Name == animation) 971 if (inv.Value.Type == (int)AssetType.Animation)
963 { 972 animID = inv.Value.AssetID;
964 if (inv.Value.Type == (int)AssetType.Animation) 973 continue;
965 animID = inv.Value.AssetID;
966 continue;
967 }
968 } 974 }
969 } 975 }
976 m_host.TaskInventory.LockItemsForRead(false);
970 977
971 if (animID == UUID.Zero) 978 if (animID == UUID.Zero)
972 target.Animator.RemoveAnimation(animation); 979 target.Animator.RemoveAnimation(animation);
@@ -1798,6 +1805,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1798 1805
1799 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1806 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1800 { 1807 {
1808 m_host.TaskInventory.LockItemsForRead(true);
1801 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1809 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1802 { 1810 {
1803 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1811 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1805,6 +1813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1805 assetID = item.AssetID; 1813 assetID = item.AssetID;
1806 } 1814 }
1807 } 1815 }
1816 m_host.TaskInventory.LockItemsForRead(false);
1808 } 1817 }
1809 1818
1810 if (assetID == UUID.Zero) 1819 if (assetID == UUID.Zero)
@@ -2272,7 +2281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2272 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2281 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2273 m_host.AddScriptLPS(1); 2282 m_host.AddScriptLPS(1);
2274 2283
2275 return NpcCreate(firstname, lastname, position, notecard, false, false); 2284 return NpcCreate(firstname, lastname, position, notecard, true, false);
2276 } 2285 }
2277 2286
2278 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2287 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2283,24 +2292,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 return NpcCreate( 2292 return NpcCreate(
2284 firstname, lastname, position, notecard, 2293 firstname, lastname, position, notecard,
2285 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2294 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2286 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2295 false);
2296// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2287 } 2297 }
2288 2298
2289 private LSL_Key NpcCreate( 2299 private LSL_Key NpcCreate(
2290 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2300 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2291 { 2301 {
2302 if (!owned)
2303 OSSLError("Unowned NPCs are unsupported");
2304
2305 string groupTitle = String.Empty;
2306
2307 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2308 return new LSL_Key(UUID.Zero.ToString());
2309
2310 if (firstname != String.Empty || lastname != String.Empty)
2311 {
2312 if (firstname != "Shown outfit:")
2313 groupTitle = "- NPC -";
2314 }
2315
2292 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2316 INPCModule module = World.RequestModuleInterface<INPCModule>();
2293 if (module != null) 2317 if (module != null)
2294 { 2318 {
2295 AvatarAppearance appearance = null; 2319 AvatarAppearance appearance = null;
2296 2320
2297 UUID id; 2321// UUID id;
2298 if (UUID.TryParse(notecard, out id)) 2322// if (UUID.TryParse(notecard, out id))
2299 { 2323// {
2300 ScenePresence clonePresence = World.GetScenePresence(id); 2324// ScenePresence clonePresence = World.GetScenePresence(id);
2301 if (clonePresence != null) 2325// if (clonePresence != null)
2302 appearance = clonePresence.Appearance; 2326// appearance = clonePresence.Appearance;
2303 } 2327// }
2304 2328
2305 if (appearance == null) 2329 if (appearance == null)
2306 { 2330 {
@@ -2328,6 +2352,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2328 World, 2352 World,
2329 appearance); 2353 appearance);
2330 2354
2355 ScenePresence sp;
2356 if (World.TryGetScenePresence(x, out sp))
2357 {
2358 sp.Grouptitle = groupTitle;
2359 sp.SendAvatarDataToAllAgents();
2360 }
2331 return new LSL_Key(x.ToString()); 2361 return new LSL_Key(x.ToString());
2332 } 2362 }
2333 2363
@@ -2596,16 +2626,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2596 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2626 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2597 m_host.AddScriptLPS(1); 2627 m_host.AddScriptLPS(1);
2598 2628
2599 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2629 ManualResetEvent ev = new ManualResetEvent(false);
2600 if (module != null)
2601 {
2602 UUID npcId = new UUID(npc.m_string);
2603 2630
2604 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2631 Util.FireAndForget(delegate(object x) {
2605 return; 2632 try
2633 {
2634 INPCModule module = World.RequestModuleInterface<INPCModule>();
2635 if (module != null)
2636 {
2637 UUID npcId = new UUID(npc.m_string);
2606 2638
2607 module.DeleteNPC(npcId, World); 2639 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2608 } 2640 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2641 {
2642 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2643 return;
2644 }
2645
2646 module.DeleteNPC(npcId, World);
2647 }
2648 }
2649 finally
2650 {
2651 ev.Set();
2652 }
2653 });
2654 ev.WaitOne();
2609 } 2655 }
2610 2656
2611 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2657 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3050,4 +3096,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 return ScriptBaseClass.TRUE; 3096 return ScriptBaseClass.TRUE;
3051 } 3097 }
3052 } 3098 }
3053} \ No newline at end of file 3099}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 1c272f8..1373971 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
222 // Is the sensor type is AGENT and not SCRIPTED then include agents 222 // Is the sensor type is AGENT and not SCRIPTED then include agents
223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
224 { 224 {
225 sensedEntities.AddRange(doAgentSensor(ts)); 225 sensedEntities.AddRange(doAgentSensor(ts));
226 } 226 }
227 227
228 // If SCRIPTED or PASSIVE or ACTIVE check objects 228 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -319,13 +319,15 @@ 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.RotationOffset; 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, the sensor cone always orients with the 326 // In attachments, the sensor cone always orients with the
326 // avatar rotation. This may include a nonzero elevation if 327 // avatar rotation. This may include a nonzero elevation if
327 // in mouselook. 328 // in mouselook.
328 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 329 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
330 fromRegionPos = avatar.AbsolutePosition;
329 q = avatar.Rotation; 331 q = avatar.Rotation;
330 } 332 }
331 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 333 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -448,6 +450,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
448 // avatar rotation. This may include a nonzero elevation if 450 // avatar rotation. This may include a nonzero elevation if
449 // in mouselook. 451 // in mouselook.
450 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 452 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
453 if (avatar == null)
454 return sensedEntities;
455 fromRegionPos = avatar.AbsolutePosition;
451 q = avatar.Rotation; 456 q = avatar.Rotation;
452 } 457 }
453 458
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 0f53bc3..b976dc3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -124,6 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
124 LSL_Float llGetEnergy(); 124 LSL_Float llGetEnergy();
125 LSL_Vector llGetForce(); 125 LSL_Vector llGetForce();
126 LSL_Integer llGetFreeMemory(); 126 LSL_Integer llGetFreeMemory();
127 LSL_Integer llGetUsedMemory();
127 LSL_Integer llGetFreeURLs(); 128 LSL_Integer llGetFreeURLs();
128 LSL_Vector llGetGeometricCenter(); 129 LSL_Vector llGetGeometricCenter();
129 LSL_Float llGetGMTclock(); 130 LSL_Float llGetGMTclock();
@@ -203,6 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
203 void llGiveInventory(string destination, string inventory); 204 void llGiveInventory(string destination, string inventory);
204 void llGiveInventoryList(string destination, string category, LSL_List inventory); 205 void llGiveInventoryList(string destination, string category, LSL_List inventory);
205 LSL_Integer llGiveMoney(string destination, int amount); 206 LSL_Integer llGiveMoney(string destination, int amount);
207 LSL_String llTransferLindenDollars(string destination, int amount);
206 void llGodLikeRezObject(string inventory, LSL_Vector pos); 208 void llGodLikeRezObject(string inventory, LSL_Vector pos);
207 LSL_Float llGround(LSL_Vector offset); 209 LSL_Float llGround(LSL_Vector offset);
208 LSL_Vector llGroundContour(LSL_Vector offset); 210 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -348,6 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
348 void llSetParcelMusicURL(string url); 350 void llSetParcelMusicURL(string url);
349 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 351 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
350 void llSetPos(LSL_Vector pos); 352 void llSetPos(LSL_Vector pos);
353 LSL_Integer llSetRegionPos(LSL_Vector pos);
351 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 354 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
352 void llSetPrimitiveParams(LSL_List rules); 355 void llSetPrimitiveParams(LSL_List rules);
353 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 356 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -396,6 +399,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
396 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 399 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
397 void llTargetRemove(int number); 400 void llTargetRemove(int number);
398 void llTeleportAgentHome(string agent); 401 void llTeleportAgentHome(string agent);
402 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
399 void llTextBox(string avatar, string message, int chat_channel); 403 void llTextBox(string avatar, string message, int chat_channel);
400 LSL_String llToLower(string source); 404 LSL_String llToLower(string source);
401 LSL_String llToUpper(string source); 405 LSL_String llToUpper(string source);
@@ -412,9 +416,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
412 LSL_Vector llWind(LSL_Vector offset); 416 LSL_Vector llWind(LSL_Vector offset);
413 LSL_String llXorBase64Strings(string str1, string str2); 417 LSL_String llXorBase64Strings(string str1, string str2);
414 LSL_String llXorBase64StringsCorrect(string str1, string str2); 418 LSL_String llXorBase64StringsCorrect(string str1, string str2);
415 void print(string str); 419 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
420 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
416 421
417 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 422 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
418 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 423 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
424 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
419 } 425 }
420} 426}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 30bd3ef..444a681 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 f58f9d6..6246b57 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;
@@ -578,6 +580,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
578 public const int PRIM_MEDIA_PERM_OWNER = 1; 580 public const int PRIM_MEDIA_PERM_OWNER = 1;
579 public const int PRIM_MEDIA_PERM_GROUP = 2; 581 public const int PRIM_MEDIA_PERM_GROUP = 2;
580 public const int PRIM_MEDIA_PERM_ANYONE = 4; 582 public const int PRIM_MEDIA_PERM_ANYONE = 4;
583
584 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
585 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
586 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
587 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
588
589 public const int PRIM_PHYSICS_MATERIAL = 31;
590 public const int DENSITY = 1;
591 public const int FRICTION = 2;
592 public const int RESTITUTION = 4;
593 public const int GRAVITY_MULTIPLIER = 8;
581 594
582 // extra constants for llSetPrimMediaParams 595 // extra constants for llSetPrimMediaParams
583 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 596 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -650,5 +663,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
650 public static readonly LSLInteger RCERR_UNKNOWN = -1; 663 public static readonly LSLInteger RCERR_UNKNOWN = -1;
651 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 664 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
652 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 665 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
666
667 public const int KFM_MODE = 1;
668 public const int KFM_LOOP = 1;
669 public const int KFM_REVERSE = 3;
670 public const int KFM_FORWARD = 0;
671 public const int KFM_PING_PONG = 2;
672 public const int KFM_DATA = 2;
673 public const int KFM_TRANSLATION = 2;
674 public const int KFM_ROTATION = 1;
675 public const int KFM_COMMAND = 0;
676 public const int KFM_CMD_PLAY = 0;
677 public const int KFM_CMD_STOP = 1;
678 public const int KFM_CMD_PAUSE = 2;
653 } 679 }
654} 680}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index f8e3c36..bf58d13 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;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -464,6 +471,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 471 return m_LSL_Functions.llGetFreeMemory();
465 } 472 }
466 473
474 public LSL_Integer llGetUsedMemory()
475 {
476 return m_LSL_Functions.llGetUsedMemory();
477 }
478
467 public LSL_Integer llGetFreeURLs() 479 public LSL_Integer llGetFreeURLs()
468 { 480 {
469 return m_LSL_Functions.llGetFreeURLs(); 481 return m_LSL_Functions.llGetFreeURLs();
@@ -849,6 +861,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
849 return m_LSL_Functions.llGiveMoney(destination, amount); 861 return m_LSL_Functions.llGiveMoney(destination, amount);
850 } 862 }
851 863
864 public LSL_String llTransferLindenDollars(string destination, int amount)
865 {
866 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
867 }
868
852 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 869 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
853 { 870 {
854 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 871 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1563,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1563 m_LSL_Functions.llSetPos(pos); 1580 m_LSL_Functions.llSetPos(pos);
1564 } 1581 }
1565 1582
1583 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1584 {
1585 return m_LSL_Functions.llSetRegionPos(pos);
1586 }
1587
1566 public void llSetPrimitiveParams(LSL_List rules) 1588 public void llSetPrimitiveParams(LSL_List rules)
1567 { 1589 {
1568 m_LSL_Functions.llSetPrimitiveParams(rules); 1590 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1798,6 +1820,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1798 m_LSL_Functions.llTargetRemove(number); 1820 m_LSL_Functions.llTargetRemove(number);
1799 } 1821 }
1800 1822
1823 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1824 {
1825 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1826 }
1827
1801 public void llTeleportAgentHome(string agent) 1828 public void llTeleportAgentHome(string agent)
1802 { 1829 {
1803 m_LSL_Functions.llTeleportAgentHome(agent); 1830 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1913,9 +1940,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1913 return m_LSL_Functions.llClearLinkMedia(link, face); 1940 return m_LSL_Functions.llClearLinkMedia(link, face);
1914 } 1941 }
1915 1942
1916 public void print(string str) 1943 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1944 {
1945 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1946 }
1947
1948 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1949 {
1950 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1951 }
1952
1953 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1917 { 1954 {
1918 m_LSL_Functions.print(str); 1955 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1919 } 1956 }
1920 } 1957 }
1921} 1958}
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..7e7e278 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,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6e36742..ff1f277 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;
@@ -218,13 +219,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
218 219
219 if (part != null) 220 if (part != null)
220 { 221 {
221 lock (part.TaskInventory) 222 part.TaskInventory.LockItemsForRead(true);
223 if (part.TaskInventory.ContainsKey(ItemID))
222 { 224 {
223 if (part.TaskInventory.ContainsKey(ItemID)) 225 ScriptTask = part.TaskInventory[ItemID];
224 {
225 ScriptTask = part.TaskInventory[ItemID];
226 }
227 } 226 }
227 part.TaskInventory.LockItemsForRead(false);
228 } 228 }
229 229
230 ApiManager am = new ApiManager(); 230 ApiManager am = new ApiManager();
@@ -416,14 +416,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
416 { 416 {
417 int permsMask; 417 int permsMask;
418 UUID permsGranter; 418 UUID permsGranter;
419 lock (part.TaskInventory) 419 part.TaskInventory.LockItemsForRead(true);
420 if (!part.TaskInventory.ContainsKey(ItemID))
420 { 421 {
421 if (!part.TaskInventory.ContainsKey(ItemID)) 422 part.TaskInventory.LockItemsForRead(false);
422 return; 423 return;
423
424 permsGranter = part.TaskInventory[ItemID].PermsGranter;
425 permsMask = part.TaskInventory[ItemID].PermsMask;
426 } 424 }
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 part.TaskInventory.LockItemsForRead(false);
427 428
428 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
429 { 430 {
@@ -551,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
551 return true; 552 return true;
552 } 553 }
553 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
554 public void SetState(string state) 556 public void SetState(string state)
555 { 557 {
556 if (state == State) 558 if (state == State)
@@ -562,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
562 new DetectParams[0])); 564 new DetectParams[0]));
563 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
564 new DetectParams[0])); 566 new DetectParams[0]));
565 567
566 throw new EventAbortException(); 568 throw new EventAbortException();
567 } 569 }
568 570
@@ -652,45 +654,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
652 /// <returns></returns> 654 /// <returns></returns>
653 public object EventProcessor() 655 public object EventProcessor()
654 { 656 {
657 EventParams data = null;
655 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 658 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
656 if (!Running) 659 if (!Running)
657 return 0; 660 return 0;
658 661
659 lock (m_Script)
660 {
661// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
662 663
663 if (Suspended) 664 if (Suspended)
664 return 0; 665 return 0;
665
666 EventParams data = null;
667 666
668 lock (EventQueue) 667 lock (EventQueue)
668 {
669 data = (EventParams) EventQueue.Dequeue();
670 if (data == null) // Shouldn't happen
669 { 671 {
670 data = (EventParams)EventQueue.Dequeue(); 672 if (EventQueue.Count > 0 && Running && !ShuttingDown)
671 if (data == null) // Shouldn't happen
672 { 673 {
673 if (EventQueue.Count > 0 && Running && !ShuttingDown) 674 m_CurrentWorkItem = Engine.QueueEventHandler(this);
674 {
675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
676 }
677 else
678 {
679 m_CurrentWorkItem = null;
680 }
681 return 0;
682 } 675 }
683 676 else
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 { 677 {
688 if (m_ControlEventsInQueue > 0) 678 m_CurrentWorkItem = null;
689 m_ControlEventsInQueue--;
690 } 679 }
691 if (data.EventName == "collision") 680 return 0;
692 m_CollisionInQueue = false;
693 } 681 }
682
683 if (data.EventName == "timer")
684 m_TimerQueued = false;
685 if (data.EventName == "control")
686 {
687 if (m_ControlEventsInQueue > 0)
688 m_ControlEventsInQueue--;
689 }
690 if (data.EventName == "collision")
691 m_CollisionInQueue = false;
692 }
693
694 lock(m_Script)
695 {
694 696
695// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 697// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
696 698
@@ -859,6 +861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
859 new Object[0], new DetectParams[0])); 861 new Object[0], new DetectParams[0]));
860 } 862 }
861 863
864 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
862 public void ApiResetScript() 865 public void ApiResetScript()
863 { 866 {
864 // bool running = Running; 867 // bool running = Running;
@@ -890,10 +893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
890 893
891 public Dictionary<string, object> GetVars() 894 public Dictionary<string, object> GetVars()
892 { 895 {
893 if (m_Script != null) 896 return m_Script.GetVars();
894 return m_Script.GetVars();
895 else
896 return new Dictionary<string, object>();
897 } 897 }
898 898
899 public void SetVars(Dictionary<string, object> vars) 899 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 {