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.cs2759
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs74
-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.cs4
-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.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs21
-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.cs92
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
18 files changed, 2322 insertions, 994 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 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 fb930e0..ac22638 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;
554
555 int numPis = (int)(Math.PI / angle);
556 double remainder = angle - Math.PI * numPis;
557 if (numPis % 2 == 1)
558 return Math.PI - angle;
559 return remainder;
560 }
478 561
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. 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 563 {
481 if (m == 0.0) return new LSL_Vector(); 564 m_host.AddScriptLPS(1);
482 double x = Math.Atan2(-v.y, v.z); 565 LSL_Vector eul = new LSL_Vector();
483 double sin = v.x / m;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
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 566
490 return new LSL_Vector(x, y, z); 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;
@@ -1406,6 +1518,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1518 {
1407 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1408 1520
1521 SetColor(m_host, color, face);
1522 }
1523
1524 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1525 {
1526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1527 return;
1528
1529 Primitive.TextureEntry tex = part.Shape.Textures;
1530 Color4 texcolor;
1531 if (face >= 0 && face < GetNumberOfSides(part))
1532 {
1533 texcolor = tex.CreateFace((uint)face).RGBA;
1534 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1535 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1536 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1537 tex.FaceTextures[face].RGBA = texcolor;
1538 part.UpdateTextureEntry(tex.GetBytes());
1539 return;
1540 }
1541 else if (face == ScriptBaseClass.ALL_SIDES)
1542 {
1543 for (uint i = 0; i < GetNumberOfSides(part); i++)
1544 {
1545 if (tex.FaceTextures[i] != null)
1546 {
1547 texcolor = tex.FaceTextures[i].RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[i].RGBA = texcolor;
1552 }
1553 texcolor = tex.DefaultTexture.RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.DefaultTexture.RGBA = texcolor;
1558 }
1559 part.UpdateTextureEntry(tex.GetBytes());
1560 return;
1561 }
1562
1409 if (face == ScriptBaseClass.ALL_SIDES) 1563 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1564 face = SceneObjectPart.ALL_SIDES;
1411 1565
@@ -1414,6 +1568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1568
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1569 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1570 {
1571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1572 return;
1573
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1574 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1575 MappingType textype;
1419 textype = MappingType.Default; 1576 textype = MappingType.Default;
@@ -1444,6 +1601,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1601
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1602 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1607 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1608 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1609 {
@@ -1469,6 +1629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1629
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1630 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1631 {
1632 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1633 return;
1472 1634
1473 Shininess sval = new Shininess(); 1635 Shininess sval = new Shininess();
1474 1636
@@ -1519,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1681
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1682 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1689 {
@@ -1579,13 +1744,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1744 m_host.AddScriptLPS(1);
1580 1745
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1746 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1747 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1748 {
1584 SetAlpha(part, alpha, face); 1749 try
1750 {
1751 parts[0].ParentGroup.areUpdatesSuspended = true;
1752 foreach (SceneObjectPart part in parts)
1753 SetAlpha(part, alpha, face);
1754 }
1755 finally
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = false;
1758 }
1759 }
1585 } 1760 }
1586 1761
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1762 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1768 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1816 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1817 float wind, float tension, LSL_Vector Force)
1640 { 1818 {
1641 if (part == null) 1819 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1820 return;
1643 1821
1644 if (flexi) 1822 if (flexi)
@@ -1672,7 +1850,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1672 /// <param name="falloff"></param> 1850 /// <param name="falloff"></param>
1673 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1851 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1674 { 1852 {
1675 if (part == null) 1853 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1676 return; 1854 return;
1677 1855
1678 if (light) 1856 if (light)
@@ -1749,15 +1927,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 m_host.AddScriptLPS(1); 1927 m_host.AddScriptLPS(1);
1750 1928
1751 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1752 1930 if (parts.Count > 0)
1753 foreach (SceneObjectPart part in parts) 1931 {
1754 SetTexture(part, texture, face); 1932 try
1755 1933 {
1934 parts[0].ParentGroup.areUpdatesSuspended = true;
1935 foreach (SceneObjectPart part in parts)
1936 SetTexture(part, texture, face);
1937 }
1938 finally
1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = false;
1941 }
1942 }
1756 ScriptSleep(200); 1943 ScriptSleep(200);
1757 } 1944 }
1758 1945
1759 protected void SetTexture(SceneObjectPart part, string texture, int face) 1946 protected void SetTexture(SceneObjectPart part, string texture, int face)
1760 { 1947 {
1948 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1949 return;
1950
1761 UUID textureID = new UUID(); 1951 UUID textureID = new UUID();
1762 1952
1763 textureID = InventoryKey(texture, (int)AssetType.Texture); 1953 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1802,6 +1992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 1992
1803 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1993 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1804 { 1994 {
1995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1996 return;
1997
1805 Primitive.TextureEntry tex = part.Shape.Textures; 1998 Primitive.TextureEntry tex = part.Shape.Textures;
1806 if (face >= 0 && face < GetNumberOfSides(part)) 1999 if (face >= 0 && face < GetNumberOfSides(part))
1807 { 2000 {
@@ -1838,6 +2031,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 2031
1839 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2032 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1840 { 2033 {
2034 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2035 return;
2036
1841 Primitive.TextureEntry tex = part.Shape.Textures; 2037 Primitive.TextureEntry tex = part.Shape.Textures;
1842 if (face >= 0 && face < GetNumberOfSides(part)) 2038 if (face >= 0 && face < GetNumberOfSides(part))
1843 { 2039 {
@@ -1874,6 +2070,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 2070
1875 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2071 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1876 { 2072 {
2073 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2074 return;
2075
1877 Primitive.TextureEntry tex = part.Shape.Textures; 2076 Primitive.TextureEntry tex = part.Shape.Textures;
1878 if (face >= 0 && face < GetNumberOfSides(part)) 2077 if (face >= 0 && face < GetNumberOfSides(part))
1879 { 2078 {
@@ -1980,24 +2179,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 2179
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2180 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2181 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2182 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2183 return;
1985 2184
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2185 LSL_Vector currentPos = GetPartLocalPos(part);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2186 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1988 2187
1989 if (part.ParentGroup.RootPart == part) 2188 if (part.ParentGroup.RootPart == part)
1990 { 2189 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2190 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2191 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1996 } 2192 }
1997 else 2193 else
1998 { 2194 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2195 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2001 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2197 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2198 parent.ScheduleGroupForTerseUpdate();
@@ -2048,9 +2243,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2243 m_host.AddScriptLPS(1);
2049 2244
2050 // try to let this work as in SL... 2245 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2246 if (m_host.LinkNum < 2)
2052 { 2247 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2248 // Special case: If we are root, rotate complete SOG to new
2249 // rotation.
2250 // We are root if the link number is 0 (single prim) or 1
2251 // (root prim). ParentID may be nonzero in attachments and
2252 // using it would cause attachments and HUDs to rotate
2253 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2254 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2255 }
2056 else 2256 else
@@ -2075,6 +2275,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2275
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2276 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2277 {
2278 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2279 return;
2280
2078 part.UpdateRotation(rot); 2281 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2282 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2283
@@ -2698,12 +2901,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2901
2699 m_host.AddScriptLPS(1); 2902 m_host.AddScriptLPS(1);
2700 2903
2904 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2905 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2906 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2907
2708 if (item.PermsGranter == UUID.Zero) 2908 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2909 return 0;
@@ -2778,6 +2978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2978 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2979 return;
2780 2980
2981 //Clone is thread-safe
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2982 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2983
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2984 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2857,7 +3058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2857 // the angles of rotation in radians into rotation value 3058 // the angles of rotation in radians into rotation value
2858 3059
2859 LSL_Rotation rot = llEuler2Rot(angle); 3060 LSL_Rotation rot = llEuler2Rot(angle);
2860 3061
2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3062 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // set the rotation of the object, copy that behavior 3063 // set the rotation of the object, copy that behavior
2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) 3064 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
@@ -2916,13 +3117,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3117 {
2917 TaskInventoryItem item; 3118 TaskInventoryItem item;
2918 3119
2919 lock (m_host.TaskInventory) 3120 m_host.TaskInventory.LockItemsForRead(true);
3121 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2920 { 3122 {
2921 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3123 m_host.TaskInventory.LockItemsForRead(false);
2922 return; 3124 return;
2923 else
2924 item = m_host.TaskInventory[InventorySelf()];
2925 } 3125 }
3126 else
3127 {
3128 item = m_host.TaskInventory[InventorySelf()];
3129 }
3130 m_host.TaskInventory.LockItemsForRead(false);
2926 3131
2927 if (item.PermsGranter != UUID.Zero) 3132 if (item.PermsGranter != UUID.Zero)
2928 { 3133 {
@@ -2944,13 +3149,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 { 3149 {
2945 TaskInventoryItem item; 3150 TaskInventoryItem item;
2946 3151
3152 m_host.TaskInventory.LockItemsForRead(true);
2947 lock (m_host.TaskInventory) 3153 lock (m_host.TaskInventory)
2948 { 3154 {
3155
2949 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3156 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3157 {
3158 m_host.TaskInventory.LockItemsForRead(false);
2950 return; 3159 return;
3160 }
2951 else 3161 else
3162 {
2952 item = m_host.TaskInventory[InventorySelf()]; 3163 item = m_host.TaskInventory[InventorySelf()];
3164 }
2953 } 3165 }
3166 m_host.TaskInventory.LockItemsForRead(false);
2954 3167
2955 m_host.AddScriptLPS(1); 3168 m_host.AddScriptLPS(1);
2956 3169
@@ -2982,18 +3195,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2982 { 3195 {
2983 m_host.AddScriptLPS(1); 3196 m_host.AddScriptLPS(1);
2984 3197
2985// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2986// return;
2987
2988 TaskInventoryItem item; 3198 TaskInventoryItem item;
2989 3199
2990 lock (m_host.TaskInventory) 3200 m_host.TaskInventory.LockItemsForRead(true);
3201
3202 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2991 { 3203 {
2992 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3204 m_host.TaskInventory.LockItemsForRead(false);
2993 return; 3205 return;
2994 else
2995 item = m_host.TaskInventory[InventorySelf()];
2996 } 3206 }
3207 else
3208 {
3209 item = m_host.TaskInventory[InventorySelf()];
3210 }
3211
3212 m_host.TaskInventory.LockItemsForRead(false);
2997 3213
2998 if (item.PermsGranter != m_host.OwnerID) 3214 if (item.PermsGranter != m_host.OwnerID)
2999 return; 3215 return;
@@ -3019,13 +3235,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 3235
3020 TaskInventoryItem item; 3236 TaskInventoryItem item;
3021 3237
3022 lock (m_host.TaskInventory) 3238 m_host.TaskInventory.LockItemsForRead(true);
3239
3240 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3023 { 3241 {
3024 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3242 m_host.TaskInventory.LockItemsForRead(false);
3025 return; 3243 return;
3026 else
3027 item = m_host.TaskInventory[InventorySelf()];
3028 } 3244 }
3245 else
3246 {
3247 item = m_host.TaskInventory[InventorySelf()];
3248 }
3249 m_host.TaskInventory.LockItemsForRead(false);
3250
3029 3251
3030 if (item.PermsGranter != m_host.OwnerID) 3252 if (item.PermsGranter != m_host.OwnerID)
3031 return; 3253 return;
@@ -3072,6 +3294,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 3294
3073 public void llInstantMessage(string user, string message) 3295 public void llInstantMessage(string user, string message)
3074 { 3296 {
3297 UUID result;
3298 if (!UUID.TryParse(user, out result))
3299 {
3300 ShoutError("An invalid key was passed to llInstantMessage");
3301 ScriptSleep(2000);
3302 return;
3303 }
3304
3305
3075 m_host.AddScriptLPS(1); 3306 m_host.AddScriptLPS(1);
3076 3307
3077 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3308 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3086,14 +3317,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3086 UUID friendTransactionID = UUID.Random(); 3317 UUID friendTransactionID = UUID.Random();
3087 3318
3088 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3319 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3089 3320
3090 GridInstantMessage msg = new GridInstantMessage(); 3321 GridInstantMessage msg = new GridInstantMessage();
3091 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3322 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3092 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3323 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3093 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3324 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3094// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3325// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3095// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3326// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3096 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3327// DateTime dt = DateTime.UtcNow;
3328//
3329// // Ticks from UtcNow, but make it look like local. Evil, huh?
3330// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3331//
3332// try
3333// {
3334// // Convert that to the PST timezone
3335// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3336// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3337// }
3338// catch
3339// {
3340// // No logging here, as it could be VERY spammy
3341// }
3342//
3343// // And make it look local again to fool the unix time util
3344// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3345
3346 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3347
3097 //if (client != null) 3348 //if (client != null)
3098 //{ 3349 //{
3099 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3350 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3107,12 +3358,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3107 msg.message = message.Substring(0, 1024); 3358 msg.message = message.Substring(0, 1024);
3108 else 3359 else
3109 msg.message = message; 3360 msg.message = message;
3110 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3361 msg.dialog = (byte)19; // MessageFromObject
3111 msg.fromGroup = false;// fromGroup; 3362 msg.fromGroup = false;// fromGroup;
3112 msg.offline = (byte)0; //offline; 3363 msg.offline = (byte)0; //offline;
3113 msg.ParentEstateID = 0; //ParentEstateID; 3364 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3114 msg.Position = new Vector3(m_host.AbsolutePosition); 3365 msg.Position = new Vector3(m_host.AbsolutePosition);
3115 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3366 msg.RegionID = World.RegionInfo.RegionID.Guid;
3116 msg.binaryBucket 3367 msg.binaryBucket
3117 = Util.StringToBytes256( 3368 = Util.StringToBytes256(
3118 "{0}/{1}/{2}/{3}", 3369 "{0}/{1}/{2}/{3}",
@@ -3140,7 +3391,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3140 } 3391 }
3141 3392
3142 emailModule.SendEmail(m_host.UUID, address, subject, message); 3393 emailModule.SendEmail(m_host.UUID, address, subject, message);
3143 ScriptSleep(20000); 3394 ScriptSleep(15000);
3144 } 3395 }
3145 3396
3146 public void llGetNextEmail(string address, string subject) 3397 public void llGetNextEmail(string address, string subject)
@@ -3279,14 +3530,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3279 3530
3280 TaskInventoryItem item; 3531 TaskInventoryItem item;
3281 3532
3282 lock (m_host.TaskInventory) 3533 m_host.TaskInventory.LockItemsForRead(true);
3534 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3283 { 3535 {
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3536 m_host.TaskInventory.LockItemsForRead(false);
3285 return; 3537 return;
3286 else
3287 item = m_host.TaskInventory[InventorySelf()];
3288 } 3538 }
3289 3539 else
3540 {
3541 item = m_host.TaskInventory[InventorySelf()];
3542 }
3543 m_host.TaskInventory.LockItemsForRead(false);
3290 if (item.PermsGranter == UUID.Zero) 3544 if (item.PermsGranter == UUID.Zero)
3291 return; 3545 return;
3292 3546
@@ -3316,13 +3570,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3316 3570
3317 TaskInventoryItem item; 3571 TaskInventoryItem item;
3318 3572
3319 lock (m_host.TaskInventory) 3573 m_host.TaskInventory.LockItemsForRead(true);
3574 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3320 { 3575 {
3321 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3576 m_host.TaskInventory.LockItemsForRead(false);
3322 return; 3577 return;
3323 else
3324 item = m_host.TaskInventory[InventorySelf()];
3325 } 3578 }
3579 else
3580 {
3581 item = m_host.TaskInventory[InventorySelf()];
3582 }
3583 m_host.TaskInventory.LockItemsForRead(false);
3584
3326 3585
3327 if (item.PermsGranter == UUID.Zero) 3586 if (item.PermsGranter == UUID.Zero)
3328 return; 3587 return;
@@ -3389,10 +3648,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3648
3390 TaskInventoryItem item; 3649 TaskInventoryItem item;
3391 3650
3392 lock (m_host.TaskInventory) 3651
3652 m_host.TaskInventory.LockItemsForRead(true);
3653 if (!m_host.TaskInventory.ContainsKey(invItemID))
3654 {
3655 m_host.TaskInventory.LockItemsForRead(false);
3656 return;
3657 }
3658 else
3393 { 3659 {
3394 item = m_host.TaskInventory[invItemID]; 3660 item = m_host.TaskInventory[invItemID];
3395 } 3661 }
3662 m_host.TaskInventory.LockItemsForRead(false);
3396 3663
3397 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3664 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3398 { 3665 {
@@ -3420,15 +3687,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3687 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3421 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3688 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3422 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3689 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3690 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3423 ScriptBaseClass.PERMISSION_ATTACH; 3691 ScriptBaseClass.PERMISSION_ATTACH;
3424 3692
3425 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3693 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3426 { 3694 {
3427 lock (m_host.TaskInventory) 3695 m_host.TaskInventory.LockItemsForWrite(true);
3428 { 3696 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3429 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3697 m_host.TaskInventory[invItemID].PermsMask = perm;
3430 m_host.TaskInventory[invItemID].PermsMask = perm; 3698 m_host.TaskInventory.LockItemsForWrite(false);
3431 }
3432 3699
3433 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3700 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3434 "run_time_permissions", new Object[] { 3701 "run_time_permissions", new Object[] {
@@ -3438,28 +3705,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 return; 3705 return;
3439 } 3706 }
3440 } 3707 }
3441 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3708 else
3442 { 3709 {
3443 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3710 bool sitting = false;
3444 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3711 if (m_host.SitTargetAvatar == agentID)
3445 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3712 {
3446 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3713 sitting = true;
3447 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3714 }
3715 else
3716 {
3717 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3718 {
3719 if (p.SitTargetAvatar == agentID)
3720 sitting = true;
3721 }
3722 }
3448 3723
3449 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3724 if (sitting)
3450 { 3725 {
3451 lock (m_host.TaskInventory) 3726 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3727 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3728 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3729 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3730 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3731
3732 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3733 {
3734 m_host.TaskInventory.LockItemsForWrite(true);
3453 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3735 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3454 m_host.TaskInventory[invItemID].PermsMask = perm; 3736 m_host.TaskInventory[invItemID].PermsMask = perm;
3455 } 3737 m_host.TaskInventory.LockItemsForWrite(false);
3456 3738
3457 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3739 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3458 "run_time_permissions", new Object[] { 3740 "run_time_permissions", new Object[] {
3459 new LSL_Integer(perm) }, 3741 new LSL_Integer(perm) },
3460 new DetectParams[0])); 3742 new DetectParams[0]));
3461 3743
3462 return; 3744 return;
3745 }
3463 } 3746 }
3464 } 3747 }
3465 3748
@@ -3473,11 +3756,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 3756
3474 if (!m_waitingForScriptAnswer) 3757 if (!m_waitingForScriptAnswer)
3475 { 3758 {
3476 lock (m_host.TaskInventory) 3759 m_host.TaskInventory.LockItemsForWrite(true);
3477 { 3760 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3478 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3761 m_host.TaskInventory[invItemID].PermsMask = 0;
3479 m_host.TaskInventory[invItemID].PermsMask = 0; 3762 m_host.TaskInventory.LockItemsForWrite(false);
3480 }
3481 3763
3482 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3764 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3483 m_waitingForScriptAnswer=true; 3765 m_waitingForScriptAnswer=true;
@@ -3512,10 +3794,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3794 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3795 llReleaseControls();
3514 3796
3515 lock (m_host.TaskInventory) 3797
3516 { 3798 m_host.TaskInventory.LockItemsForWrite(true);
3517 m_host.TaskInventory[invItemID].PermsMask = answer; 3799 m_host.TaskInventory[invItemID].PermsMask = answer;
3518 } 3800 m_host.TaskInventory.LockItemsForWrite(false);
3801
3519 3802
3520 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3803 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3521 "run_time_permissions", new Object[] { 3804 "run_time_permissions", new Object[] {
@@ -3527,16 +3810,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 { 3810 {
3528 m_host.AddScriptLPS(1); 3811 m_host.AddScriptLPS(1);
3529 3812
3530 lock (m_host.TaskInventory) 3813 m_host.TaskInventory.LockItemsForRead(true);
3814
3815 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3531 { 3816 {
3532 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3817 if (item.Type == 10 && item.ItemID == m_itemID)
3533 { 3818 {
3534 if (item.Type == 10 && item.ItemID == m_itemID) 3819 m_host.TaskInventory.LockItemsForRead(false);
3535 { 3820 return item.PermsGranter.ToString();
3536 return item.PermsGranter.ToString();
3537 }
3538 } 3821 }
3539 } 3822 }
3823 m_host.TaskInventory.LockItemsForRead(false);
3540 3824
3541 return UUID.Zero.ToString(); 3825 return UUID.Zero.ToString();
3542 } 3826 }
@@ -3545,19 +3829,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 { 3829 {
3546 m_host.AddScriptLPS(1); 3830 m_host.AddScriptLPS(1);
3547 3831
3548 lock (m_host.TaskInventory) 3832 m_host.TaskInventory.LockItemsForRead(true);
3833
3834 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3549 { 3835 {
3550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3836 if (item.Type == 10 && item.ItemID == m_itemID)
3551 { 3837 {
3552 if (item.Type == 10 && item.ItemID == m_itemID) 3838 int perms = item.PermsMask;
3553 { 3839 if (m_automaticLinkPermission)
3554 int perms = item.PermsMask; 3840 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3555 if (m_automaticLinkPermission) 3841 m_host.TaskInventory.LockItemsForRead(false);
3556 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3842 return perms;
3557 return perms;
3558 }
3559 } 3843 }
3560 } 3844 }
3845 m_host.TaskInventory.LockItemsForRead(false);
3561 3846
3562 return 0; 3847 return 0;
3563 } 3848 }
@@ -3579,9 +3864,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3864 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3865 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3866 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3867 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3868 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3869 try
3870 {
3871 parts[0].ParentGroup.areUpdatesSuspended = true;
3872 foreach (SceneObjectPart part in parts)
3873 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3874 }
3875 finally
3876 {
3877 parts[0].ParentGroup.areUpdatesSuspended = false;
3878 }
3879 }
3585 } 3880 }
3586 3881
3587 public void llCreateLink(string target, int parent) 3882 public void llCreateLink(string target, int parent)
@@ -3594,11 +3889,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 return; 3889 return;
3595 3890
3596 TaskInventoryItem item; 3891 TaskInventoryItem item;
3597 lock (m_host.TaskInventory) 3892 m_host.TaskInventory.LockItemsForRead(true);
3598 { 3893 item = m_host.TaskInventory[invItemID];
3599 item = m_host.TaskInventory[invItemID]; 3894 m_host.TaskInventory.LockItemsForRead(false);
3600 } 3895
3601
3602 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3896 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3603 && !m_automaticLinkPermission) 3897 && !m_automaticLinkPermission)
3604 { 3898 {
@@ -3615,11 +3909,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3615 3909
3616 if (targetPart.ParentGroup.AttachmentPoint != 0) 3910 if (targetPart.ParentGroup.AttachmentPoint != 0)
3617 return; // Fail silently if attached 3911 return; // Fail silently if attached
3912
3913 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3914 return;
3915
3618 SceneObjectGroup parentPrim = null, childPrim = null; 3916 SceneObjectGroup parentPrim = null, childPrim = null;
3619 3917
3620 if (targetPart != null) 3918 if (targetPart != null)
3621 { 3919 {
3622 if (parent != 0) { 3920 if (parent != 0)
3921 {
3623 parentPrim = m_host.ParentGroup; 3922 parentPrim = m_host.ParentGroup;
3624 childPrim = targetPart.ParentGroup; 3923 childPrim = targetPart.ParentGroup;
3625 } 3924 }
@@ -3650,16 +3949,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3650 m_host.AddScriptLPS(1); 3949 m_host.AddScriptLPS(1);
3651 UUID invItemID = InventorySelf(); 3950 UUID invItemID = InventorySelf();
3652 3951
3653 lock (m_host.TaskInventory) 3952 m_host.TaskInventory.LockItemsForRead(true);
3654 {
3655 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3953 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3656 && !m_automaticLinkPermission) 3954 && !m_automaticLinkPermission)
3657 { 3955 {
3658 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3956 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3957 m_host.TaskInventory.LockItemsForRead(false);
3659 return; 3958 return;
3660 } 3959 }
3661 } 3960 m_host.TaskInventory.LockItemsForRead(false);
3662 3961
3663 if (linknum < ScriptBaseClass.LINK_THIS) 3962 if (linknum < ScriptBaseClass.LINK_THIS)
3664 return; 3963 return;
3665 3964
@@ -3698,10 +3997,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 3997 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3998 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 3999 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4000 if (parts.Count > 0)
3702 { 4001 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4002 try
4003 {
4004 parts[0].ParentGroup.areUpdatesSuspended = true;
4005 foreach (SceneObjectPart part in parts)
4006 {
4007 parentPrim.DelinkFromGroup(part.LocalId, true);
4008 }
4009 }
4010 finally
4011 {
4012 parts[0].ParentGroup.areUpdatesSuspended = false;
4013 }
3704 } 4014 }
4015
3705 parentPrim.HasGroupChanged = true; 4016 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4017 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4018 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4021,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4021 {
3711 SceneObjectPart newRoot = parts[0]; 4022 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4023 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4024
4025 try
3714 { 4026 {
3715 // Required for linking 4027 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4028 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4029 {
4030 part.ClearUpdateSchedule();
4031 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4032 }
3718 } 4033 }
4034 finally
4035 {
4036 parts[0].ParentGroup.areUpdatesSuspended = false;
4037 }
4038
4039
3719 newRoot.ParentGroup.HasGroupChanged = true; 4040 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4041 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4042 }
@@ -3735,6 +4056,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4056 public void llBreakAllLinks()
3736 { 4057 {
3737 m_host.AddScriptLPS(1); 4058 m_host.AddScriptLPS(1);
4059
4060 UUID invItemID = InventorySelf();
4061
4062 TaskInventoryItem item;
4063 m_host.TaskInventory.LockItemsForRead(true);
4064 item = m_host.TaskInventory[invItemID];
4065 m_host.TaskInventory.LockItemsForRead(false);
4066
4067 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4068 && !m_automaticLinkPermission)
4069 {
4070 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4071 return;
4072 }
4073
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4074 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4075 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4076 return; // Fail silently if attached
@@ -3754,25 +4090,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4090 public LSL_String llGetLinkKey(int linknum)
3755 { 4091 {
3756 m_host.AddScriptLPS(1); 4092 m_host.AddScriptLPS(1);
3757 List<UUID> keytable = new List<UUID>();
3758 // parse for sitting avatare-uuids
3759 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3760 {
3761 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
3762 keytable.Add(presence.UUID);
3763 });
3764
3765 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3766 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3767 {
3768 return keytable[totalprims - linknum].ToString();
3769 }
3770
3771 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3772 {
3773 return m_host.UUID.ToString();
3774 }
3775
3776 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4093 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4094 if (part != null)
3778 { 4095 {
@@ -3780,6 +4097,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4097 }
3781 else 4098 else
3782 { 4099 {
4100 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4101 {
4102 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4103
4104 if (linknum < 0)
4105 return UUID.Zero.ToString();
4106
4107 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4108 if (avatars.Count > linknum)
4109 {
4110 return avatars[linknum].UUID.ToString();
4111 }
4112 }
3783 return UUID.Zero.ToString(); 4113 return UUID.Zero.ToString();
3784 } 4114 }
3785 } 4115 }
@@ -3878,17 +4208,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 m_host.AddScriptLPS(1); 4208 m_host.AddScriptLPS(1);
3879 int count = 0; 4209 int count = 0;
3880 4210
3881 lock (m_host.TaskInventory) 4211 m_host.TaskInventory.LockItemsForRead(true);
4212 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3882 { 4213 {
3883 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4214 if (inv.Value.Type == type || type == -1)
3884 { 4215 {
3885 if (inv.Value.Type == type || type == -1) 4216 count = count + 1;
3886 {
3887 count = count + 1;
3888 }
3889 } 4217 }
3890 } 4218 }
3891 4219
4220 m_host.TaskInventory.LockItemsForRead(false);
3892 return count; 4221 return count;
3893 } 4222 }
3894 4223
@@ -3897,16 +4226,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 m_host.AddScriptLPS(1); 4226 m_host.AddScriptLPS(1);
3898 ArrayList keys = new ArrayList(); 4227 ArrayList keys = new ArrayList();
3899 4228
3900 lock (m_host.TaskInventory) 4229 m_host.TaskInventory.LockItemsForRead(true);
4230 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4231 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4232 if (inv.Value.Type == type || type == -1)
3903 { 4233 {
3904 if (inv.Value.Type == type || type == -1) 4234 keys.Add(inv.Value.Name);
3905 {
3906 keys.Add(inv.Value.Name);
3907 }
3908 } 4235 }
3909 } 4236 }
4237 m_host.TaskInventory.LockItemsForRead(false);
3910 4238
3911 if (keys.Count == 0) 4239 if (keys.Count == 0)
3912 { 4240 {
@@ -3943,25 +4271,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 } 4271 }
3944 4272
3945 // move the first object found with this inventory name 4273 // move the first object found with this inventory name
3946 lock (m_host.TaskInventory) 4274 m_host.TaskInventory.LockItemsForRead(true);
4275 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3947 { 4276 {
3948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4277 if (inv.Value.Name == inventory)
3949 { 4278 {
3950 if (inv.Value.Name == inventory) 4279 found = true;
3951 { 4280 objId = inv.Key;
3952 found = true; 4281 assetType = inv.Value.Type;
3953 objId = inv.Key; 4282 objName = inv.Value.Name;
3954 assetType = inv.Value.Type; 4283 break;
3955 objName = inv.Value.Name;
3956 break;
3957 }
3958 } 4284 }
3959 } 4285 }
4286 m_host.TaskInventory.LockItemsForRead(false);
3960 4287
3961 if (!found) 4288 if (!found)
3962 { 4289 {
3963 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4290 llSay(0, String.Format("Could not find object '{0}'", inventory));
3964 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4291 return;
4292// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3965 } 4293 }
3966 4294
3967 // check if destination is an object 4295 // check if destination is an object
@@ -3987,48 +4315,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 return; 4315 return;
3988 } 4316 }
3989 } 4317 }
4318
3990 // destination is an avatar 4319 // destination is an avatar
3991 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4320 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3992 4321
3993 if (agentItem == null) 4322 if (agentItem == null)
3994 return; 4323 return;
3995 4324
3996 byte[] bucket = new byte[17]; 4325 byte[] bucket = new byte[1];
3997 bucket[0] = (byte)assetType; 4326 bucket[0] = (byte)assetType;
3998 byte[] objBytes = agentItem.ID.GetBytes(); 4327 //byte[] objBytes = agentItem.ID.GetBytes();
3999 Array.Copy(objBytes, 0, bucket, 1, 16); 4328 //Array.Copy(objBytes, 0, bucket, 1, 16);
4000 4329
4001 GridInstantMessage msg = new GridInstantMessage(World, 4330 GridInstantMessage msg = new GridInstantMessage(World,
4002 m_host.UUID, m_host.Name+", an object owned by "+ 4331 m_host.OwnerID, m_host.Name, destId,
4003 resolveName(m_host.OwnerID)+",", destId,
4004 (byte)InstantMessageDialog.TaskInventoryOffered, 4332 (byte)InstantMessageDialog.TaskInventoryOffered,
4005 false, objName+"\n"+m_host.Name+" is located at "+ 4333 false, objName+". "+m_host.Name+" is located at "+
4006 World.RegionInfo.RegionName+" "+ 4334 World.RegionInfo.RegionName+" "+
4007 m_host.AbsolutePosition.ToString(), 4335 m_host.AbsolutePosition.ToString(),
4008 agentItem.ID, true, m_host.AbsolutePosition, 4336 agentItem.ID, true, m_host.AbsolutePosition,
4009 bucket); 4337 bucket);
4010 if (m_TransferModule != null) 4338
4011 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4339 ScenePresence sp;
4340
4341 if (World.TryGetScenePresence(destId, out sp))
4342 {
4343 sp.ControllingClient.SendInstantMessage(msg);
4344 }
4345 else
4346 {
4347 if (m_TransferModule != null)
4348 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4349 }
4350
4351 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4352 ScriptSleep(3000);
4013 } 4353 }
4014 } 4354 }
4015 4355
4356 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4357 public void llRemoveInventory(string name)
4017 { 4358 {
4018 m_host.AddScriptLPS(1); 4359 m_host.AddScriptLPS(1);
4019 4360
4020 lock (m_host.TaskInventory) 4361 List<TaskInventoryItem> inv;
4362 try
4021 { 4363 {
4022 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4364 m_host.TaskInventory.LockItemsForRead(true);
4365 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4366 }
4367 finally
4368 {
4369 m_host.TaskInventory.LockItemsForRead(false);
4370 }
4371 foreach (TaskInventoryItem item in inv)
4372 {
4373 if (item.Name == name)
4023 { 4374 {
4024 if (item.Name == name) 4375 if (item.ItemID == m_itemID)
4025 { 4376 throw new ScriptDeleteException();
4026 if (item.ItemID == m_itemID) 4377 else
4027 throw new ScriptDeleteException(); 4378 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4028 else 4379 return;
4029 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4030 return;
4031 }
4032 } 4380 }
4033 } 4381 }
4034 } 4382 }
@@ -4063,112 +4411,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4411 {
4064 m_host.AddScriptLPS(1); 4412 m_host.AddScriptLPS(1);
4065 4413
4066 UUID uuid = (UUID)id; 4414 UUID uuid;
4067 PresenceInfo pinfo = null; 4415 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4416 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4417 PresenceInfo pinfo = null;
4074 if (account == null) 4418 UserAccount account;
4419
4420 UserInfoCacheEntry ce;
4421 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4422 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4423 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4424 if (account == null)
4078 } 4425 {
4426 m_userInfoCache[uuid] = null; // Cache negative
4427 return UUID.Zero.ToString();
4428 }
4079 4429
4080 4430
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4431 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4432 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4433 {
4086 if (p.RegionID != UUID.Zero) 4434 foreach (PresenceInfo p in pinfos)
4087 { 4435 {
4088 pinfo = p; 4436 if (p.RegionID != UUID.Zero)
4437 {
4438 pinfo = p;
4439 }
4089 } 4440 }
4090 } 4441 }
4091 }
4092 4442
4093 ce = new UserInfoCacheEntry(); 4443 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4444 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4445 ce.account = account;
4096 ce.pinfo = pinfo; 4446 ce.pinfo = pinfo;
4097 } 4447 m_userInfoCache[uuid] = ce;
4098 else 4448 }
4099 { 4449 else
4100 if (ce == null) 4450 {
4101 return UUID.Zero.ToString(); 4451 if (ce == null)
4452 return UUID.Zero.ToString();
4102 4453
4103 account = ce.account; 4454 account = ce.account;
4104 pinfo = ce.pinfo; 4455 pinfo = ce.pinfo;
4105 } 4456 }
4106 4457
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4458 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4108 {
4109 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4110 if (pinfos != null && pinfos.Length > 0)
4111 { 4459 {
4112 foreach (PresenceInfo p in pinfos) 4460 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4461 if (pinfos != null && pinfos.Length > 0)
4113 { 4462 {
4114 if (p.RegionID != UUID.Zero) 4463 foreach (PresenceInfo p in pinfos)
4115 { 4464 {
4116 pinfo = p; 4465 if (p.RegionID != UUID.Zero)
4466 {
4467 pinfo = p;
4468 }
4117 } 4469 }
4118 } 4470 }
4119 } 4471 else
4120 else 4472 pinfo = null;
4121 pinfo = null;
4122 4473
4123 ce.time = Util.EnvironmentTickCount(); 4474 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4475 ce.pinfo = pinfo;
4125 } 4476 }
4126 4477
4127 string reply = String.Empty; 4478 string reply = String.Empty;
4128 4479
4129 switch (data) 4480 switch (data)
4130 { 4481 {
4131 case 1: // DATA_ONLINE (0|1) 4482 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4483 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4484 reply = "1";
4134 else 4485 else
4135 reply = "0"; 4486 reply = "0";
4136 break; 4487 break;
4137 case 2: // DATA_NAME (First Last) 4488 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4489 reply = account.FirstName + " " + account.LastName;
4139 break; 4490 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4491 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4492 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4493 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4494 reply = born.ToString("yyyy-MM-dd");
4144 break; 4495 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4496 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4497 reply = "0,0,0,0,0,0";
4147 break; 4498 break;
4148 case 8: // DATA_PAYINFO (0|1|2|3) 4499 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = "0"; 4500 reply = "0";
4150 break; 4501 break;
4151 default: 4502 default:
4152 return UUID.Zero.ToString(); // Raise no event 4503 return UUID.Zero.ToString(); // Raise no event
4153 } 4504 }
4154 4505
4155 UUID rq = UUID.Random(); 4506 UUID rq = UUID.Random();
4156 4507
4157 UUID tid = AsyncCommands. 4508 UUID tid = AsyncCommands.
4158 DataserverPlugin.RegisterRequest(m_localID, 4509 DataserverPlugin.RegisterRequest(m_localID,
4159 m_itemID, rq.ToString()); 4510 m_itemID, rq.ToString());
4160 4511
4161 AsyncCommands. 4512 AsyncCommands.
4162 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4513 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4163 4514
4164 ScriptSleep(100); 4515 ScriptSleep(100);
4165 return tid.ToString(); 4516 return tid.ToString();
4517 }
4518 else
4519 {
4520 ShoutError("Invalid UUID passed to llRequestAgentData.");
4521 }
4522 return "";
4166 } 4523 }
4167 4524
4168 public LSL_String llRequestInventoryData(string name) 4525 public LSL_String llRequestInventoryData(string name)
4169 { 4526 {
4170 m_host.AddScriptLPS(1); 4527 m_host.AddScriptLPS(1);
4171 4528
4529 //Clone is thread safe
4172 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4530 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4173 4531
4174 foreach (TaskInventoryItem item in itemDictionary.Values) 4532 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4222,6 +4580,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 ScenePresence presence = World.GetScenePresence(agentId); 4580 ScenePresence presence = World.GetScenePresence(agentId);
4223 if (presence != null) 4581 if (presence != null)
4224 { 4582 {
4583 // agent must not be a god
4584 if (presence.UserLevel >= 200) return;
4585
4225 // agent must be over the owners land 4586 // agent must be over the owners land
4226 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4587 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4227 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4588 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4244,7 +4605,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 UUID av = new UUID(); 4605 UUID av = new UUID();
4245 if (!UUID.TryParse(agent,out av)) 4606 if (!UUID.TryParse(agent,out av))
4246 { 4607 {
4247 LSLError("First parameter to llDialog needs to be a key"); 4608 //LSLError("First parameter to llDialog needs to be a key");
4248 return; 4609 return;
4249 } 4610 }
4250 4611
@@ -4281,17 +4642,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID soundId = UUID.Zero; 4642 UUID soundId = UUID.Zero;
4282 if (!UUID.TryParse(impact_sound, out soundId)) 4643 if (!UUID.TryParse(impact_sound, out soundId))
4283 { 4644 {
4284 lock (m_host.TaskInventory) 4645 m_host.TaskInventory.LockItemsForRead(true);
4646 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4285 { 4647 {
4286 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4648 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4287 { 4649 {
4288 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4650 soundId = item.AssetID;
4289 { 4651 break;
4290 soundId = item.AssetID;
4291 break;
4292 }
4293 } 4652 }
4294 } 4653 }
4654 m_host.TaskInventory.LockItemsForRead(false);
4295 } 4655 }
4296 m_host.CollisionSound = soundId; 4656 m_host.CollisionSound = soundId;
4297 m_host.CollisionSoundVolume = (float)impact_volume; 4657 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4331,6 +4691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 UUID partItemID; 4691 UUID partItemID;
4332 foreach (SceneObjectPart part in parts) 4692 foreach (SceneObjectPart part in parts)
4333 { 4693 {
4694 //Clone is thread safe
4334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4695 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4335 4696
4336 foreach (TaskInventoryItem item in itemsDictionary.Values) 4697 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4545,17 +4906,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4545 4906
4546 m_host.AddScriptLPS(1); 4907 m_host.AddScriptLPS(1);
4547 4908
4548 lock (m_host.TaskInventory) 4909 m_host.TaskInventory.LockItemsForRead(true);
4910 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4549 { 4911 {
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4912 if (item.Type == 10 && item.ItemID == m_itemID)
4551 { 4913 {
4552 if (item.Type == 10 && item.ItemID == m_itemID) 4914 result = item.Name!=null?item.Name:String.Empty;
4553 { 4915 break;
4554 result = item.Name != null ? item.Name : String.Empty;
4555 break;
4556 }
4557 } 4916 }
4558 } 4917 }
4918 m_host.TaskInventory.LockItemsForRead(false);
4559 4919
4560 return result; 4920 return result;
4561 } 4921 }
@@ -4728,23 +5088,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5088 {
4729 m_host.AddScriptLPS(1); 5089 m_host.AddScriptLPS(1);
4730 5090
4731 lock (m_host.TaskInventory) 5091 m_host.TaskInventory.LockItemsForRead(true);
5092 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4732 { 5093 {
4733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5094 if (inv.Value.Name == name)
4734 { 5095 {
4735 if (inv.Value.Name == name) 5096 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4736 { 5097 {
4737 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5098 m_host.TaskInventory.LockItemsForRead(false);
4738 { 5099 return inv.Value.AssetID.ToString();
4739 return inv.Value.AssetID.ToString(); 5100 }
4740 } 5101 else
4741 else 5102 {
4742 { 5103 m_host.TaskInventory.LockItemsForRead(false);
4743 return UUID.Zero.ToString(); 5104 return UUID.Zero.ToString();
4744 }
4745 } 5105 }
4746 } 5106 }
4747 } 5107 }
5108 m_host.TaskInventory.LockItemsForRead(false);
4748 5109
4749 return UUID.Zero.ToString(); 5110 return UUID.Zero.ToString();
4750 } 5111 }
@@ -4897,14 +5258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 { 5258 {
4898 m_host.AddScriptLPS(1); 5259 m_host.AddScriptLPS(1);
4899 5260
4900 if (src == null) 5261 return src.Length;
4901 {
4902 return 0;
4903 }
4904 else
4905 {
4906 return src.Length;
4907 }
4908 } 5262 }
4909 5263
4910 public LSL_Integer llList2Integer(LSL_List src, int index) 5264 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4950,7 +5304,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 else if (src.Data[index] is LSL_Float) 5304 else if (src.Data[index] is LSL_Float)
4951 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5305 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4952 else if (src.Data[index] is LSL_String) 5306 else if (src.Data[index] is LSL_String)
4953 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5307 {
5308 string str = ((LSL_String) src.Data[index]).m_string;
5309 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5310 if (m != Match.Empty)
5311 {
5312 str = m.Value;
5313 double d = 0.0;
5314 if (!Double.TryParse(str, out d))
5315 return 0.0;
5316
5317 return d;
5318 }
5319 return 0.0;
5320 }
4954 return Convert.ToDouble(src.Data[index]); 5321 return Convert.ToDouble(src.Data[index]);
4955 } 5322 }
4956 catch (FormatException) 5323 catch (FormatException)
@@ -5223,7 +5590,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5223 } 5590 }
5224 } 5591 }
5225 } 5592 }
5226 else { 5593 else
5594 {
5227 object[] array = new object[src.Length]; 5595 object[] array = new object[src.Length];
5228 Array.Copy(src.Data, 0, array, 0, src.Length); 5596 Array.Copy(src.Data, 0, array, 0, src.Length);
5229 result = new LSL_List(array); 5597 result = new LSL_List(array);
@@ -5672,10 +6040,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5672 m_host.AddScriptLPS(1); 6040 m_host.AddScriptLPS(1);
5673 6041
5674 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6042 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5675 6043 if (parts.Count > 0)
5676 foreach (var part in parts)
5677 { 6044 {
5678 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6045 try
6046 {
6047 parts[0].ParentGroup.areUpdatesSuspended = true;
6048 foreach (var part in parts)
6049 {
6050 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6051 }
6052 }
6053 finally
6054 {
6055 parts[0].ParentGroup.areUpdatesSuspended = false;
6056 }
5679 } 6057 }
5680 } 6058 }
5681 6059
@@ -5729,6 +6107,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5729 ScriptSleep(5000); 6107 ScriptSleep(5000);
5730 } 6108 }
5731 6109
6110 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6111 {
6112 return ParseString2List(str, separators, in_spacers, false);
6113 }
6114
5732 public LSL_Integer llOverMyLand(string id) 6115 public LSL_Integer llOverMyLand(string id)
5733 { 6116 {
5734 m_host.AddScriptLPS(1); 6117 m_host.AddScriptLPS(1);
@@ -5793,8 +6176,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5793 UUID agentId = new UUID(); 6176 UUID agentId = new UUID();
5794 if (!UUID.TryParse(agent, out agentId)) 6177 if (!UUID.TryParse(agent, out agentId))
5795 return new LSL_Integer(0); 6178 return new LSL_Integer(0);
6179 if (agentId == m_host.GroupID)
6180 return new LSL_Integer(1);
5796 ScenePresence presence = World.GetScenePresence(agentId); 6181 ScenePresence presence = World.GetScenePresence(agentId);
5797 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6182 if (presence == null || presence.IsChildAgent) // Return false for child agents
5798 return new LSL_Integer(0); 6183 return new LSL_Integer(0);
5799 IClientAPI client = presence.ControllingClient; 6184 IClientAPI client = presence.ControllingClient;
5800 if (m_host.GroupID == client.ActiveGroupId) 6185 if (m_host.GroupID == client.ActiveGroupId)
@@ -5929,7 +6314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5929 return m_host.ParentGroup.AttachmentPoint; 6314 return m_host.ParentGroup.AttachmentPoint;
5930 } 6315 }
5931 6316
5932 public LSL_Integer llGetFreeMemory() 6317 public virtual LSL_Integer llGetFreeMemory()
5933 { 6318 {
5934 m_host.AddScriptLPS(1); 6319 m_host.AddScriptLPS(1);
5935 // Make scripts designed for LSO happy 6320 // Make scripts designed for LSO happy
@@ -6046,7 +6431,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6046 SetParticleSystem(m_host, rules); 6431 SetParticleSystem(m_host, rules);
6047 } 6432 }
6048 6433
6049 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6434 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6435 {
6050 6436
6051 6437
6052 if (rules.Length == 0) 6438 if (rules.Length == 0)
@@ -6240,14 +6626,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6240 6626
6241 protected UUID GetTaskInventoryItem(string name) 6627 protected UUID GetTaskInventoryItem(string name)
6242 { 6628 {
6243 lock (m_host.TaskInventory) 6629 m_host.TaskInventory.LockItemsForRead(true);
6630 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6244 { 6631 {
6245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6632 if (inv.Value.Name == name)
6246 { 6633 {
6247 if (inv.Value.Name == name) 6634 m_host.TaskInventory.LockItemsForRead(false);
6248 return inv.Key; 6635 return inv.Key;
6249 } 6636 }
6250 } 6637 }
6638 m_host.TaskInventory.LockItemsForRead(false);
6251 6639
6252 return UUID.Zero; 6640 return UUID.Zero;
6253 } 6641 }
@@ -6285,16 +6673,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6285 if (folderID == UUID.Zero) 6673 if (folderID == UUID.Zero)
6286 return; 6674 return;
6287 6675
6288 byte[] bucket = new byte[17]; 6676 byte[] bucket = new byte[1];
6289 bucket[0] = (byte)AssetType.Folder; 6677 bucket[0] = (byte)AssetType.Folder;
6290 byte[] objBytes = folderID.GetBytes(); 6678 //byte[] objBytes = folderID.GetBytes();
6291 Array.Copy(objBytes, 0, bucket, 1, 16); 6679 //Array.Copy(objBytes, 0, bucket, 1, 16);
6292 6680
6293 GridInstantMessage msg = new GridInstantMessage(World, 6681 GridInstantMessage msg = new GridInstantMessage(World,
6294 m_host.UUID, m_host.Name+", an object owned by "+ 6682 m_host.OwnerID, m_host.Name, destID,
6295 resolveName(m_host.OwnerID)+",", destID, 6683 (byte)InstantMessageDialog.TaskInventoryOffered,
6296 (byte)InstantMessageDialog.InventoryOffered, 6684 false, category+". "+m_host.Name+" is located at "+
6297 false, category+"\n"+m_host.Name+" is located at "+
6298 World.RegionInfo.RegionName+" "+ 6685 World.RegionInfo.RegionName+" "+
6299 m_host.AbsolutePosition.ToString(), 6686 m_host.AbsolutePosition.ToString(),
6300 folderID, true, m_host.AbsolutePosition, 6687 folderID, true, m_host.AbsolutePosition,
@@ -6497,13 +6884,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6497 UUID av = new UUID(); 6884 UUID av = new UUID();
6498 if (!UUID.TryParse(avatar,out av)) 6885 if (!UUID.TryParse(avatar,out av))
6499 { 6886 {
6500 LSLError("First parameter to llDialog needs to be a key"); 6887 //LSLError("First parameter to llDialog needs to be a key");
6501 return; 6888 return;
6502 } 6889 }
6503 if (buttons.Length < 1) 6890 if (buttons.Length < 1)
6504 { 6891 {
6505 LSLError("No less than 1 button can be shown"); 6892 buttons.Add("OK");
6506 return;
6507 } 6893 }
6508 if (buttons.Length > 12) 6894 if (buttons.Length > 12)
6509 { 6895 {
@@ -6520,7 +6906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6520 } 6906 }
6521 if (buttons.Data[i].ToString().Length > 24) 6907 if (buttons.Data[i].ToString().Length > 24)
6522 { 6908 {
6523 LSLError("button label cannot be longer than 24 characters"); 6909 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6524 return; 6910 return;
6525 } 6911 }
6526 buts[i] = buttons.Data[i].ToString(); 6912 buts[i] = buttons.Data[i].ToString();
@@ -6579,22 +6965,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6579 } 6965 }
6580 6966
6581 // copy the first script found with this inventory name 6967 // copy the first script found with this inventory name
6582 lock (m_host.TaskInventory) 6968 TaskInventoryItem scriptItem = null;
6969 m_host.TaskInventory.LockItemsForRead(true);
6970 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6583 { 6971 {
6584 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6972 if (inv.Value.Name == name)
6585 { 6973 {
6586 if (inv.Value.Name == name) 6974 // make sure the object is a script
6975 if (10 == inv.Value.Type)
6587 { 6976 {
6588 // make sure the object is a script 6977 found = true;
6589 if (10 == inv.Value.Type) 6978 srcId = inv.Key;
6590 { 6979 scriptItem = inv.Value;
6591 found = true; 6980 break;
6592 srcId = inv.Key;
6593 break;
6594 }
6595 } 6981 }
6596 } 6982 }
6597 } 6983 }
6984 m_host.TaskInventory.LockItemsForRead(false);
6598 6985
6599 if (!found) 6986 if (!found)
6600 { 6987 {
@@ -6602,8 +6989,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6602 return; 6989 return;
6603 } 6990 }
6604 6991
6605 // the rest of the permission checks are done in RezScript, so check the pin there as well 6992 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6606 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6993 if (dest != null)
6994 {
6995 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6996 {
6997 // the rest of the permission checks are done in RezScript, so check the pin there as well
6998 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6999
7000 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7001 m_host.Inventory.RemoveInventoryItem(srcId);
7002 }
7003 }
6607 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7004 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6608 ScriptSleep(3000); 7005 ScriptSleep(3000);
6609 } 7006 }
@@ -6666,19 +7063,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6666 public LSL_String llMD5String(string src, int nonce) 7063 public LSL_String llMD5String(string src, int nonce)
6667 { 7064 {
6668 m_host.AddScriptLPS(1); 7065 m_host.AddScriptLPS(1);
6669 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7066 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6670 } 7067 }
6671 7068
6672 public LSL_String llSHA1String(string src) 7069 public LSL_String llSHA1String(string src)
6673 { 7070 {
6674 m_host.AddScriptLPS(1); 7071 m_host.AddScriptLPS(1);
6675 return Util.SHA1Hash(src).ToLower(); 7072 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6676 } 7073 }
6677 7074
6678 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7075 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6679 { 7076 {
6680 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7077 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6681 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7078 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7080 return shapeBlock;
6682 7081
6683 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7082 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6684 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7083 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6783,6 +7182,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6783 // Prim type box, cylinder and prism. 7182 // Prim type box, cylinder and prism.
6784 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) 7183 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)
6785 { 7184 {
7185 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7186 return;
7187
6786 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7188 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6787 ObjectShapePacket.ObjectDataBlock shapeBlock; 7189 ObjectShapePacket.ObjectDataBlock shapeBlock;
6788 7190
@@ -6836,6 +7238,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6836 // Prim type sphere. 7238 // Prim type sphere.
6837 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7239 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6838 { 7240 {
7241 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7242 return;
7243
6839 ObjectShapePacket.ObjectDataBlock shapeBlock; 7244 ObjectShapePacket.ObjectDataBlock shapeBlock;
6840 7245
6841 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7246 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6877,6 +7282,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 // Prim type torus, tube and ring. 7282 // Prim type torus, tube and ring.
6878 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) 7283 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)
6879 { 7284 {
7285 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7286 return;
7287
6880 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7288 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6881 ObjectShapePacket.ObjectDataBlock shapeBlock; 7289 ObjectShapePacket.ObjectDataBlock shapeBlock;
6882 7290
@@ -7012,6 +7420,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7012 // Prim type sculpt. 7420 // Prim type sculpt.
7013 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7421 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7014 { 7422 {
7423 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7424 return;
7425
7015 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7426 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7016 UUID sculptId; 7427 UUID sculptId;
7017 7428
@@ -7028,13 +7439,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7028 shapeBlock.PathScaleX = 100; 7439 shapeBlock.PathScaleX = 100;
7029 shapeBlock.PathScaleY = 150; 7440 shapeBlock.PathScaleY = 150;
7030 7441
7031 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7442 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7032 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7443 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7033 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7444 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7034 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7445 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7035 { 7446 {
7036 // default 7447 // default
7037 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7448 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7038 } 7449 }
7039 7450
7040 part.Shape.SetSculptProperties((byte)type, sculptId); 7451 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7050,32 +7461,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7050 ScriptSleep(200); 7461 ScriptSleep(200);
7051 } 7462 }
7052 7463
7053 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7464 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7054 { 7465 {
7055 m_host.AddScriptLPS(1); 7466 m_host.AddScriptLPS(1);
7056 7467
7057 setLinkPrimParams(linknumber, rules); 7468 setLinkPrimParams(linknumber, rules);
7058
7059 ScriptSleep(200);
7060 } 7469 }
7061 7470
7062 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7471 private void setLinkPrimParams(int linknumber, LSL_List rules)
7063 { 7472 {
7064 m_host.AddScriptLPS(1); 7473 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7474 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7475 if (parts.Count>0)
7476 {
7477 try
7478 {
7479 parts[0].ParentGroup.areUpdatesSuspended = true;
7480 foreach (SceneObjectPart part in parts)
7481 SetPrimParams(part, rules);
7482 }
7483 finally
7484 {
7485 parts[0].ParentGroup.areUpdatesSuspended = false;
7486 }
7487 }
7488 if (avatars.Count > 0)
7489 {
7490 foreach (ScenePresence avatar in avatars)
7491 SetPrimParams(avatar, rules);
7492 }
7493 }
7065 7494
7066 setLinkPrimParams(linknumber, rules); 7495 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7496 {
7497 llSetLinkPrimitiveParamsFast(linknumber, rules);
7498 ScriptSleep(200);
7067 } 7499 }
7068 7500
7069 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7501 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7070 { 7502 {
7071 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7503 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7504 //We only support PRIM_POSITION and PRIM_ROTATION
7072 7505
7073 foreach (SceneObjectPart part in parts) 7506 int idx = 0;
7074 SetPrimParams(part, rules); 7507
7508 while (idx < rules.Length)
7509 {
7510 int code = rules.GetLSLIntegerItem(idx++);
7511
7512 int remain = rules.Length - idx;
7513
7514
7515
7516 switch (code)
7517 {
7518 case (int)ScriptBaseClass.PRIM_POSITION:
7519 if (remain < 1)
7520 return;
7521 LSL_Vector v;
7522 v = rules.GetVector3Item(idx++);
7523 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7524 av.SendAvatarDataToAllAgents();
7525
7526 break;
7527
7528 case (int)ScriptBaseClass.PRIM_ROTATION:
7529 if (remain < 1)
7530 return;
7531 LSL_Rotation r;
7532 r = rules.GetQuaternionItem(idx++);
7533 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7534 av.SendAvatarDataToAllAgents();
7535 break;
7536 }
7537 }
7075 } 7538 }
7076 7539
7077 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7540 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7078 { 7541 {
7542 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7543 return;
7544
7079 int idx = 0; 7545 int idx = 0;
7080 7546
7081 bool positionChanged = false; 7547 bool positionChanged = false;
@@ -7103,6 +7569,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7103 currentPosition = GetSetPosTarget(part, v, currentPosition); 7569 currentPosition = GetSetPosTarget(part, v, currentPosition);
7104 7570
7105 break; 7571 break;
7572 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7573 if (remain < 1)
7574 return;
7575
7576 v=rules.GetVector3Item(idx++);
7577 positionChanged = true;
7578 currentPosition = GetSetPosTarget(part, v, currentPosition);
7579
7580 break;
7106 case (int)ScriptBaseClass.PRIM_SIZE: 7581 case (int)ScriptBaseClass.PRIM_SIZE:
7107 if (remain < 1) 7582 if (remain < 1)
7108 return; 7583 return;
@@ -7480,6 +7955,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7480 } 7955 }
7481 } 7956 }
7482 } 7957 }
7958
7959 if (positionChanged)
7960 {
7961 if (part.ParentGroup.RootPart == part)
7962 {
7963 SceneObjectGroup parent = part.ParentGroup;
7964 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7965 }
7966 else
7967 {
7968 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7969 SceneObjectGroup parent = part.ParentGroup;
7970 parent.HasGroupChanged = true;
7971 parent.ScheduleGroupForTerseUpdate();
7972 }
7973 }
7483 } 7974 }
7484 7975
7485 public LSL_String llStringToBase64(string str) 7976 public LSL_String llStringToBase64(string str)
@@ -7628,13 +8119,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7628 public LSL_Integer llGetNumberOfPrims() 8119 public LSL_Integer llGetNumberOfPrims()
7629 { 8120 {
7630 m_host.AddScriptLPS(1); 8121 m_host.AddScriptLPS(1);
7631 int avatarCount = 0; 8122 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7632 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8123
7633 {
7634 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7635 avatarCount++;
7636 });
7637
7638 return m_host.ParentGroup.PrimCount + avatarCount; 8124 return m_host.ParentGroup.PrimCount + avatarCount;
7639 } 8125 }
7640 8126
@@ -7650,55 +8136,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7650 m_host.AddScriptLPS(1); 8136 m_host.AddScriptLPS(1);
7651 UUID objID = UUID.Zero; 8137 UUID objID = UUID.Zero;
7652 LSL_List result = new LSL_List(); 8138 LSL_List result = new LSL_List();
8139
8140 // If the ID is not valid, return null result
7653 if (!UUID.TryParse(obj, out objID)) 8141 if (!UUID.TryParse(obj, out objID))
7654 { 8142 {
7655 result.Add(new LSL_Vector()); 8143 result.Add(new LSL_Vector());
7656 result.Add(new LSL_Vector()); 8144 result.Add(new LSL_Vector());
7657 return result; 8145 return result;
7658 } 8146 }
8147
8148 // Check if this is an attached prim. If so, replace
8149 // the UUID with the avatar UUID and report it's bounding box
8150 SceneObjectPart part = World.GetSceneObjectPart(objID);
8151 if (part != null && part.ParentGroup.IsAttachment)
8152 objID = part.ParentGroup.AttachedAvatar;
8153
8154 // Find out if this is an avatar ID. If so, return it's box
7659 ScenePresence presence = World.GetScenePresence(objID); 8155 ScenePresence presence = World.GetScenePresence(objID);
7660 if (presence != null) 8156 if (presence != null)
7661 { 8157 {
7662 if (presence.ParentID == 0) // not sat on an object 8158 // As per LSL Wiki, there is no difference between sitting
8159 // and standing avatar since server 1.36
8160 LSL_Vector lower;
8161 LSL_Vector upper;
8162 if (presence.Animator.Animations.DefaultAnimation.AnimID
8163 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7663 { 8164 {
7664 LSL_Vector lower; 8165 // This is for ground sitting avatars
7665 LSL_Vector upper; 8166 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7666 if (presence.Animator.Animations.DefaultAnimation.AnimID 8167 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7667 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8168 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7668 {
7669 // This is for ground sitting avatars
7670 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7671 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7672 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7673 }
7674 else
7675 {
7676 // This is for standing/flying avatars
7677 float height = presence.Appearance.AvatarHeight / 2.0f;
7678 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7679 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7680 }
7681 result.Add(lower);
7682 result.Add(upper);
7683 return result;
7684 } 8169 }
7685 else 8170 else
7686 { 8171 {
7687 // sitting on an object so we need the bounding box of that 8172 // This is for standing/flying avatars
7688 // which should include the avatar so set the UUID to the 8173 float height = presence.Appearance.AvatarHeight / 2.0f;
7689 // UUID of the object the avatar is sat on and allow it to fall through 8174 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7690 // to processing an object 8175 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7691 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7692 objID = p.UUID;
7693 } 8176 }
8177
8178 // Adjust to the documented error offsets (see LSL Wiki)
8179 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8180 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8181
8182 if (lower.x > upper.x)
8183 lower.x = upper.x;
8184 if (lower.y > upper.y)
8185 lower.y = upper.y;
8186 if (lower.z > upper.z)
8187 lower.z = upper.z;
8188
8189 result.Add(lower);
8190 result.Add(upper);
8191 return result;
7694 } 8192 }
7695 SceneObjectPart part = World.GetSceneObjectPart(objID); 8193
8194 part = World.GetSceneObjectPart(objID);
7696 // Currently only works for single prims without a sitting avatar 8195 // Currently only works for single prims without a sitting avatar
7697 if (part != null) 8196 if (part != null)
7698 { 8197 {
7699 Vector3 halfSize = part.Scale / 2.0f; 8198 float minX;
7700 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8199 float maxX;
7701 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8200 float minY;
8201 float maxY;
8202 float minZ;
8203 float maxZ;
8204
8205 // This BBox is in sim coordinates, with the offset being
8206 // a contained point.
8207 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8208 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8209
8210 minX -= offsets[0].X;
8211 maxX -= offsets[0].X;
8212 minY -= offsets[0].Y;
8213 maxY -= offsets[0].Y;
8214 minZ -= offsets[0].Z;
8215 maxZ -= offsets[0].Z;
8216
8217 LSL_Vector lower;
8218 LSL_Vector upper;
8219
8220 // Adjust to the documented error offsets (see LSL Wiki)
8221 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8222 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8223
8224 if (lower.x > upper.x)
8225 lower.x = upper.x;
8226 if (lower.y > upper.y)
8227 lower.y = upper.y;
8228 if (lower.z > upper.z)
8229 lower.z = upper.z;
8230
7702 result.Add(lower); 8231 result.Add(lower);
7703 result.Add(upper); 8232 result.Add(upper);
7704 return result; 8233 return result;
@@ -7778,13 +8307,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7778 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8307 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7779 part.AbsolutePosition.Y, 8308 part.AbsolutePosition.Y,
7780 part.AbsolutePosition.Z); 8309 part.AbsolutePosition.Z);
7781 // For some reason, the part.AbsolutePosition.* values do not change if the
7782 // linkset is rotated; they always reflect the child prim's world position
7783 // as though the linkset is unrotated. This is incompatible behavior with SL's
7784 // implementation, so will break scripts imported from there (not to mention it
7785 // makes it more difficult to determine a child prim's actual inworld position).
7786 if (part.ParentID != 0)
7787 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7788 res.Add(v); 8310 res.Add(v);
7789 break; 8311 break;
7790 8312
@@ -7955,56 +8477,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8477 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7956 if (remain < 1) 8478 if (remain < 1)
7957 return res; 8479 return res;
7958 8480 face = (int)rules.GetLSLIntegerItem(idx++);
7959 face=(int)rules.GetLSLIntegerItem(idx++);
7960 8481
7961 tex = part.Shape.Textures; 8482 tex = part.Shape.Textures;
8483 int shiny;
7962 if (face == ScriptBaseClass.ALL_SIDES) 8484 if (face == ScriptBaseClass.ALL_SIDES)
7963 { 8485 {
7964 for (face = 0; face < GetNumberOfSides(part); face++) 8486 for (face = 0; face < GetNumberOfSides(part); face++)
7965 { 8487 {
7966 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8488 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7967 // Convert Shininess to PRIM_SHINY_* 8489 if (shinyness == Shininess.High)
7968 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8490 {
7969 // PRIM_BUMP_* 8491 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7970 res.Add(new LSL_Integer((int)texface.Bump)); 8492 }
8493 else if (shinyness == Shininess.Medium)
8494 {
8495 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8496 }
8497 else if (shinyness == Shininess.Low)
8498 {
8499 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8500 }
8501 else
8502 {
8503 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8504 }
8505 res.Add(new LSL_Integer(shiny));
8506 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7971 } 8507 }
7972 } 8508 }
7973 else 8509 else
7974 { 8510 {
7975 if (face >= 0 && face < GetNumberOfSides(part)) 8511 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8512 if (shinyness == Shininess.High)
7976 { 8513 {
7977 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8514 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7978 // Convert Shininess to PRIM_SHINY_* 8515 }
7979 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8516 else if (shinyness == Shininess.Medium)
7980 // PRIM_BUMP_* 8517 {
7981 res.Add(new LSL_Integer((int)texface.Bump)); 8518 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8519 }
8520 else if (shinyness == Shininess.Low)
8521 {
8522 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8523 }
8524 else
8525 {
8526 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7982 } 8527 }
8528 res.Add(new LSL_Integer(shiny));
8529 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7983 } 8530 }
7984 break; 8531 break;
7985 8532
7986 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8533 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7987 if (remain < 1) 8534 if (remain < 1)
7988 return res; 8535 return res;
7989 8536 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8537
7992 tex = part.Shape.Textures; 8538 tex = part.Shape.Textures;
8539 int fullbright;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8540 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8541 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8542 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8543 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8544 if (tex.GetFace((uint)face).Fullbright == true)
7998 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8545 {
8546 fullbright = ScriptBaseClass.TRUE;
8547 }
8548 else
8549 {
8550 fullbright = ScriptBaseClass.FALSE;
8551 }
8552 res.Add(new LSL_Integer(fullbright));
7999 } 8553 }
8000 } 8554 }
8001 else 8555 else
8002 { 8556 {
8003 if (face >= 0 && face < GetNumberOfSides(part)) 8557 if (tex.GetFace((uint)face).Fullbright == true)
8004 { 8558 {
8005 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8559 fullbright = ScriptBaseClass.TRUE;
8006 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8007 } 8560 }
8561 else
8562 {
8563 fullbright = ScriptBaseClass.FALSE;
8564 }
8565 res.Add(new LSL_Integer(fullbright));
8008 } 8566 }
8009 break; 8567 break;
8010 8568
@@ -8026,27 +8584,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8026 break; 8584 break;
8027 8585
8028 case (int)ScriptBaseClass.PRIM_TEXGEN: 8586 case (int)ScriptBaseClass.PRIM_TEXGEN:
8587 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8029 if (remain < 1) 8588 if (remain < 1)
8030 return res; 8589 return res;
8031 8590 face = (int)rules.GetLSLIntegerItem(idx++);
8032 face=(int)rules.GetLSLIntegerItem(idx++);
8033 8591
8034 tex = part.Shape.Textures; 8592 tex = part.Shape.Textures;
8035 if (face == ScriptBaseClass.ALL_SIDES) 8593 if (face == ScriptBaseClass.ALL_SIDES)
8036 { 8594 {
8037 for (face = 0; face < GetNumberOfSides(part); face++) 8595 for (face = 0; face < GetNumberOfSides(part); face++)
8038 { 8596 {
8039 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8597 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8040 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8598 {
8041 res.Add(new LSL_Integer((uint)texgen >> 1)); 8599 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8600 }
8601 else
8602 {
8603 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8604 }
8042 } 8605 }
8043 } 8606 }
8044 else 8607 else
8045 { 8608 {
8046 if (face >= 0 && face < GetNumberOfSides(part)) 8609 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8610 {
8611 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8612 }
8613 else
8047 { 8614 {
8048 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8615 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8049 res.Add(new LSL_Integer((uint)texgen >> 1));
8050 } 8616 }
8051 } 8617 }
8052 break; 8618 break;
@@ -8069,28 +8635,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8069 case (int)ScriptBaseClass.PRIM_GLOW: 8635 case (int)ScriptBaseClass.PRIM_GLOW:
8070 if (remain < 1) 8636 if (remain < 1)
8071 return res; 8637 return res;
8072 8638 face = (int)rules.GetLSLIntegerItem(idx++);
8073 face=(int)rules.GetLSLIntegerItem(idx++);
8074 8639
8075 tex = part.Shape.Textures; 8640 tex = part.Shape.Textures;
8641 float primglow;
8076 if (face == ScriptBaseClass.ALL_SIDES) 8642 if (face == ScriptBaseClass.ALL_SIDES)
8077 { 8643 {
8078 for (face = 0; face < GetNumberOfSides(part); face++) 8644 for (face = 0; face < GetNumberOfSides(part); face++)
8079 { 8645 {
8080 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8646 primglow = tex.GetFace((uint)face).Glow;
8081 res.Add(new LSL_Float(texface.Glow)); 8647 res.Add(new LSL_Float(primglow));
8082 } 8648 }
8083 } 8649 }
8084 else 8650 else
8085 { 8651 {
8086 if (face >= 0 && face < GetNumberOfSides(part)) 8652 primglow = tex.GetFace((uint)face).Glow;
8087 { 8653 res.Add(new LSL_Float(primglow));
8088 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8089 res.Add(new LSL_Float(texface.Glow));
8090 }
8091 } 8654 }
8092 break; 8655 break;
8093
8094 case (int)ScriptBaseClass.PRIM_TEXT: 8656 case (int)ScriptBaseClass.PRIM_TEXT:
8095 Color4 textColor = part.GetTextColor(); 8657 Color4 textColor = part.GetTextColor();
8096 res.Add(new LSL_String(part.Text)); 8658 res.Add(new LSL_String(part.Text));
@@ -8642,8 +9204,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8642 // The function returns an ordered list 9204 // The function returns an ordered list
8643 // representing the tokens found in the supplied 9205 // representing the tokens found in the supplied
8644 // sources string. If two successive tokenizers 9206 // sources string. If two successive tokenizers
8645 // are encountered, then a NULL entry is added 9207 // are encountered, then a null-string entry is
8646 // to the list. 9208 // added to the list.
8647 // 9209 //
8648 // It is a precondition that the source and 9210 // It is a precondition that the source and
8649 // toekizer lisst are non-null. If they are null, 9211 // toekizer lisst are non-null. If they are null,
@@ -8651,7 +9213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8651 // while their lengths are being determined. 9213 // while their lengths are being determined.
8652 // 9214 //
8653 // A small amount of working memoryis required 9215 // A small amount of working memoryis required
8654 // of approximately 8*#tokenizers. 9216 // of approximately 8*#tokenizers + 8*srcstrlen.
8655 // 9217 //
8656 // There are many ways in which this function 9218 // There are many ways in which this function
8657 // can be implemented, this implementation is 9219 // can be implemented, this implementation is
@@ -8667,155 +9229,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8667 // and eliminates redundant tokenizers as soon 9229 // and eliminates redundant tokenizers as soon
8668 // as is possible. 9230 // as is possible.
8669 // 9231 //
8670 // The implementation tries to avoid any copying 9232 // The implementation tries to minimize temporary
8671 // of arrays or other objects. 9233 // garbage generation.
8672 // </remarks> 9234 // </remarks>
8673 9235
8674 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9236 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8675 { 9237 {
8676 int beginning = 0; 9238 return ParseString2List(src, separators, spacers, true);
8677 int srclen = src.Length; 9239 }
8678 int seplen = separators.Length;
8679 object[] separray = separators.Data;
8680 int spclen = spacers.Length;
8681 object[] spcarray = spacers.Data;
8682 int mlen = seplen+spclen;
8683
8684 int[] offset = new int[mlen+1];
8685 bool[] active = new bool[mlen];
8686
8687 int best;
8688 int j;
8689
8690 // Initial capacity reduces resize cost
8691 9240
8692 LSL_List tokens = new LSL_List(); 9241 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9242 {
9243 int srclen = src.Length;
9244 int seplen = separators.Length;
9245 object[] separray = separators.Data;
9246 int spclen = spacers.Length;
9247 object[] spcarray = spacers.Data;
9248 int dellen = 0;
9249 string[] delarray = new string[seplen+spclen];
8693 9250
8694 // All entries are initially valid 9251 int outlen = 0;
9252 string[] outarray = new string[srclen*2+1];
8695 9253
8696 for (int i = 0; i < mlen; i++) 9254 int i, j;
8697 active[i] = true; 9255 string d;
8698 9256
8699 offset[mlen] = srclen; 9257 m_host.AddScriptLPS(1);
8700 9258
8701 while (beginning < srclen) 9259 /*
9260 * Convert separator and spacer lists to C# strings.
9261 * Also filter out null strings so we don't hang.
9262 */
9263 for (i = 0; i < seplen; i ++)
8702 { 9264 {
9265 d = separray[i].ToString();
9266 if (d.Length > 0)
9267 {
9268 delarray[dellen++] = d;
9269 }
9270 }
9271 seplen = dellen;
8703 9272
8704 best = mlen; // as bad as it gets 9273 for (i = 0; i < spclen; i ++)
9274 {
9275 d = spcarray[i].ToString();
9276 if (d.Length > 0)
9277 {
9278 delarray[dellen++] = d;
9279 }
9280 }
8705 9281
8706 // Scan for separators 9282 /*
9283 * Scan through source string from beginning to end.
9284 */
9285 for (i = 0;;)
9286 {
8707 9287
8708 for (j = 0; j < seplen; j++) 9288 /*
9289 * Find earliest delimeter in src starting at i (if any).
9290 */
9291 int earliestDel = -1;
9292 int earliestSrc = srclen;
9293 string earliestStr = null;
9294 for (j = 0; j < dellen; j ++)
8709 { 9295 {
8710 if (separray[j].ToString() == String.Empty) 9296 d = delarray[j];
8711 active[j] = false; 9297 if (d != null)
8712
8713 if (active[j])
8714 { 9298 {
8715 // scan all of the markers 9299 int index = src.IndexOf(d, i);
8716 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9300 if (index < 0)
8717 { 9301 {
8718 // not present at all 9302 delarray[j] = null; // delim nowhere in src, don't check it anymore
8719 active[j] = false;
8720 } 9303 }
8721 else 9304 else if (index < earliestSrc)
8722 { 9305 {
8723 // present and correct 9306 earliestSrc = index; // where delimeter starts in source string
8724 if (offset[j] < offset[best]) 9307 earliestDel = j; // where delimeter is in delarray[]
8725 { 9308 earliestStr = d; // the delimeter string from delarray[]
8726 // closest so far 9309 if (index == i) break; // can't do any better than found at beg of string
8727 best = j;
8728 if (offset[best] == beginning)
8729 break;
8730 }
8731 } 9310 }
8732 } 9311 }
8733 } 9312 }
8734 9313
8735 // Scan for spacers 9314 /*
8736 9315 * Output source string starting at i through start of earliest delimeter.
8737 if (offset[best] != beginning) 9316 */
9317 if (keepNulls || (earliestSrc > i))
8738 { 9318 {
8739 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9319 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8740 {
8741 if (spcarray[j-seplen].ToString() == String.Empty)
8742 active[j] = false;
8743
8744 if (active[j])
8745 {
8746 // scan all of the markers
8747 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8748 {
8749 // not present at all
8750 active[j] = false;
8751 }
8752 else
8753 {
8754 // present and correct
8755 if (offset[j] < offset[best])
8756 {
8757 // closest so far
8758 best = j;
8759 }
8760 }
8761 }
8762 }
8763 } 9320 }
8764 9321
8765 // This is the normal exit from the scanning loop 9322 /*
9323 * If no delimeter found at or after i, we're done scanning.
9324 */
9325 if (earliestDel < 0) break;
8766 9326
8767 if (best == mlen) 9327 /*
9328 * If delimeter was a spacer, output the spacer.
9329 */
9330 if (earliestDel >= seplen)
8768 { 9331 {
8769 // no markers were found on this pass 9332 outarray[outlen++] = earliestStr;
8770 // so we're pretty much done
8771 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8772 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8773 break;
8774 } 9333 }
8775 9334
8776 // Otherwise we just add the newly delimited token 9335 /*
8777 // and recalculate where the search should continue. 9336 * Look at rest of src string following delimeter.
8778 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9337 */
8779 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9338 i = earliestSrc + earliestStr.Length;
8780
8781 if (best < seplen)
8782 {
8783 beginning = offset[best] + (separray[best].ToString()).Length;
8784 }
8785 else
8786 {
8787 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8788 string str = spcarray[best - seplen].ToString();
8789 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8790 tokens.Add(new LSL_String(str));
8791 }
8792 } 9339 }
8793 9340
8794 // This an awkward an not very intuitive boundary case. If the 9341 /*
8795 // last substring is a tokenizer, then there is an implied trailing 9342 * Make up an exact-sized output array suitable for an LSL_List object.
8796 // null list entry. Hopefully the single comparison will not be too 9343 */
8797 // arduous. Alternatively the 'break' could be replced with a return 9344 object[] outlist = new object[outlen];
8798 // but that's shabby programming. 9345 for (i = 0; i < outlen; i ++)
8799
8800 if ((beginning == srclen) && (keepNulls))
8801 { 9346 {
8802 if (srclen != 0) 9347 outlist[i] = new LSL_String(outarray[i]);
8803 tokens.Add(new LSL_String(""));
8804 } 9348 }
8805 9349 return new LSL_List(outlist);
8806 return tokens;
8807 }
8808
8809 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8810 {
8811 m_host.AddScriptLPS(1);
8812 return this.ParseString(src, separators, spacers, false);
8813 }
8814
8815 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8816 {
8817 m_host.AddScriptLPS(1);
8818 return this.ParseString(src, separators, spacers, true);
8819 } 9350 }
8820 9351
8821 public LSL_Integer llGetObjectPermMask(int mask) 9352 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8892,28 +9423,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8892 { 9423 {
8893 m_host.AddScriptLPS(1); 9424 m_host.AddScriptLPS(1);
8894 9425
8895 lock (m_host.TaskInventory) 9426 m_host.TaskInventory.LockItemsForRead(true);
9427 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8896 { 9428 {
8897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9429 if (inv.Value.Name == item)
8898 { 9430 {
8899 if (inv.Value.Name == item) 9431 m_host.TaskInventory.LockItemsForRead(false);
9432 switch (mask)
8900 { 9433 {
8901 switch (mask) 9434 case 0:
8902 { 9435 return (int)inv.Value.BasePermissions;
8903 case 0: 9436 case 1:
8904 return (int)inv.Value.BasePermissions; 9437 return (int)inv.Value.CurrentPermissions;
8905 case 1: 9438 case 2:
8906 return (int)inv.Value.CurrentPermissions; 9439 return (int)inv.Value.GroupPermissions;
8907 case 2: 9440 case 3:
8908 return (int)inv.Value.GroupPermissions; 9441 return (int)inv.Value.EveryonePermissions;
8909 case 3: 9442 case 4:
8910 return (int)inv.Value.EveryonePermissions; 9443 return (int)inv.Value.NextPermissions;
8911 case 4:
8912 return (int)inv.Value.NextPermissions;
8913 }
8914 } 9444 }
8915 } 9445 }
8916 } 9446 }
9447 m_host.TaskInventory.LockItemsForRead(false);
8917 9448
8918 return -1; 9449 return -1;
8919 } 9450 }
@@ -8960,16 +9491,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8960 { 9491 {
8961 m_host.AddScriptLPS(1); 9492 m_host.AddScriptLPS(1);
8962 9493
8963 lock (m_host.TaskInventory) 9494 m_host.TaskInventory.LockItemsForRead(true);
9495 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8964 { 9496 {
8965 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9497 if (inv.Value.Name == item)
8966 { 9498 {
8967 if (inv.Value.Name == item) 9499 m_host.TaskInventory.LockItemsForRead(false);
8968 { 9500 return inv.Value.CreatorID.ToString();
8969 return inv.Value.CreatorID.ToString();
8970 }
8971 } 9501 }
8972 } 9502 }
9503 m_host.TaskInventory.LockItemsForRead(false);
8973 9504
8974 llSay(0, "No item name '" + item + "'"); 9505 llSay(0, "No item name '" + item + "'");
8975 9506
@@ -9117,7 +9648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 } 9648 }
9118 9649
9119 /// <summary> 9650 /// <summary>
9120 /// illListReplaceList removes the sub-list defined by the inclusive indices 9651 /// llListReplaceList removes the sub-list defined by the inclusive indices
9121 /// start and end and inserts the src list in its place. The inclusive 9652 /// start and end and inserts the src list in its place. The inclusive
9122 /// nature of the indices means that at least one element must be deleted 9653 /// nature of the indices means that at least one element must be deleted
9123 /// if the indices are within the bounds of the existing list. I.e. 2,2 9654 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9174,16 +9705,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9174 // based upon end. Note that if end exceeds the upper 9705 // based upon end. Note that if end exceeds the upper
9175 // bound in this case, the entire destination list 9706 // bound in this case, the entire destination list
9176 // is removed. 9707 // is removed.
9177 else 9708 else if (start == 0)
9178 { 9709 {
9179 if (end + 1 < dest.Length) 9710 if (end + 1 < dest.Length)
9180 {
9181 return src + dest.GetSublist(end + 1, -1); 9711 return src + dest.GetSublist(end + 1, -1);
9182 }
9183 else 9712 else
9184 {
9185 return src; 9713 return src;
9186 } 9714 }
9715 else // Start < 0
9716 {
9717 if (end + 1 < dest.Length)
9718 return dest.GetSublist(end + 1, -1);
9719 else
9720 return new LSL_List();
9187 } 9721 }
9188 } 9722 }
9189 // Finally, if start > end, we strip away a prefix and 9723 // Finally, if start > end, we strip away a prefix and
@@ -9234,17 +9768,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9234 int width = 0; 9768 int width = 0;
9235 int height = 0; 9769 int height = 0;
9236 9770
9237 ParcelMediaCommandEnum? commandToSend = null; 9771 uint commandToSend = 0;
9238 float time = 0.0f; // default is from start 9772 float time = 0.0f; // default is from start
9239 9773
9240 ScenePresence presence = null; 9774 ScenePresence presence = null;
9241 9775
9242 for (int i = 0; i < commandList.Data.Length; i++) 9776 for (int i = 0; i < commandList.Data.Length; i++)
9243 { 9777 {
9244 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9778 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9245 switch (command) 9779 switch (command)
9246 { 9780 {
9247 case ParcelMediaCommandEnum.Agent: 9781 case (uint)ParcelMediaCommandEnum.Agent:
9248 // we send only to one agent 9782 // we send only to one agent
9249 if ((i + 1) < commandList.Length) 9783 if ((i + 1) < commandList.Length)
9250 { 9784 {
@@ -9261,25 +9795,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 } 9795 }
9262 break; 9796 break;
9263 9797
9264 case ParcelMediaCommandEnum.Loop: 9798 case (uint)ParcelMediaCommandEnum.Loop:
9265 loop = 1; 9799 loop = 1;
9266 commandToSend = command; 9800 commandToSend = command;
9267 update = true; //need to send the media update packet to set looping 9801 update = true; //need to send the media update packet to set looping
9268 break; 9802 break;
9269 9803
9270 case ParcelMediaCommandEnum.Play: 9804 case (uint)ParcelMediaCommandEnum.Play:
9271 loop = 0; 9805 loop = 0;
9272 commandToSend = command; 9806 commandToSend = command;
9273 update = true; //need to send the media update packet to make sure it doesn't loop 9807 update = true; //need to send the media update packet to make sure it doesn't loop
9274 break; 9808 break;
9275 9809
9276 case ParcelMediaCommandEnum.Pause: 9810 case (uint)ParcelMediaCommandEnum.Pause:
9277 case ParcelMediaCommandEnum.Stop: 9811 case (uint)ParcelMediaCommandEnum.Stop:
9278 case ParcelMediaCommandEnum.Unload: 9812 case (uint)ParcelMediaCommandEnum.Unload:
9279 commandToSend = command; 9813 commandToSend = command;
9280 break; 9814 break;
9281 9815
9282 case ParcelMediaCommandEnum.Url: 9816 case (uint)ParcelMediaCommandEnum.Url:
9283 if ((i + 1) < commandList.Length) 9817 if ((i + 1) < commandList.Length)
9284 { 9818 {
9285 if (commandList.Data[i + 1] is LSL_String) 9819 if (commandList.Data[i + 1] is LSL_String)
@@ -9292,7 +9826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9826 }
9293 break; 9827 break;
9294 9828
9295 case ParcelMediaCommandEnum.Texture: 9829 case (uint)ParcelMediaCommandEnum.Texture:
9296 if ((i + 1) < commandList.Length) 9830 if ((i + 1) < commandList.Length)
9297 { 9831 {
9298 if (commandList.Data[i + 1] is LSL_String) 9832 if (commandList.Data[i + 1] is LSL_String)
@@ -9305,7 +9839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9305 } 9839 }
9306 break; 9840 break;
9307 9841
9308 case ParcelMediaCommandEnum.Time: 9842 case (uint)ParcelMediaCommandEnum.Time:
9309 if ((i + 1) < commandList.Length) 9843 if ((i + 1) < commandList.Length)
9310 { 9844 {
9311 if (commandList.Data[i + 1] is LSL_Float) 9845 if (commandList.Data[i + 1] is LSL_Float)
@@ -9317,7 +9851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9317 } 9851 }
9318 break; 9852 break;
9319 9853
9320 case ParcelMediaCommandEnum.AutoAlign: 9854 case (uint)ParcelMediaCommandEnum.AutoAlign:
9321 if ((i + 1) < commandList.Length) 9855 if ((i + 1) < commandList.Length)
9322 { 9856 {
9323 if (commandList.Data[i + 1] is LSL_Integer) 9857 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9331,7 +9865,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9331 } 9865 }
9332 break; 9866 break;
9333 9867
9334 case ParcelMediaCommandEnum.Type: 9868 case (uint)ParcelMediaCommandEnum.Type:
9335 if ((i + 1) < commandList.Length) 9869 if ((i + 1) < commandList.Length)
9336 { 9870 {
9337 if (commandList.Data[i + 1] is LSL_String) 9871 if (commandList.Data[i + 1] is LSL_String)
@@ -9344,7 +9878,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9344 } 9878 }
9345 break; 9879 break;
9346 9880
9347 case ParcelMediaCommandEnum.Desc: 9881 case (uint)ParcelMediaCommandEnum.Desc:
9348 if ((i + 1) < commandList.Length) 9882 if ((i + 1) < commandList.Length)
9349 { 9883 {
9350 if (commandList.Data[i + 1] is LSL_String) 9884 if (commandList.Data[i + 1] is LSL_String)
@@ -9357,7 +9891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 } 9891 }
9358 break; 9892 break;
9359 9893
9360 case ParcelMediaCommandEnum.Size: 9894 case (uint)ParcelMediaCommandEnum.Size:
9361 if ((i + 2) < commandList.Length) 9895 if ((i + 2) < commandList.Length)
9362 { 9896 {
9363 if (commandList.Data[i + 1] is LSL_Integer) 9897 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9427,7 +9961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9427 } 9961 }
9428 } 9962 }
9429 9963
9430 if (commandToSend != null) 9964 if (commandToSend != 0)
9431 { 9965 {
9432 // the commandList contained a start/stop/... command, too 9966 // the commandList contained a start/stop/... command, too
9433 if (presence == null) 9967 if (presence == null)
@@ -9464,7 +9998,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 9998
9465 if (aList.Data[i] != null) 9999 if (aList.Data[i] != null)
9466 { 10000 {
9467 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10001 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9468 { 10002 {
9469 case ParcelMediaCommandEnum.Url: 10003 case ParcelMediaCommandEnum.Url:
9470 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10004 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9507,16 +10041,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9507 { 10041 {
9508 m_host.AddScriptLPS(1); 10042 m_host.AddScriptLPS(1);
9509 10043
9510 lock (m_host.TaskInventory) 10044 m_host.TaskInventory.LockItemsForRead(true);
10045 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9511 { 10046 {
9512 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10047 if (inv.Value.Name == name)
9513 { 10048 {
9514 if (inv.Value.Name == name) 10049 m_host.TaskInventory.LockItemsForRead(false);
9515 { 10050 return inv.Value.Type;
9516 return inv.Value.Type;
9517 }
9518 } 10051 }
9519 } 10052 }
10053 m_host.TaskInventory.LockItemsForRead(false);
9520 10054
9521 return -1; 10055 return -1;
9522 } 10056 }
@@ -9527,15 +10061,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 10061
9528 if (quick_pay_buttons.Data.Length < 4) 10062 if (quick_pay_buttons.Data.Length < 4)
9529 { 10063 {
9530 LSLError("List must have at least 4 elements"); 10064 int x;
9531 return; 10065 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10066 {
10067 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10068 }
9532 } 10069 }
9533 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10070 int[] nPrice = new int[5];
9534 10071 nPrice[0] = price;
9535 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10072 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9536 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10073 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9537 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10074 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9538 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10075 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10076 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9539 m_host.ParentGroup.HasGroupChanged = true; 10077 m_host.ParentGroup.HasGroupChanged = true;
9540 } 10078 }
9541 10079
@@ -9547,17 +10085,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9547 if (invItemID == UUID.Zero) 10085 if (invItemID == UUID.Zero)
9548 return new LSL_Vector(); 10086 return new LSL_Vector();
9549 10087
9550 lock (m_host.TaskInventory) 10088 m_host.TaskInventory.LockItemsForRead(true);
10089 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9551 { 10090 {
9552 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10091 m_host.TaskInventory.LockItemsForRead(false);
9553 return new LSL_Vector(); 10092 return new LSL_Vector();
10093 }
9554 10094
9555 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10095 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9556 { 10096 {
9557 ShoutError("No permissions to track the camera"); 10097 ShoutError("No permissions to track the camera");
9558 return new LSL_Vector(); 10098 m_host.TaskInventory.LockItemsForRead(false);
9559 } 10099 return new LSL_Vector();
9560 } 10100 }
10101 m_host.TaskInventory.LockItemsForRead(false);
9561 10102
9562 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10103 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9563 if (presence != null) 10104 if (presence != null)
@@ -9575,17 +10116,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9575 if (invItemID == UUID.Zero) 10116 if (invItemID == UUID.Zero)
9576 return new LSL_Rotation(); 10117 return new LSL_Rotation();
9577 10118
9578 lock (m_host.TaskInventory) 10119 m_host.TaskInventory.LockItemsForRead(true);
10120 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9579 { 10121 {
9580 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10122 m_host.TaskInventory.LockItemsForRead(false);
9581 return new LSL_Rotation(); 10123 return new LSL_Rotation();
9582
9583 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9584 {
9585 ShoutError("No permissions to track the camera");
9586 return new LSL_Rotation();
9587 }
9588 } 10124 }
10125 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10126 {
10127 ShoutError("No permissions to track the camera");
10128 m_host.TaskInventory.LockItemsForRead(false);
10129 return new LSL_Rotation();
10130 }
10131 m_host.TaskInventory.LockItemsForRead(false);
9589 10132
9590 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10133 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9591 if (presence != null) 10134 if (presence != null)
@@ -9647,8 +10190,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 { 10190 {
9648 m_host.AddScriptLPS(1); 10191 m_host.AddScriptLPS(1);
9649 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10192 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9650 if (detectedParams == null) return; // only works on the first detected avatar 10193 if (detectedParams == null)
9651 10194 {
10195 if (m_host.ParentGroup.IsAttachment == true)
10196 {
10197 detectedParams = new DetectParams();
10198 detectedParams.Key = m_host.OwnerID;
10199 }
10200 else
10201 {
10202 return;
10203 }
10204 }
10205
9652 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10206 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9653 if (avatar != null) 10207 if (avatar != null)
9654 { 10208 {
@@ -9656,6 +10210,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10210 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9657 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10211 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9658 } 10212 }
10213
9659 ScriptSleep(1000); 10214 ScriptSleep(1000);
9660 } 10215 }
9661 10216
@@ -9748,14 +10303,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9748 if (objectID == UUID.Zero) return; 10303 if (objectID == UUID.Zero) return;
9749 10304
9750 UUID agentID; 10305 UUID agentID;
9751 lock (m_host.TaskInventory) 10306 m_host.TaskInventory.LockItemsForRead(true);
9752 { 10307 // we need the permission first, to know which avatar we want to set the camera for
9753 // we need the permission first, to know which avatar we want to set the camera for 10308 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9754 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9755 10309
9756 if (agentID == UUID.Zero) return; 10310 if (agentID == UUID.Zero)
9757 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10311 {
10312 m_host.TaskInventory.LockItemsForRead(false);
10313 return;
10314 }
10315 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10316 {
10317 m_host.TaskInventory.LockItemsForRead(false);
10318 return;
9758 } 10319 }
10320 m_host.TaskInventory.LockItemsForRead(false);
9759 10321
9760 ScenePresence presence = World.GetScenePresence(agentID); 10322 ScenePresence presence = World.GetScenePresence(agentID);
9761 10323
@@ -9764,12 +10326,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9764 10326
9765 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10327 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9766 object[] data = rules.Data; 10328 object[] data = rules.Data;
9767 for (int i = 0; i < data.Length; ++i) { 10329 for (int i = 0; i < data.Length; ++i)
10330 {
9768 int type = Convert.ToInt32(data[i++].ToString()); 10331 int type = Convert.ToInt32(data[i++].ToString());
9769 if (i >= data.Length) break; // odd number of entries => ignore the last 10332 if (i >= data.Length) break; // odd number of entries => ignore the last
9770 10333
9771 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10334 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9772 switch (type) { 10335 switch (type)
10336 {
9773 case ScriptBaseClass.CAMERA_FOCUS: 10337 case ScriptBaseClass.CAMERA_FOCUS:
9774 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10338 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9775 case ScriptBaseClass.CAMERA_POSITION: 10339 case ScriptBaseClass.CAMERA_POSITION:
@@ -9805,12 +10369,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 10369
9806 // we need the permission first, to know which avatar we want to clear the camera for 10370 // we need the permission first, to know which avatar we want to clear the camera for
9807 UUID agentID; 10371 UUID agentID;
9808 lock (m_host.TaskInventory) 10372 m_host.TaskInventory.LockItemsForRead(true);
10373 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10374 if (agentID == UUID.Zero)
10375 {
10376 m_host.TaskInventory.LockItemsForRead(false);
10377 return;
10378 }
10379 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9809 { 10380 {
9810 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10381 m_host.TaskInventory.LockItemsForRead(false);
9811 if (agentID == UUID.Zero) return; 10382 return;
9812 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9813 } 10383 }
10384 m_host.TaskInventory.LockItemsForRead(false);
9814 10385
9815 ScenePresence presence = World.GetScenePresence(agentID); 10386 ScenePresence presence = World.GetScenePresence(agentID);
9816 10387
@@ -9877,19 +10448,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9877 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10448 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9878 { 10449 {
9879 m_host.AddScriptLPS(1); 10450 m_host.AddScriptLPS(1);
9880 string ret = String.Empty; 10451
9881 string src1 = llBase64ToString(str1); 10452 if (str1 == String.Empty)
9882 string src2 = llBase64ToString(str2); 10453 return String.Empty;
9883 int c = 0; 10454 if (str2 == String.Empty)
9884 for (int i = 0; i < src1.Length; i++) 10455 return str1;
10456
10457 int len = str2.Length;
10458 if ((len % 4) != 0) // LL is EVIL!!!!
10459 {
10460 while (str2.EndsWith("="))
10461 str2 = str2.Substring(0, str2.Length - 1);
10462
10463 len = str2.Length;
10464 int mod = len % 4;
10465
10466 if (mod == 1)
10467 str2 = str2.Substring(0, str2.Length - 1);
10468 else if (mod == 2)
10469 str2 += "==";
10470 else if (mod == 3)
10471 str2 += "=";
10472 }
10473
10474 byte[] data1;
10475 byte[] data2;
10476 try
10477 {
10478 data1 = Convert.FromBase64String(str1);
10479 data2 = Convert.FromBase64String(str2);
10480 }
10481 catch (Exception)
10482 {
10483 return new LSL_String(String.Empty);
10484 }
10485
10486 byte[] d2 = new Byte[data1.Length];
10487 int pos = 0;
10488
10489 if (data1.Length <= data2.Length)
9885 { 10490 {
9886 ret += (char) (src1[i] ^ src2[c]); 10491 Array.Copy(data2, 0, d2, 0, data1.Length);
10492 }
10493 else
10494 {
10495 while (pos < data1.Length)
10496 {
10497 len = data1.Length - pos;
10498 if (len > data2.Length)
10499 len = data2.Length;
9887 10500
9888 c++; 10501 Array.Copy(data2, 0, d2, pos, len);
9889 if (c >= src2.Length) 10502 pos += len;
9890 c = 0; 10503 }
9891 } 10504 }
9892 return llStringToBase64(ret); 10505
10506 for (pos = 0 ; pos < data1.Length ; pos++ )
10507 data1[pos] ^= d2[pos];
10508
10509 return Convert.ToBase64String(data1);
9893 } 10510 }
9894 10511
9895 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10512 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9946,12 +10563,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9946 Regex r = new Regex(authregex); 10563 Regex r = new Regex(authregex);
9947 int[] gnums = r.GetGroupNumbers(); 10564 int[] gnums = r.GetGroupNumbers();
9948 Match m = r.Match(url); 10565 Match m = r.Match(url);
9949 if (m.Success) { 10566 if (m.Success)
9950 for (int i = 1; i < gnums.Length; i++) { 10567 {
10568 for (int i = 1; i < gnums.Length; i++)
10569 {
9951 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10570 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9952 //CaptureCollection cc = g.Captures; 10571 //CaptureCollection cc = g.Captures;
9953 } 10572 }
9954 if (m.Groups.Count == 5) { 10573 if (m.Groups.Count == 5)
10574 {
9955 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10575 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9956 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10576 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9957 } 10577 }
@@ -10237,15 +10857,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10237 10857
10238 internal UUID ScriptByName(string name) 10858 internal UUID ScriptByName(string name)
10239 { 10859 {
10240 lock (m_host.TaskInventory) 10860 m_host.TaskInventory.LockItemsForRead(true);
10861
10862 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10241 { 10863 {
10242 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10864 if (item.Type == 10 && item.Name == name)
10243 { 10865 {
10244 if (item.Type == 10 && item.Name == name) 10866 m_host.TaskInventory.LockItemsForRead(false);
10245 return item.ItemID; 10867 return item.ItemID;
10246 } 10868 }
10247 } 10869 }
10248 10870
10871 m_host.TaskInventory.LockItemsForRead(false);
10872
10249 return UUID.Zero; 10873 return UUID.Zero;
10250 } 10874 }
10251 10875
@@ -10286,6 +10910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10286 { 10910 {
10287 m_host.AddScriptLPS(1); 10911 m_host.AddScriptLPS(1);
10288 10912
10913 //Clone is thread safe
10289 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10914 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10290 10915
10291 UUID assetID = UUID.Zero; 10916 UUID assetID = UUID.Zero;
@@ -10348,6 +10973,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10348 { 10973 {
10349 m_host.AddScriptLPS(1); 10974 m_host.AddScriptLPS(1);
10350 10975
10976 //Clone is thread safe
10351 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10977 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10352 10978
10353 UUID assetID = UUID.Zero; 10979 UUID assetID = UUID.Zero;
@@ -10428,15 +11054,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10428 return GetLinkPrimitiveParams(obj, rules); 11054 return GetLinkPrimitiveParams(obj, rules);
10429 } 11055 }
10430 11056
10431 public void print(string str) 11057 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10432 { 11058 {
10433 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11059 List<SceneObjectPart> parts = GetLinkParts(link);
10434 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11060 if (parts.Count < 1)
10435 if (ossl != null) 11061 return 0;
10436 { 11062
10437 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11063 return GetNumberOfSides(parts[0]);
10438 m_log.Info("LSL print():" + str);
10439 }
10440 } 11064 }
10441 11065
10442 private string Name2Username(string name) 11066 private string Name2Username(string name)
@@ -10482,153 +11106,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10482 return rq.ToString(); 11106 return rq.ToString();
10483 } 11107 }
10484 11108
11109 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11110 {
11111 m_SayShoutCount = 0;
11112 }
11113
11114 private struct Tri
11115 {
11116 public Vector3 p1;
11117 public Vector3 p2;
11118 public Vector3 p3;
11119 }
11120
11121 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11122 {
11123 float height = avatar.Appearance.AvatarHeight;
11124 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11125 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11126
11127 if (point.X > b1.X && point.X < b2.X &&
11128 point.Y > b1.Y && point.Y < b2.Y &&
11129 point.Z > b1.Z && point.Z < b2.Z)
11130 return true;
11131 return false;
11132 }
11133
11134 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11135 {
11136 List<ContactResult> contacts = new List<ContactResult>();
11137
11138 Vector3 ab = rayEnd - rayStart;
11139
11140 World.ForEachScenePresence(delegate(ScenePresence sp)
11141 {
11142 Vector3 ac = sp.AbsolutePosition - rayStart;
11143 Vector3 bc = sp.AbsolutePosition - rayEnd;
11144
11145 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11146
11147 if (d > 1.5)
11148 return;
11149
11150 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11151
11152 if (d2 > 0)
11153 return;
11154
11155 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11156 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11157
11158 if (!InBoundingBox(sp, p))
11159 return;
11160
11161 ContactResult result = new ContactResult ();
11162 result.ConsumerID = sp.LocalId;
11163 result.Depth = Vector3.Distance(rayStart, p);
11164 result.Normal = Vector3.Zero;
11165 result.Pos = p;
11166
11167 contacts.Add(result);
11168 });
11169
11170 return contacts.ToArray();
11171 }
11172
11173 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11174 {
11175 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11176 List<ContactResult> contacts = new List<ContactResult>();
11177
11178 Vector3 ab = rayEnd - rayStart;
11179
11180 World.ForEachSOG(delegate(SceneObjectGroup group)
11181 {
11182 if (m_host.ParentGroup == group)
11183 return;
11184
11185 if (group.IsAttachment)
11186 return;
11187
11188 if (group.RootPart.PhysActor == null)
11189 {
11190 if (!includePhantom)
11191 return;
11192 }
11193 else
11194 {
11195 if (group.RootPart.PhysActor.IsPhysical)
11196 {
11197 if (!includePhysical)
11198 return;
11199 }
11200 else
11201 {
11202 if (!includeNonPhysical)
11203 return;
11204 }
11205 }
11206
11207 // Find the radius ouside of which we don't even need to hit test
11208 float minX;
11209 float maxX;
11210 float minY;
11211 float maxY;
11212 float minZ;
11213 float maxZ;
11214
11215 float radius = 0.0f;
11216
11217 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11218
11219 if (Math.Abs(minX) > radius)
11220 radius = Math.Abs(minX);
11221 if (Math.Abs(minY) > radius)
11222 radius = Math.Abs(minY);
11223 if (Math.Abs(minZ) > radius)
11224 radius = Math.Abs(minZ);
11225 if (Math.Abs(maxX) > radius)
11226 radius = Math.Abs(maxX);
11227 if (Math.Abs(maxY) > radius)
11228 radius = Math.Abs(maxY);
11229 if (Math.Abs(maxZ) > radius)
11230 radius = Math.Abs(maxZ);
11231
11232 Vector3 ac = group.AbsolutePosition - rayStart;
11233 Vector3 bc = group.AbsolutePosition - rayEnd;
11234
11235 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11236
11237 // Too far off ray, don't bother
11238 if (d > radius)
11239 return;
11240
11241 // Behind ray, drop
11242 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11243 if (d2 > 0)
11244 return;
11245
11246 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11247 // Miss.
11248 if (!intersection.HitTF)
11249 return;
11250
11251 ContactResult result = new ContactResult ();
11252 result.ConsumerID = group.LocalId;
11253 result.Depth = intersection.distance;
11254 result.Normal = intersection.normal;
11255 result.Pos = intersection.ipoint;
11256
11257 contacts.Add(result);
11258 });
11259
11260 return contacts.ToArray();
11261 }
11262
11263 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11264 {
11265 double[,] heightfield = World.Heightmap.GetDoubles();
11266 List<ContactResult> contacts = new List<ContactResult>();
11267
11268 double min = 2048.0;
11269 double max = 0.0;
11270
11271 // Find the min and max of the heightfield
11272 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11273 {
11274 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11275 {
11276 if (heightfield[x, y] > max)
11277 max = heightfield[x, y];
11278 if (heightfield[x, y] < min)
11279 min = heightfield[x, y];
11280 }
11281 }
11282
11283
11284 // A ray extends past rayEnd, but doesn't go back before
11285 // rayStart. If the start is above the highest point of the ground
11286 // and the ray goes up, we can't hit the ground. Ever.
11287 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11288 return null;
11289
11290 // Same for going down
11291 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11292 return null;
11293
11294 List<Tri> trilist = new List<Tri>();
11295
11296 // Create our triangle list
11297 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11298 {
11299 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11300 {
11301 Tri t1 = new Tri();
11302 Tri t2 = new Tri();
11303
11304 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11305 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11306 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11307 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11308
11309 t1.p1 = p1;
11310 t1.p2 = p2;
11311 t1.p3 = p3;
11312
11313 t2.p1 = p3;
11314 t2.p2 = p4;
11315 t2.p3 = p1;
11316
11317 trilist.Add(t1);
11318 trilist.Add(t2);
11319 }
11320 }
11321
11322 // Ray direction
11323 Vector3 rayDirection = rayEnd - rayStart;
11324
11325 foreach (Tri t in trilist)
11326 {
11327 // Compute triangle plane normal and edges
11328 Vector3 u = t.p2 - t.p1;
11329 Vector3 v = t.p3 - t.p1;
11330 Vector3 n = Vector3.Cross(u, v);
11331
11332 if (n == Vector3.Zero)
11333 continue;
11334
11335 Vector3 w0 = rayStart - t.p1;
11336 double a = -Vector3.Dot(n, w0);
11337 double b = Vector3.Dot(n, rayDirection);
11338
11339 // Not intersecting the plane, or in plane (same thing)
11340 // Ignoring this MAY cause the ground to not be detected
11341 // sometimes
11342 if (Math.Abs(b) < 0.000001)
11343 continue;
11344
11345 double r = a / b;
11346
11347 // ray points away from plane
11348 if (r < 0.0)
11349 continue;
11350
11351 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11352
11353 float uu = Vector3.Dot(u, u);
11354 float uv = Vector3.Dot(u, v);
11355 float vv = Vector3.Dot(v, v);
11356 Vector3 w = ip - t.p1;
11357 float wu = Vector3.Dot(w, u);
11358 float wv = Vector3.Dot(w, v);
11359 float d = uv * uv - uu * vv;
11360
11361 float cs = (uv * wv - vv * wu) / d;
11362 if (cs < 0 || cs > 1.0)
11363 continue;
11364 float ct = (uv * wu - uu * wv) / d;
11365 if (ct < 0 || (cs + ct) > 1.0)
11366 continue;
11367
11368 // Add contact point
11369 ContactResult result = new ContactResult ();
11370 result.ConsumerID = 0;
11371 result.Depth = Vector3.Distance(rayStart, ip);
11372 result.Normal = n;
11373 result.Pos = ip;
11374
11375 contacts.Add(result);
11376 }
11377
11378 if (contacts.Count == 0)
11379 return null;
11380
11381 contacts.Sort(delegate(ContactResult a, ContactResult b)
11382 {
11383 return (int)(a.Depth - b.Depth);
11384 });
11385
11386 return contacts[0];
11387 }
11388
10485 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11389 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10486 { 11390 {
11391 LSL_List list = new LSL_List();
11392
10487 m_host.AddScriptLPS(1); 11393 m_host.AddScriptLPS(1);
10488 11394
10489 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11395 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10490 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11396 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10491 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11397 Vector3 dir = rayEnd - rayStart;
10492 11398
10493 int count = 0; 11399 int count = 1;
10494// int detectPhantom = 0; 11400 bool detectPhantom = false;
10495 int dataFlags = 0; 11401 int dataFlags = 0;
10496 int rejectTypes = 0; 11402 int rejectTypes = 0;
10497 11403
10498 for (int i = 0; i < options.Length; i += 2) 11404 for (int i = 0; i < options.Length; i += 2)
10499 { 11405 {
10500 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11406 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10501 {
10502 count = options.GetLSLIntegerItem(i + 1); 11407 count = options.GetLSLIntegerItem(i + 1);
10503 } 11408 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10504// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11409 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10505// {
10506// detectPhantom = options.GetLSLIntegerItem(i + 1);
10507// }
10508 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11410 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10509 {
10510 dataFlags = options.GetLSLIntegerItem(i + 1); 11411 dataFlags = options.GetLSLIntegerItem(i + 1);
10511 }
10512 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11412 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10513 {
10514 rejectTypes = options.GetLSLIntegerItem(i + 1); 11413 rejectTypes = options.GetLSLIntegerItem(i + 1);
10515 }
10516 } 11414 }
10517 11415
10518 LSL_List list = new LSL_List(); 11416 if (count > 16)
10519 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11417 count = 16;
10520 11418
10521 double distance = Util.GetDistanceTo(startvector, endvector); 11419 List<ContactResult> results = new List<ContactResult>();
10522
10523 if (distance == 0)
10524 distance = 0.001;
10525
10526 Vector3 posToCheck = startvector;
10527 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10528 11420
10529 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11421 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10530 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11422 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10531 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11423 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10532 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11424 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10533 11425
10534 for (float i = 0; i <= distance; i += 0.1f) 11426 if (checkTerrain)
10535 { 11427 {
10536 posToCheck = startvector + (dir * (i / (float)distance)); 11428 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11429 if (groundContact != null)
11430 results.Add((ContactResult)groundContact);
11431 }
10537 11432
10538 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11433 if (checkAgents)
10539 { 11434 {
10540 ContactResult result = new ContactResult(); 11435 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10541 result.ConsumerID = 0; 11436 foreach (ContactResult r in agentHits)
10542 result.Depth = 0; 11437 results.Add(r);
10543 result.Normal = Vector3.Zero; 11438 }
10544 result.Pos = posToCheck;
10545 results.Add(result);
10546 checkTerrain = false;
10547 }
10548 11439
10549 if (checkAgents) 11440 if (checkPhysical || checkNonPhysical)
10550 { 11441 {
10551 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11442 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10552 { 11443 foreach (ContactResult r in objectHits)
10553 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11444 results.Add(r);
10554 {
10555 ContactResult result = new ContactResult ();
10556 result.ConsumerID = sp.LocalId;
10557 result.Depth = 0;
10558 result.Normal = Vector3.Zero;
10559 result.Pos = posToCheck;
10560 results.Add(result);
10561 }
10562 });
10563 }
10564 } 11445 }
10565 11446
10566 int refcount = 0; 11447 results.Sort(delegate(ContactResult a, ContactResult b)
11448 {
11449 return (int)(a.Depth - b.Depth);
11450 });
11451
11452 int values = 0;
10567 foreach (ContactResult result in results) 11453 foreach (ContactResult result in results)
10568 { 11454 {
10569 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11455 UUID itemID = UUID.Zero;
10570 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11456 int linkNum = 0;
10571 continue;
10572
10573 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10574
10575 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10576 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10577 11457
10578 if (entity == null) 11458 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11459 // It's a prim!
11460 if (part != null)
10579 { 11461 {
10580 list.Add(UUID.Zero); 11462 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10581 11463 itemID = part.ParentGroup.UUID;
10582 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11464 else
10583 list.Add(0); 11465 itemID = part.UUID;
10584
10585 list.Add(result.Pos);
10586
10587 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10588 list.Add(result.Normal);
10589 11466
10590 continue; //Can't find it, so add UUID.Zero 11467 linkNum = part.LinkNum;
10591 } 11468 }
10592 11469 else
10593 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10594 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10595 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10596
10597 if (entity is SceneObjectPart)
10598 { 11470 {
10599 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11471 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10600 { 11472 /// It it a boy? a girl?
10601 if (!checkPhysical) 11473 if (sp != null)
10602 continue; 11474 itemID = sp.UUID;
10603 }
10604 else
10605 {
10606 if (!checkNonPhysical)
10607 continue;
10608 }
10609 } 11475 }
10610 11476
10611 refcount++; 11477 list.Add(new LSL_String(itemID.ToString()));
10612 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11478 list.Add(new LSL_String(result.Pos.ToString()));
10613 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10614 else
10615 list.Add(entity.UUID);
10616 11479
10617 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11480 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10618 { 11481 list.Add(new LSL_Integer(linkNum));
10619 if (entity is SceneObjectPart)
10620 list.Add(((SceneObjectPart)entity).LinkNum);
10621 else
10622 list.Add(0);
10623 }
10624 11482
10625 list.Add(result.Pos);
10626 11483
10627 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11484 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10628 list.Add(result.Normal); 11485 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11486
11487 values++;
11488 count--;
11489
11490 if (count == 0)
11491 break;
10629 } 11492 }
10630 11493
10631 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11494 list.Add(new LSL_Integer(values));
10632 11495
10633 return list; 11496 return list;
10634 } 11497 }
@@ -10651,22 +11514,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 NotImplemented("llGetSPMaxMemory"); 11514 NotImplemented("llGetSPMaxMemory");
10652 } 11515 }
10653 11516
10654 public void llGetUsedMemory() 11517 public virtual LSL_Integer llGetUsedMemory()
10655 { 11518 {
10656 m_host.AddScriptLPS(1); 11519 m_host.AddScriptLPS(1);
10657 NotImplemented("llGetUsedMemory"); 11520 NotImplemented("llGetUsedMemory");
11521 return 0;
10658 } 11522 }
10659 11523
10660 public void llScriptProfiler(LSL_Integer flags) 11524 public void llScriptProfiler(LSL_Integer flags)
10661 { 11525 {
10662 m_host.AddScriptLPS(1); 11526 m_host.AddScriptLPS(1);
10663 NotImplemented("llScriptProfiler"); 11527 //NotImplemented("llScriptProfiler");
10664 } 11528 }
10665 11529
10666 public void llSetSoundQueueing(int queue) 11530 public void llSetSoundQueueing(int queue)
10667 { 11531 {
10668 m_host.AddScriptLPS(1); 11532 m_host.AddScriptLPS(1);
10669 NotImplemented("llSetSoundQueueing");
10670 } 11533 }
10671 11534
10672 public void llCollisionSprite(string impact_sprite) 11535 public void llCollisionSprite(string impact_sprite)
@@ -10678,7 +11541,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10678 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11541 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10679 { 11542 {
10680 m_host.AddScriptLPS(1); 11543 m_host.AddScriptLPS(1);
10681 NotImplemented("llGodLikeRezObject"); 11544
11545 if (!World.Permissions.IsGod(m_host.OwnerID))
11546 NotImplemented("llGodLikeRezObject");
11547
11548 AssetBase rezAsset = World.AssetService.Get(inventory);
11549 if (rezAsset == null)
11550 {
11551 llSay(0, "Asset not found");
11552 return;
11553 }
11554
11555 SceneObjectGroup group = null;
11556
11557 try
11558 {
11559 string xmlData = Utils.BytesToString(rezAsset.Data);
11560 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11561 }
11562 catch
11563 {
11564 llSay(0, "Asset not found");
11565 return;
11566 }
11567
11568 if (group == null)
11569 {
11570 llSay(0, "Asset not found");
11571 return;
11572 }
11573
11574 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11575 group.RootPart.AttachOffset = group.AbsolutePosition;
11576
11577 group.ResetIDs();
11578
11579 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11580 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11581 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11582 group.ScheduleGroupForFullUpdate();
11583
11584 // objects rezzed with this method are die_at_edge by default.
11585 group.RootPart.SetDieAtEdge(true);
11586
11587 group.ResumeScripts();
11588
11589 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11590 "object_rez", new Object[] {
11591 new LSL_String(
11592 group.RootPart.UUID.ToString()) },
11593 new DetectParams[0]));
11594 }
11595
11596 public LSL_String llTransferLindenDollars(string destination, int amount)
11597 {
11598 UUID txn = UUID.Random();
11599
11600 Util.FireAndForget(delegate(object x)
11601 {
11602 int replycode = 0;
11603 string replydata = destination + "," + amount.ToString();
11604
11605 try
11606 {
11607 UUID invItemID=InventorySelf();
11608 if (invItemID == UUID.Zero)
11609 {
11610 replydata = "SERVICE_ERROR";
11611 return;
11612 }
11613
11614 m_host.AddScriptLPS(1);
11615
11616 m_host.TaskInventory.LockItemsForRead(true);
11617 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11618 m_host.TaskInventory.LockItemsForRead(false);
11619
11620 if (item.PermsGranter == UUID.Zero)
11621 {
11622 replydata = "MISSING_PERMISSION_DEBIT";
11623 return;
11624 }
11625
11626 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11627 {
11628 replydata = "MISSING_PERMISSION_DEBIT";
11629 return;
11630 }
11631
11632 UUID toID = new UUID();
11633
11634 if (!UUID.TryParse(destination, out toID))
11635 {
11636 replydata = "INVALID_AGENT";
11637 return;
11638 }
11639
11640 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11641
11642 if (money == null)
11643 {
11644 replydata = "TRANSFERS_DISABLED";
11645 return;
11646 }
11647
11648 bool result = money.ObjectGiveMoney(
11649 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11650
11651 if (result)
11652 {
11653 replycode = 1;
11654 return;
11655 }
11656
11657 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11658 }
11659 finally
11660 {
11661 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11662 "transaction_result", new Object[] {
11663 new LSL_String(txn.ToString()),
11664 new LSL_Integer(replycode),
11665 new LSL_String(replydata) },
11666 new DetectParams[0]));
11667 }
11668 });
11669
11670 return txn.ToString();
10682 } 11671 }
10683 11672
10684 #endregion 11673 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index fc478ab..ca340c6 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()
@@ -912,18 +921,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
912 if (target != null) 921 if (target != null)
913 { 922 {
914 UUID animID=UUID.Zero; 923 UUID animID=UUID.Zero;
915 lock (m_host.TaskInventory) 924 m_host.TaskInventory.LockItemsForRead(true);
925 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
916 { 926 {
917 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 927 if (inv.Value.Name == animation)
918 { 928 {
919 if (inv.Value.Name == animation) 929 if (inv.Value.Type == (int)AssetType.Animation)
920 { 930 animID = inv.Value.AssetID;
921 if (inv.Value.Type == (int)AssetType.Animation) 931 continue;
922 animID = inv.Value.AssetID;
923 continue;
924 }
925 } 932 }
926 } 933 }
934 m_host.TaskInventory.LockItemsForRead(false);
927 if (animID == UUID.Zero) 935 if (animID == UUID.Zero)
928 target.Animator.AddAnimation(animation, m_host.UUID); 936 target.Animator.AddAnimation(animation, m_host.UUID);
929 else 937 else
@@ -950,18 +958,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
950 if (target != null) 958 if (target != null)
951 { 959 {
952 UUID animID = UUID.Zero; 960 UUID animID = UUID.Zero;
953 lock (m_host.TaskInventory) 961 m_host.TaskInventory.LockItemsForRead(true);
962 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
954 { 963 {
955 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 964 if (inv.Value.Name == animation)
956 { 965 {
957 if (inv.Value.Name == animation) 966 if (inv.Value.Type == (int)AssetType.Animation)
958 { 967 animID = inv.Value.AssetID;
959 if (inv.Value.Type == (int)AssetType.Animation) 968 continue;
960 animID = inv.Value.AssetID;
961 continue;
962 }
963 } 969 }
964 } 970 }
971 m_host.TaskInventory.LockItemsForRead(false);
965 972
966 if (animID == UUID.Zero) 973 if (animID == UUID.Zero)
967 target.Animator.RemoveAnimation(animation); 974 target.Animator.RemoveAnimation(animation);
@@ -1792,6 +1799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1799
1793 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1800 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1794 { 1801 {
1802 m_host.TaskInventory.LockItemsForRead(true);
1795 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1803 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1796 { 1804 {
1797 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1805 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1799,6 +1807,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 assetID = item.AssetID; 1807 assetID = item.AssetID;
1800 } 1808 }
1801 } 1809 }
1810 m_host.TaskInventory.LockItemsForRead(false);
1802 } 1811 }
1803 1812
1804 if (assetID == UUID.Zero) 1813 if (assetID == UUID.Zero)
@@ -2101,18 +2110,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2101 2110
2102 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned) 2111 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned)
2103 { 2112 {
2113 if (!owned)
2114 OSSLError("Unowned NPCs are unsupported");
2115
2116 string groupTitle = String.Empty;
2117
2118 if (firstname != String.Empty || lastname != String.Empty)
2119 {
2120 if (firstname != "Shown outfit:")
2121 groupTitle = "- NPC -";
2122 }
2123
2104 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2124 INPCModule module = World.RequestModuleInterface<INPCModule>();
2105 if (module != null) 2125 if (module != null)
2106 { 2126 {
2107 AvatarAppearance appearance = null; 2127 AvatarAppearance appearance = null;
2108 2128
2109 UUID id; 2129// UUID id;
2110 if (UUID.TryParse(notecard, out id)) 2130// if (UUID.TryParse(notecard, out id))
2111 { 2131// {
2112 ScenePresence clonePresence = World.GetScenePresence(id); 2132// ScenePresence clonePresence = World.GetScenePresence(id);
2113 if (clonePresence != null) 2133// if (clonePresence != null)
2114 appearance = clonePresence.Appearance; 2134// appearance = clonePresence.Appearance;
2115 } 2135// }
2116 2136
2117 if (appearance == null) 2137 if (appearance == null)
2118 { 2138 {
@@ -2138,6 +2158,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2138 ownerID, 2158 ownerID,
2139 World,appearance); 2159 World,appearance);
2140 2160
2161 ScenePresence sp;
2162 if (World.TryGetScenePresence(x, out sp))
2163 {
2164 sp.Grouptitle = groupTitle;
2165 sp.SendAvatarDataToAllAgents();
2166 }
2141 return new LSL_Key(x.ToString()); 2167 return new LSL_Key(x.ToString());
2142 } 2168 }
2143 2169
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 8356dce..dddf913 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -209,7 +209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
209 // Is the sensor type is AGENT and not SCRIPTED then include agents 209 // Is the sensor type is AGENT and not SCRIPTED then include agents
210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
211 { 211 {
212 sensedEntities.AddRange(doAgentSensor(ts)); 212 sensedEntities.AddRange(doAgentSensor(ts));
213 } 213 }
214 214
215 // If SCRIPTED or PASSIVE or ACTIVE check objects 215 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -306,13 +306,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
306 float dy; 306 float dy;
307 float dz; 307 float dz;
308 308
309 Quaternion q = SensePoint.RotationOffset; 309// Quaternion q = SensePoint.RotationOffset;
310 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
310 if (SensePoint.ParentGroup.IsAttachment) 311 if (SensePoint.ParentGroup.IsAttachment)
311 { 312 {
312 // In attachments, the sensor cone always orients with the 313 // In attachments, the sensor cone always orients with the
313 // avatar rotation. This may include a nonzero elevation if 314 // avatar rotation. This may include a nonzero elevation if
314 // in mouselook. 315 // in mouselook.
315 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 316 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
317 fromRegionPos = avatar.AbsolutePosition;
316 q = avatar.Rotation; 318 q = avatar.Rotation;
317 } 319 }
318 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 320 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -435,6 +437,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
435 // avatar rotation. This may include a nonzero elevation if 437 // avatar rotation. This may include a nonzero elevation if
436 // in mouselook. 438 // in mouselook.
437 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 439 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
440 if (avatar == null)
441 return sensedEntities;
442 fromRegionPos = avatar.AbsolutePosition;
438 q = avatar.Rotation; 443 q = avatar.Rotation;
439 } 444 }
440 445
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
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 62e2854..e0027b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -199,6 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
199 void llGiveInventory(string destination, string inventory); 200 void llGiveInventory(string destination, string inventory);
200 void llGiveInventoryList(string destination, string category, LSL_List inventory); 201 void llGiveInventoryList(string destination, string category, LSL_List inventory);
201 LSL_Integer llGiveMoney(string destination, int amount); 202 LSL_Integer llGiveMoney(string destination, int amount);
203 LSL_String llTransferLindenDollars(string destination, int amount);
202 void llGodLikeRezObject(string inventory, LSL_Vector pos); 204 void llGodLikeRezObject(string inventory, LSL_Vector pos);
203 LSL_Float llGround(LSL_Vector offset); 205 LSL_Float llGround(LSL_Vector offset);
204 LSL_Vector llGroundContour(LSL_Vector offset); 206 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -405,7 +407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 407 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 408 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 409 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 410 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 411
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 413 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index af6be5f..403e491 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 176dc56..32226f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -282,6 +282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 283 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 284 public const int CHANGED_ANIMATION = 16384;
285 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 286 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 287 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 288 public const int TYPE_FLOAT = 2;
@@ -378,6 +379,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
378 public const int PRIM_SCULPT_TYPE_TORUS = 2; 379 public const int PRIM_SCULPT_TYPE_TORUS = 2;
379 public const int PRIM_SCULPT_TYPE_PLANE = 3; 380 public const int PRIM_SCULPT_TYPE_PLANE = 3;
380 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 381 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
382 public const int PRIM_SCULPT_FLAG_INVERT = 64;
383 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
381 384
382 public const int MASK_BASE = 0; 385 public const int MASK_BASE = 0;
383 public const int MASK_OWNER = 1; 386 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..231cd7e 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();
@@ -839,6 +851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
839 return m_LSL_Functions.llGiveMoney(destination, amount); 851 return m_LSL_Functions.llGiveMoney(destination, amount);
840 } 852 }
841 853
854 public LSL_String llTransferLindenDollars(string destination, int amount)
855 {
856 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
857 }
858
842 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 859 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
843 { 860 {
844 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 861 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1878,9 +1895,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1895 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1896 }
1880 1897
1881 public void print(string str) 1898 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1899 {
1883 m_LSL_Functions.print(str); 1900 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1901 }
1885 } 1902 }
1886} 1903}
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 f9d6eee..9ff2e4d 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;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -263,13 +264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
263 264
264 if (part != null) 265 if (part != null)
265 { 266 {
266 lock (part.TaskInventory) 267 part.TaskInventory.LockItemsForRead(true);
268 if (part.TaskInventory.ContainsKey(m_ItemID))
267 { 269 {
268 if (part.TaskInventory.ContainsKey(m_ItemID)) 270 m_thisScriptTask = part.TaskInventory[m_ItemID];
269 {
270 m_thisScriptTask = part.TaskInventory[m_ItemID];
271 }
272 } 271 }
272 part.TaskInventory.LockItemsForRead(false);
273 } 273 }
274 274
275 ApiManager am = new ApiManager(); 275 ApiManager am = new ApiManager();
@@ -296,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 297// lease.Register(this);
298 } 298 }
299 catch (Exception) 299 catch (Exception e)
300 { 300 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
302 } 303 }
303 304
304 try 305 try
@@ -459,14 +460,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
459 { 460 {
460 int permsMask; 461 int permsMask;
461 UUID permsGranter; 462 UUID permsGranter;
462 lock (part.TaskInventory) 463 part.TaskInventory.LockItemsForRead(true);
464 if (!part.TaskInventory.ContainsKey(m_ItemID))
463 { 465 {
464 if (!part.TaskInventory.ContainsKey(m_ItemID)) 466 part.TaskInventory.LockItemsForRead(false);
465 return; 467 return;
466
467 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
468 permsMask = part.TaskInventory[m_ItemID].PermsMask;
469 } 468 }
469 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
470 permsMask = part.TaskInventory[m_ItemID].PermsMask;
471 part.TaskInventory.LockItemsForRead(false);
470 472
471 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 473 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 { 474 {
@@ -575,6 +577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 return true; 577 return true;
576 } 578 }
577 579
580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
578 public void SetState(string state) 581 public void SetState(string state)
579 { 582 {
580 if (state == State) 583 if (state == State)
@@ -586,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
586 new DetectParams[0])); 589 new DetectParams[0]));
587 PostEvent(new EventParams("state_entry", new Object[0], 590 PostEvent(new EventParams("state_entry", new Object[0],
588 new DetectParams[0])); 591 new DetectParams[0]));
589 592
590 throw new EventAbortException(); 593 throw new EventAbortException();
591 } 594 }
592 595
@@ -669,41 +672,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
669 /// <returns></returns> 672 /// <returns></returns>
670 public object EventProcessor() 673 public object EventProcessor()
671 { 674 {
672 lock (m_Script) 675 EventParams data = null;
673 {
674// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
675 676
676 if (Suspended) 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
677 return 0;
678 678
679 EventParams data = null; 679 if (Suspended)
680 return 0;
680 681
681 lock (m_EventQueue) 682 lock (m_EventQueue)
683 {
684 data = (EventParams) m_EventQueue.Dequeue();
685 if (data == null) // Shouldn't happen
682 { 686 {
683 data = (EventParams) m_EventQueue.Dequeue(); 687 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
684 if (data == null) // Shouldn't happen
685 { 688 {
686 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 689 m_CurrentResult = m_Engine.QueueEventHandler(this);
687 {
688 m_CurrentResult = m_Engine.QueueEventHandler(this);
689 }
690 else
691 {
692 m_CurrentResult = null;
693 }
694 return 0;
695 } 690 }
696 691 else
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 { 692 {
701 if (m_ControlEventsInQueue > 0) 693 m_CurrentResult = null;
702 m_ControlEventsInQueue--;
703 } 694 }
704 if (data.EventName == "collision") 695 return 0;
705 m_CollisionInQueue = false; 696 }
697
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 {
702 if (m_ControlEventsInQueue > 0)
703 m_ControlEventsInQueue--;
706 } 704 }
705 if (data.EventName == "collision")
706 m_CollisionInQueue = false;
707 }
708
709 lock(m_Script)
710 {
707 711
708// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 713
@@ -860,6 +864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 864 new Object[0], new DetectParams[0]));
861 } 865 }
862 866
867 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 868 public void ApiResetScript()
864 { 869 {
865 // bool running = Running; 870 // bool running = Running;
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 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..9e6752c 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 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {