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.cs2800
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs78
-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, 2348 insertions, 1013 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..7af5d2d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -156,6 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
156 get { return m_ScriptEngine.World; } 170 get { return m_ScriptEngine.World; }
157 } 171 }
158 172
173 [DebuggerNonUserCode]
159 public void state(string newState) 174 public void state(string newState)
160 { 175 {
161 m_ScriptEngine.SetState(m_itemID, newState); 176 m_ScriptEngine.SetState(m_itemID, newState);
@@ -165,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
165 /// Reset the named script. The script must be present 180 /// Reset the named script. The script must be present
166 /// in the same prim. 181 /// in the same prim.
167 /// </summary> 182 /// </summary>
183 [DebuggerNonUserCode]
168 public void llResetScript() 184 public void llResetScript()
169 { 185 {
170 m_host.AddScriptLPS(1); 186 m_host.AddScriptLPS(1);
@@ -221,9 +237,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 } 237 }
222 } 238 }
223 239
240 public List<ScenePresence> GetLinkAvatars(int linkType)
241 {
242 List<ScenePresence> ret = new List<ScenePresence>();
243 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
244 return ret;
245
246 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
247
248 switch (linkType)
249 {
250 case ScriptBaseClass.LINK_SET:
251 return avs;
252
253 case ScriptBaseClass.LINK_ROOT:
254 return ret;
255
256 case ScriptBaseClass.LINK_ALL_OTHERS:
257 return avs;
258
259 case ScriptBaseClass.LINK_ALL_CHILDREN:
260 return avs;
261
262 case ScriptBaseClass.LINK_THIS:
263 return ret;
264
265 default:
266 if (linkType < 0)
267 return ret;
268
269 int partCount = m_host.ParentGroup.GetPartCount();
270
271 if (linkType <= partCount)
272 {
273 return ret;
274 }
275 else
276 {
277 linkType = linkType - partCount;
278 if (linkType > avs.Count)
279 {
280 return ret;
281 }
282 else
283 {
284 ret.Add(avs[linkType-1]);
285 return ret;
286 }
287 }
288 }
289 }
290
224 public List<SceneObjectPart> GetLinkParts(int linkType) 291 public List<SceneObjectPart> GetLinkParts(int linkType)
225 { 292 {
226 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 293 List<SceneObjectPart> ret = new List<SceneObjectPart>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
227 ret.Add(m_host); 296 ret.Add(m_host);
228 297
229 switch (linkType) 298 switch (linkType)
@@ -270,40 +339,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
270 protected UUID InventorySelf() 339 protected UUID InventorySelf()
271 { 340 {
272 UUID invItemID = new UUID(); 341 UUID invItemID = new UUID();
273 342 bool unlock = false;
274 lock (m_host.TaskInventory) 343 if (!m_host.TaskInventory.IsReadLockedByMe())
275 { 344 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
349 {
350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
277 { 351 {
278 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 352 invItemID = inv.Key;
279 { 353 break;
280 invItemID = inv.Key;
281 break;
282 }
283 } 354 }
284 } 355 }
285 356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
286 return invItemID; 360 return invItemID;
287 } 361 }
288 362
289 protected UUID InventoryKey(string name, int type) 363 protected UUID InventoryKey(string name, int type)
290 { 364 {
291 m_host.AddScriptLPS(1); 365 m_host.AddScriptLPS(1);
292 366 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 369 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 370 if (inv.Value.Name == name)
296 { 371 {
297 if (inv.Value.Name == name) 372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
298 { 375 {
299 if (inv.Value.Type != type) 376 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 377 }
378
379 return inv.Value.AssetID;
304 } 380 }
305 } 381 }
306 382
383 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 384 return UUID.Zero;
308 } 385 }
309 386
@@ -311,17 +388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 388 {
312 m_host.AddScriptLPS(1); 389 m_host.AddScriptLPS(1);
313 390
314 lock (m_host.TaskInventory) 391
392 m_host.TaskInventory.LockItemsForRead(true);
393
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 395 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 396 if (inv.Value.Name == name)
317 { 397 {
318 if (inv.Value.Name == name) 398 m_host.TaskInventory.LockItemsForRead(false);
319 { 399 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 400 }
323 } 401 }
324 402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
325 return UUID.Zero; 406 return UUID.Zero;
326 } 407 }
327 408
@@ -463,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 544
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 546
466 /// <summary> 547 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 548
468 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 550 protected double NormalizeAngle(double angle)
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
475 public LSL_Vector llRot2Euler(LSL_Rotation r)
476 { 551 {
477 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
478 554
479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 555 int numPis = (int)(Math.PI / angle);
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
481 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
482 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
483 double sin = v.x / m; 559 return remainder;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
485 double y = Math.Asin(sin); 561
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
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))); 563 {
488 double z = Math.Atan2(v.y, v.x); 564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
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)
@@ -2839,34 +3040,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3040 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3041 {
2841 m_host.AddScriptLPS(1); 3042 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from
2843 LSL_Vector from = llGetPos();
2844 3043
2845 // Work out the normalised vector from the source to the target 3044 // Get the normalized vector to the target
2846 LSL_Vector delta = llVecNorm(target - from); 3045 LSL_Vector d1 = llVecNorm(target - llGetPos());
2847 LSL_Vector angle = new LSL_Vector(0,0,0);
2848 3046
2849 // Calculate the yaw 3047 // Get the bearing (yaw)
2850 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3048 LSL_Vector a1 = new LSL_Vector(0,0,0);
2851 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3049 a1.z = llAtan2(d1.y, d1.x);
2852 3050
2853 // Calculate pitch 3051 // Get the elevation (pitch)
2854 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3052 LSL_Vector a2 = new LSL_Vector(0,0,0);
3053 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2855 3054
2856 // we need to convert from a vector describing 3055 LSL_Rotation r1 = llEuler2Rot(a1);
2857 // the angles of rotation in radians into rotation value 3056 LSL_Rotation r2 = llEuler2Rot(a2);
3057 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2858 3058
2859 LSL_Rotation rot = llEuler2Rot(angle); 3059 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2860
2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // set the rotation of the object, copy that behavior
2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 { 3060 {
2865 llSetRot(rot); 3061 // Do nothing if either value is 0 (this has been checked in SL)
3062 if (strength <= 0.0 || damping <= 0.0)
3063 return;
3064
3065 llSetRot(r3 * r2 * r1);
2866 } 3066 }
2867 else 3067 else
2868 { 3068 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3069 if (strength == 0)
3070 {
3071 llSetRot(r3 * r2 * r1);
3072 return;
3073 }
3074
3075 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2870 } 3076 }
2871 } 3077 }
2872 3078
@@ -2916,13 +3122,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3122 {
2917 TaskInventoryItem item; 3123 TaskInventoryItem item;
2918 3124
2919 lock (m_host.TaskInventory) 3125 m_host.TaskInventory.LockItemsForRead(true);
3126 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2920 { 3127 {
2921 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3128 m_host.TaskInventory.LockItemsForRead(false);
2922 return; 3129 return;
2923 else 3130 }
2924 item = m_host.TaskInventory[InventorySelf()]; 3131 else
3132 {
3133 item = m_host.TaskInventory[InventorySelf()];
2925 } 3134 }
3135 m_host.TaskInventory.LockItemsForRead(false);
2926 3136
2927 if (item.PermsGranter != UUID.Zero) 3137 if (item.PermsGranter != UUID.Zero)
2928 { 3138 {
@@ -2944,13 +3154,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 { 3154 {
2945 TaskInventoryItem item; 3155 TaskInventoryItem item;
2946 3156
3157 m_host.TaskInventory.LockItemsForRead(true);
2947 lock (m_host.TaskInventory) 3158 lock (m_host.TaskInventory)
2948 { 3159 {
3160
2949 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3161 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3162 {
3163 m_host.TaskInventory.LockItemsForRead(false);
2950 return; 3164 return;
3165 }
2951 else 3166 else
3167 {
2952 item = m_host.TaskInventory[InventorySelf()]; 3168 item = m_host.TaskInventory[InventorySelf()];
3169 }
2953 } 3170 }
3171 m_host.TaskInventory.LockItemsForRead(false);
2954 3172
2955 m_host.AddScriptLPS(1); 3173 m_host.AddScriptLPS(1);
2956 3174
@@ -2982,18 +3200,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2982 { 3200 {
2983 m_host.AddScriptLPS(1); 3201 m_host.AddScriptLPS(1);
2984 3202
2985// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2986// return;
2987
2988 TaskInventoryItem item; 3203 TaskInventoryItem item;
2989 3204
2990 lock (m_host.TaskInventory) 3205 m_host.TaskInventory.LockItemsForRead(true);
3206
3207 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2991 { 3208 {
2992 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3209 m_host.TaskInventory.LockItemsForRead(false);
2993 return; 3210 return;
2994 else
2995 item = m_host.TaskInventory[InventorySelf()];
2996 } 3211 }
3212 else
3213 {
3214 item = m_host.TaskInventory[InventorySelf()];
3215 }
3216
3217 m_host.TaskInventory.LockItemsForRead(false);
2997 3218
2998 if (item.PermsGranter != m_host.OwnerID) 3219 if (item.PermsGranter != m_host.OwnerID)
2999 return; 3220 return;
@@ -3019,13 +3240,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 3240
3020 TaskInventoryItem item; 3241 TaskInventoryItem item;
3021 3242
3022 lock (m_host.TaskInventory) 3243 m_host.TaskInventory.LockItemsForRead(true);
3244
3245 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3023 { 3246 {
3024 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3247 m_host.TaskInventory.LockItemsForRead(false);
3025 return; 3248 return;
3026 else
3027 item = m_host.TaskInventory[InventorySelf()];
3028 } 3249 }
3250 else
3251 {
3252 item = m_host.TaskInventory[InventorySelf()];
3253 }
3254 m_host.TaskInventory.LockItemsForRead(false);
3255
3029 3256
3030 if (item.PermsGranter != m_host.OwnerID) 3257 if (item.PermsGranter != m_host.OwnerID)
3031 return; 3258 return;
@@ -3072,6 +3299,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 3299
3073 public void llInstantMessage(string user, string message) 3300 public void llInstantMessage(string user, string message)
3074 { 3301 {
3302 UUID result;
3303 if (!UUID.TryParse(user, out result))
3304 {
3305 ShoutError("An invalid key was passed to llInstantMessage");
3306 ScriptSleep(2000);
3307 return;
3308 }
3309
3310
3075 m_host.AddScriptLPS(1); 3311 m_host.AddScriptLPS(1);
3076 3312
3077 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3313 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3086,14 +3322,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3086 UUID friendTransactionID = UUID.Random(); 3322 UUID friendTransactionID = UUID.Random();
3087 3323
3088 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3324 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3089 3325
3090 GridInstantMessage msg = new GridInstantMessage(); 3326 GridInstantMessage msg = new GridInstantMessage();
3091 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3327 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3092 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3328 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3093 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3329 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); 3330// 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()); 3331// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3096 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3332// DateTime dt = DateTime.UtcNow;
3333//
3334// // Ticks from UtcNow, but make it look like local. Evil, huh?
3335// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3336//
3337// try
3338// {
3339// // Convert that to the PST timezone
3340// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3341// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3342// }
3343// catch
3344// {
3345// // No logging here, as it could be VERY spammy
3346// }
3347//
3348// // And make it look local again to fool the unix time util
3349// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3350
3351 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3352
3097 //if (client != null) 3353 //if (client != null)
3098 //{ 3354 //{
3099 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3355 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3107,12 +3363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3107 msg.message = message.Substring(0, 1024); 3363 msg.message = message.Substring(0, 1024);
3108 else 3364 else
3109 msg.message = message; 3365 msg.message = message;
3110 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3366 msg.dialog = (byte)19; // MessageFromObject
3111 msg.fromGroup = false;// fromGroup; 3367 msg.fromGroup = false;// fromGroup;
3112 msg.offline = (byte)0; //offline; 3368 msg.offline = (byte)0; //offline;
3113 msg.ParentEstateID = 0; //ParentEstateID; 3369 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3114 msg.Position = new Vector3(m_host.AbsolutePosition); 3370 msg.Position = new Vector3(m_host.AbsolutePosition);
3115 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3371 msg.RegionID = World.RegionInfo.RegionID.Guid;
3116 msg.binaryBucket 3372 msg.binaryBucket
3117 = Util.StringToBytes256( 3373 = Util.StringToBytes256(
3118 "{0}/{1}/{2}/{3}", 3374 "{0}/{1}/{2}/{3}",
@@ -3140,7 +3396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3140 } 3396 }
3141 3397
3142 emailModule.SendEmail(m_host.UUID, address, subject, message); 3398 emailModule.SendEmail(m_host.UUID, address, subject, message);
3143 ScriptSleep(20000); 3399 ScriptSleep(15000);
3144 } 3400 }
3145 3401
3146 public void llGetNextEmail(string address, string subject) 3402 public void llGetNextEmail(string address, string subject)
@@ -3279,14 +3535,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3279 3535
3280 TaskInventoryItem item; 3536 TaskInventoryItem item;
3281 3537
3282 lock (m_host.TaskInventory) 3538 m_host.TaskInventory.LockItemsForRead(true);
3539 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3283 { 3540 {
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3541 m_host.TaskInventory.LockItemsForRead(false);
3285 return; 3542 return;
3286 else
3287 item = m_host.TaskInventory[InventorySelf()];
3288 } 3543 }
3289 3544 else
3545 {
3546 item = m_host.TaskInventory[InventorySelf()];
3547 }
3548 m_host.TaskInventory.LockItemsForRead(false);
3290 if (item.PermsGranter == UUID.Zero) 3549 if (item.PermsGranter == UUID.Zero)
3291 return; 3550 return;
3292 3551
@@ -3316,13 +3575,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3316 3575
3317 TaskInventoryItem item; 3576 TaskInventoryItem item;
3318 3577
3319 lock (m_host.TaskInventory) 3578 m_host.TaskInventory.LockItemsForRead(true);
3579 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3320 { 3580 {
3321 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3581 m_host.TaskInventory.LockItemsForRead(false);
3322 return; 3582 return;
3323 else 3583 }
3324 item = m_host.TaskInventory[InventorySelf()]; 3584 else
3585 {
3586 item = m_host.TaskInventory[InventorySelf()];
3325 } 3587 }
3588 m_host.TaskInventory.LockItemsForRead(false);
3589
3326 3590
3327 if (item.PermsGranter == UUID.Zero) 3591 if (item.PermsGranter == UUID.Zero)
3328 return; 3592 return;
@@ -3389,10 +3653,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3653
3390 TaskInventoryItem item; 3654 TaskInventoryItem item;
3391 3655
3392 lock (m_host.TaskInventory) 3656
3657 m_host.TaskInventory.LockItemsForRead(true);
3658 if (!m_host.TaskInventory.ContainsKey(invItemID))
3659 {
3660 m_host.TaskInventory.LockItemsForRead(false);
3661 return;
3662 }
3663 else
3393 { 3664 {
3394 item = m_host.TaskInventory[invItemID]; 3665 item = m_host.TaskInventory[invItemID];
3395 } 3666 }
3667 m_host.TaskInventory.LockItemsForRead(false);
3396 3668
3397 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3669 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3398 { 3670 {
@@ -3420,15 +3692,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3692 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3421 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3693 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3422 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3694 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3695 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3423 ScriptBaseClass.PERMISSION_ATTACH; 3696 ScriptBaseClass.PERMISSION_ATTACH;
3424 3697
3425 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3698 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3426 { 3699 {
3427 lock (m_host.TaskInventory) 3700 m_host.TaskInventory.LockItemsForWrite(true);
3428 { 3701 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3429 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3702 m_host.TaskInventory[invItemID].PermsMask = perm;
3430 m_host.TaskInventory[invItemID].PermsMask = perm; 3703 m_host.TaskInventory.LockItemsForWrite(false);
3431 }
3432 3704
3433 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3705 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3434 "run_time_permissions", new Object[] { 3706 "run_time_permissions", new Object[] {
@@ -3438,28 +3710,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 return; 3710 return;
3439 } 3711 }
3440 } 3712 }
3441 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3713 else
3442 { 3714 {
3443 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3715 bool sitting = false;
3444 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3716 if (m_host.SitTargetAvatar == agentID)
3445 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3717 {
3446 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3718 sitting = true;
3447 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3719 }
3720 else
3721 {
3722 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3723 {
3724 if (p.SitTargetAvatar == agentID)
3725 sitting = true;
3726 }
3727 }
3448 3728
3449 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3729 if (sitting)
3450 { 3730 {
3451 lock (m_host.TaskInventory) 3731 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3732 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3733 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3734 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3735 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3736
3737 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3738 {
3739 m_host.TaskInventory.LockItemsForWrite(true);
3453 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3740 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3454 m_host.TaskInventory[invItemID].PermsMask = perm; 3741 m_host.TaskInventory[invItemID].PermsMask = perm;
3455 } 3742 m_host.TaskInventory.LockItemsForWrite(false);
3456 3743
3457 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3744 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3458 "run_time_permissions", new Object[] { 3745 "run_time_permissions", new Object[] {
3459 new LSL_Integer(perm) }, 3746 new LSL_Integer(perm) },
3460 new DetectParams[0])); 3747 new DetectParams[0]));
3461 3748
3462 return; 3749 return;
3750 }
3463 } 3751 }
3464 } 3752 }
3465 3753
@@ -3473,11 +3761,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 3761
3474 if (!m_waitingForScriptAnswer) 3762 if (!m_waitingForScriptAnswer)
3475 { 3763 {
3476 lock (m_host.TaskInventory) 3764 m_host.TaskInventory.LockItemsForWrite(true);
3477 { 3765 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3478 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3766 m_host.TaskInventory[invItemID].PermsMask = 0;
3479 m_host.TaskInventory[invItemID].PermsMask = 0; 3767 m_host.TaskInventory.LockItemsForWrite(false);
3480 }
3481 3768
3482 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3769 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3483 m_waitingForScriptAnswer=true; 3770 m_waitingForScriptAnswer=true;
@@ -3512,10 +3799,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3799 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3800 llReleaseControls();
3514 3801
3515 lock (m_host.TaskInventory) 3802
3516 { 3803 m_host.TaskInventory.LockItemsForWrite(true);
3517 m_host.TaskInventory[invItemID].PermsMask = answer; 3804 m_host.TaskInventory[invItemID].PermsMask = answer;
3518 } 3805 m_host.TaskInventory.LockItemsForWrite(false);
3806
3519 3807
3520 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3808 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3521 "run_time_permissions", new Object[] { 3809 "run_time_permissions", new Object[] {
@@ -3527,16 +3815,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 { 3815 {
3528 m_host.AddScriptLPS(1); 3816 m_host.AddScriptLPS(1);
3529 3817
3530 lock (m_host.TaskInventory) 3818 m_host.TaskInventory.LockItemsForRead(true);
3819
3820 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3531 { 3821 {
3532 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3822 if (item.Type == 10 && item.ItemID == m_itemID)
3533 { 3823 {
3534 if (item.Type == 10 && item.ItemID == m_itemID) 3824 m_host.TaskInventory.LockItemsForRead(false);
3535 { 3825 return item.PermsGranter.ToString();
3536 return item.PermsGranter.ToString();
3537 }
3538 } 3826 }
3539 } 3827 }
3828 m_host.TaskInventory.LockItemsForRead(false);
3540 3829
3541 return UUID.Zero.ToString(); 3830 return UUID.Zero.ToString();
3542 } 3831 }
@@ -3545,19 +3834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 { 3834 {
3546 m_host.AddScriptLPS(1); 3835 m_host.AddScriptLPS(1);
3547 3836
3548 lock (m_host.TaskInventory) 3837 m_host.TaskInventory.LockItemsForRead(true);
3838
3839 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3549 { 3840 {
3550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3841 if (item.Type == 10 && item.ItemID == m_itemID)
3551 { 3842 {
3552 if (item.Type == 10 && item.ItemID == m_itemID) 3843 int perms = item.PermsMask;
3553 { 3844 if (m_automaticLinkPermission)
3554 int perms = item.PermsMask; 3845 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3555 if (m_automaticLinkPermission) 3846 m_host.TaskInventory.LockItemsForRead(false);
3556 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3847 return perms;
3557 return perms;
3558 }
3559 } 3848 }
3560 } 3849 }
3850 m_host.TaskInventory.LockItemsForRead(false);
3561 3851
3562 return 0; 3852 return 0;
3563 } 3853 }
@@ -3579,9 +3869,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3869 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3870 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3871 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3872 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3873 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3874 try
3875 {
3876 parts[0].ParentGroup.areUpdatesSuspended = true;
3877 foreach (SceneObjectPart part in parts)
3878 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3879 }
3880 finally
3881 {
3882 parts[0].ParentGroup.areUpdatesSuspended = false;
3883 }
3884 }
3585 } 3885 }
3586 3886
3587 public void llCreateLink(string target, int parent) 3887 public void llCreateLink(string target, int parent)
@@ -3594,11 +3894,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 return; 3894 return;
3595 3895
3596 TaskInventoryItem item; 3896 TaskInventoryItem item;
3597 lock (m_host.TaskInventory) 3897 m_host.TaskInventory.LockItemsForRead(true);
3598 { 3898 item = m_host.TaskInventory[invItemID];
3599 item = m_host.TaskInventory[invItemID]; 3899 m_host.TaskInventory.LockItemsForRead(false);
3600 } 3900
3601
3602 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3901 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3603 && !m_automaticLinkPermission) 3902 && !m_automaticLinkPermission)
3604 { 3903 {
@@ -3615,11 +3914,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3615 3914
3616 if (targetPart.ParentGroup.AttachmentPoint != 0) 3915 if (targetPart.ParentGroup.AttachmentPoint != 0)
3617 return; // Fail silently if attached 3916 return; // Fail silently if attached
3917
3918 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3919 return;
3920
3618 SceneObjectGroup parentPrim = null, childPrim = null; 3921 SceneObjectGroup parentPrim = null, childPrim = null;
3619 3922
3620 if (targetPart != null) 3923 if (targetPart != null)
3621 { 3924 {
3622 if (parent != 0) { 3925 if (parent != 0)
3926 {
3623 parentPrim = m_host.ParentGroup; 3927 parentPrim = m_host.ParentGroup;
3624 childPrim = targetPart.ParentGroup; 3928 childPrim = targetPart.ParentGroup;
3625 } 3929 }
@@ -3650,16 +3954,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3650 m_host.AddScriptLPS(1); 3954 m_host.AddScriptLPS(1);
3651 UUID invItemID = InventorySelf(); 3955 UUID invItemID = InventorySelf();
3652 3956
3653 lock (m_host.TaskInventory) 3957 m_host.TaskInventory.LockItemsForRead(true);
3654 {
3655 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3958 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3656 && !m_automaticLinkPermission) 3959 && !m_automaticLinkPermission)
3657 { 3960 {
3658 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3961 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3962 m_host.TaskInventory.LockItemsForRead(false);
3659 return; 3963 return;
3660 } 3964 }
3661 } 3965 m_host.TaskInventory.LockItemsForRead(false);
3662 3966
3663 if (linknum < ScriptBaseClass.LINK_THIS) 3967 if (linknum < ScriptBaseClass.LINK_THIS)
3664 return; 3968 return;
3665 3969
@@ -3698,10 +4002,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 4002 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4003 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 4004 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4005 if (parts.Count > 0)
3702 { 4006 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4007 try
4008 {
4009 parts[0].ParentGroup.areUpdatesSuspended = true;
4010 foreach (SceneObjectPart part in parts)
4011 {
4012 parentPrim.DelinkFromGroup(part.LocalId, true);
4013 }
4014 }
4015 finally
4016 {
4017 parts[0].ParentGroup.areUpdatesSuspended = false;
4018 }
3704 } 4019 }
4020
3705 parentPrim.HasGroupChanged = true; 4021 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4022 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4023 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4026,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4026 {
3711 SceneObjectPart newRoot = parts[0]; 4027 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4028 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4029
4030 try
3714 { 4031 {
3715 // Required for linking 4032 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4033 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4034 {
4035 part.ClearUpdateSchedule();
4036 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4037 }
3718 } 4038 }
4039 finally
4040 {
4041 parts[0].ParentGroup.areUpdatesSuspended = false;
4042 }
4043
4044
3719 newRoot.ParentGroup.HasGroupChanged = true; 4045 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4046 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4047 }
@@ -3735,6 +4061,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4061 public void llBreakAllLinks()
3736 { 4062 {
3737 m_host.AddScriptLPS(1); 4063 m_host.AddScriptLPS(1);
4064
4065 UUID invItemID = InventorySelf();
4066
4067 TaskInventoryItem item;
4068 m_host.TaskInventory.LockItemsForRead(true);
4069 item = m_host.TaskInventory[invItemID];
4070 m_host.TaskInventory.LockItemsForRead(false);
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3754,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3755 { 4096 {
3756 m_host.AddScriptLPS(1); 4097 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); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4099 if (part != null)
3778 { 4100 {
@@ -3780,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4102 }
3781 else 4103 else
3782 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3783 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3784 } 4119 }
3785 } 4120 }
@@ -3878,17 +4213,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 m_host.AddScriptLPS(1); 4213 m_host.AddScriptLPS(1);
3879 int count = 0; 4214 int count = 0;
3880 4215
3881 lock (m_host.TaskInventory) 4216 m_host.TaskInventory.LockItemsForRead(true);
4217 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3882 { 4218 {
3883 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4219 if (inv.Value.Type == type || type == -1)
3884 { 4220 {
3885 if (inv.Value.Type == type || type == -1) 4221 count = count + 1;
3886 {
3887 count = count + 1;
3888 }
3889 } 4222 }
3890 } 4223 }
3891 4224
4225 m_host.TaskInventory.LockItemsForRead(false);
3892 return count; 4226 return count;
3893 } 4227 }
3894 4228
@@ -3897,16 +4231,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3898 ArrayList keys = new ArrayList(); 4232 ArrayList keys = new ArrayList();
3899 4233
3900 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4236 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Type == type || type == -1)
3903 { 4238 {
3904 if (inv.Value.Type == type || type == -1) 4239 keys.Add(inv.Value.Name);
3905 {
3906 keys.Add(inv.Value.Name);
3907 }
3908 } 4240 }
3909 } 4241 }
4242 m_host.TaskInventory.LockItemsForRead(false);
3910 4243
3911 if (keys.Count == 0) 4244 if (keys.Count == 0)
3912 { 4245 {
@@ -3943,25 +4276,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 } 4276 }
3944 4277
3945 // move the first object found with this inventory name 4278 // move the first object found with this inventory name
3946 lock (m_host.TaskInventory) 4279 m_host.TaskInventory.LockItemsForRead(true);
4280 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3947 { 4281 {
3948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4282 if (inv.Value.Name == inventory)
3949 { 4283 {
3950 if (inv.Value.Name == inventory) 4284 found = true;
3951 { 4285 objId = inv.Key;
3952 found = true; 4286 assetType = inv.Value.Type;
3953 objId = inv.Key; 4287 objName = inv.Value.Name;
3954 assetType = inv.Value.Type; 4288 break;
3955 objName = inv.Value.Name;
3956 break;
3957 }
3958 } 4289 }
3959 } 4290 }
4291 m_host.TaskInventory.LockItemsForRead(false);
3960 4292
3961 if (!found) 4293 if (!found)
3962 { 4294 {
3963 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4295 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)); 4296 return;
4297// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3965 } 4298 }
3966 4299
3967 // check if destination is an object 4300 // check if destination is an object
@@ -3987,48 +4320,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 return; 4320 return;
3988 } 4321 }
3989 } 4322 }
4323
3990 // destination is an avatar 4324 // destination is an avatar
3991 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4325 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3992 4326
3993 if (agentItem == null) 4327 if (agentItem == null)
3994 return; 4328 return;
3995 4329
3996 byte[] bucket = new byte[17]; 4330 byte[] bucket = new byte[1];
3997 bucket[0] = (byte)assetType; 4331 bucket[0] = (byte)assetType;
3998 byte[] objBytes = agentItem.ID.GetBytes(); 4332 //byte[] objBytes = agentItem.ID.GetBytes();
3999 Array.Copy(objBytes, 0, bucket, 1, 16); 4333 //Array.Copy(objBytes, 0, bucket, 1, 16);
4000 4334
4001 GridInstantMessage msg = new GridInstantMessage(World, 4335 GridInstantMessage msg = new GridInstantMessage(World,
4002 m_host.UUID, m_host.Name+", an object owned by "+ 4336 m_host.OwnerID, m_host.Name, destId,
4003 resolveName(m_host.OwnerID)+",", destId,
4004 (byte)InstantMessageDialog.TaskInventoryOffered, 4337 (byte)InstantMessageDialog.TaskInventoryOffered,
4005 false, objName+"\n"+m_host.Name+" is located at "+ 4338 false, objName+". "+m_host.Name+" is located at "+
4006 World.RegionInfo.RegionName+" "+ 4339 World.RegionInfo.RegionName+" "+
4007 m_host.AbsolutePosition.ToString(), 4340 m_host.AbsolutePosition.ToString(),
4008 agentItem.ID, true, m_host.AbsolutePosition, 4341 agentItem.ID, true, m_host.AbsolutePosition,
4009 bucket); 4342 bucket);
4010 if (m_TransferModule != null) 4343
4011 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4344 ScenePresence sp;
4345
4346 if (World.TryGetScenePresence(destId, out sp))
4347 {
4348 sp.ControllingClient.SendInstantMessage(msg);
4349 }
4350 else
4351 {
4352 if (m_TransferModule != null)
4353 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4354 }
4355
4356 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4357 ScriptSleep(3000);
4013 } 4358 }
4014 } 4359 }
4015 4360
4361 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4362 public void llRemoveInventory(string name)
4017 { 4363 {
4018 m_host.AddScriptLPS(1); 4364 m_host.AddScriptLPS(1);
4019 4365
4020 lock (m_host.TaskInventory) 4366 List<TaskInventoryItem> inv;
4367 try
4021 { 4368 {
4022 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4369 m_host.TaskInventory.LockItemsForRead(true);
4370 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4371 }
4372 finally
4373 {
4374 m_host.TaskInventory.LockItemsForRead(false);
4375 }
4376 foreach (TaskInventoryItem item in inv)
4377 {
4378 if (item.Name == name)
4023 { 4379 {
4024 if (item.Name == name) 4380 if (item.ItemID == m_itemID)
4025 { 4381 throw new ScriptDeleteException();
4026 if (item.ItemID == m_itemID) 4382 else
4027 throw new ScriptDeleteException(); 4383 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4028 else 4384 return;
4029 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4030 return;
4031 }
4032 } 4385 }
4033 } 4386 }
4034 } 4387 }
@@ -4063,112 +4416,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4416 {
4064 m_host.AddScriptLPS(1); 4417 m_host.AddScriptLPS(1);
4065 4418
4066 UUID uuid = (UUID)id; 4419 UUID uuid;
4067 PresenceInfo pinfo = null; 4420 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4421 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4422 PresenceInfo pinfo = null;
4074 if (account == null) 4423 UserAccount account;
4424
4425 UserInfoCacheEntry ce;
4426 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4427 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4428 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4429 if (account == null)
4078 } 4430 {
4431 m_userInfoCache[uuid] = null; // Cache negative
4432 return UUID.Zero.ToString();
4433 }
4079 4434
4080 4435
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4436 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4437 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4438 {
4086 if (p.RegionID != UUID.Zero) 4439 foreach (PresenceInfo p in pinfos)
4087 { 4440 {
4088 pinfo = p; 4441 if (p.RegionID != UUID.Zero)
4442 {
4443 pinfo = p;
4444 }
4089 } 4445 }
4090 } 4446 }
4091 }
4092 4447
4093 ce = new UserInfoCacheEntry(); 4448 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4449 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4450 ce.account = account;
4096 ce.pinfo = pinfo; 4451 ce.pinfo = pinfo;
4097 } 4452 m_userInfoCache[uuid] = ce;
4098 else 4453 }
4099 { 4454 else
4100 if (ce == null) 4455 {
4101 return UUID.Zero.ToString(); 4456 if (ce == null)
4457 return UUID.Zero.ToString();
4102 4458
4103 account = ce.account; 4459 account = ce.account;
4104 pinfo = ce.pinfo; 4460 pinfo = ce.pinfo;
4105 } 4461 }
4106 4462
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4463 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 { 4464 {
4112 foreach (PresenceInfo p in pinfos) 4465 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4466 if (pinfos != null && pinfos.Length > 0)
4113 { 4467 {
4114 if (p.RegionID != UUID.Zero) 4468 foreach (PresenceInfo p in pinfos)
4115 { 4469 {
4116 pinfo = p; 4470 if (p.RegionID != UUID.Zero)
4471 {
4472 pinfo = p;
4473 }
4117 } 4474 }
4118 } 4475 }
4119 } 4476 else
4120 else 4477 pinfo = null;
4121 pinfo = null;
4122 4478
4123 ce.time = Util.EnvironmentTickCount(); 4479 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4480 ce.pinfo = pinfo;
4125 } 4481 }
4126 4482
4127 string reply = String.Empty; 4483 string reply = String.Empty;
4128 4484
4129 switch (data) 4485 switch (data)
4130 { 4486 {
4131 case 1: // DATA_ONLINE (0|1) 4487 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4488 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4489 reply = "1";
4134 else 4490 else
4135 reply = "0"; 4491 reply = "0";
4136 break; 4492 break;
4137 case 2: // DATA_NAME (First Last) 4493 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4494 reply = account.FirstName + " " + account.LastName;
4139 break; 4495 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4496 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4497 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4498 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4499 reply = born.ToString("yyyy-MM-dd");
4144 break; 4500 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4501 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4502 reply = "0,0,0,0,0,0";
4147 break; 4503 break;
4148 case 8: // DATA_PAYINFO (0|1|2|3) 4504 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = "0"; 4505 reply = "0";
4150 break; 4506 break;
4151 default: 4507 default:
4152 return UUID.Zero.ToString(); // Raise no event 4508 return UUID.Zero.ToString(); // Raise no event
4153 } 4509 }
4154 4510
4155 UUID rq = UUID.Random(); 4511 UUID rq = UUID.Random();
4156 4512
4157 UUID tid = AsyncCommands. 4513 UUID tid = AsyncCommands.
4158 DataserverPlugin.RegisterRequest(m_localID, 4514 DataserverPlugin.RegisterRequest(m_localID,
4159 m_itemID, rq.ToString()); 4515 m_itemID, rq.ToString());
4160 4516
4161 AsyncCommands. 4517 AsyncCommands.
4162 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4518 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4163 4519
4164 ScriptSleep(100); 4520 ScriptSleep(100);
4165 return tid.ToString(); 4521 return tid.ToString();
4522 }
4523 else
4524 {
4525 ShoutError("Invalid UUID passed to llRequestAgentData.");
4526 }
4527 return "";
4166 } 4528 }
4167 4529
4168 public LSL_String llRequestInventoryData(string name) 4530 public LSL_String llRequestInventoryData(string name)
4169 { 4531 {
4170 m_host.AddScriptLPS(1); 4532 m_host.AddScriptLPS(1);
4171 4533
4534 //Clone is thread safe
4172 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4535 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4173 4536
4174 foreach (TaskInventoryItem item in itemDictionary.Values) 4537 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4222,6 +4585,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 ScenePresence presence = World.GetScenePresence(agentId); 4585 ScenePresence presence = World.GetScenePresence(agentId);
4223 if (presence != null) 4586 if (presence != null)
4224 { 4587 {
4588 // agent must not be a god
4589 if (presence.UserLevel >= 200) return;
4590
4225 // agent must be over the owners land 4591 // agent must be over the owners land
4226 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4592 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4227 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4593 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4244,7 +4610,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 UUID av = new UUID(); 4610 UUID av = new UUID();
4245 if (!UUID.TryParse(agent,out av)) 4611 if (!UUID.TryParse(agent,out av))
4246 { 4612 {
4247 LSLError("First parameter to llDialog needs to be a key"); 4613 //LSLError("First parameter to llDialog needs to be a key");
4248 return; 4614 return;
4249 } 4615 }
4250 4616
@@ -4281,17 +4647,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID soundId = UUID.Zero; 4647 UUID soundId = UUID.Zero;
4282 if (!UUID.TryParse(impact_sound, out soundId)) 4648 if (!UUID.TryParse(impact_sound, out soundId))
4283 { 4649 {
4284 lock (m_host.TaskInventory) 4650 m_host.TaskInventory.LockItemsForRead(true);
4651 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4285 { 4652 {
4286 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4653 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4287 { 4654 {
4288 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4655 soundId = item.AssetID;
4289 { 4656 break;
4290 soundId = item.AssetID;
4291 break;
4292 }
4293 } 4657 }
4294 } 4658 }
4659 m_host.TaskInventory.LockItemsForRead(false);
4295 } 4660 }
4296 m_host.CollisionSound = soundId; 4661 m_host.CollisionSound = soundId;
4297 m_host.CollisionSoundVolume = (float)impact_volume; 4662 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4331,6 +4696,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 UUID partItemID; 4696 UUID partItemID;
4332 foreach (SceneObjectPart part in parts) 4697 foreach (SceneObjectPart part in parts)
4333 { 4698 {
4699 //Clone is thread safe
4334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4700 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4335 4701
4336 foreach (TaskInventoryItem item in itemsDictionary.Values) 4702 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4545,17 +4911,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4545 4911
4546 m_host.AddScriptLPS(1); 4912 m_host.AddScriptLPS(1);
4547 4913
4548 lock (m_host.TaskInventory) 4914 m_host.TaskInventory.LockItemsForRead(true);
4915 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4549 { 4916 {
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4917 if (item.Type == 10 && item.ItemID == m_itemID)
4551 { 4918 {
4552 if (item.Type == 10 && item.ItemID == m_itemID) 4919 result = item.Name!=null?item.Name:String.Empty;
4553 { 4920 break;
4554 result = item.Name != null ? item.Name : String.Empty;
4555 break;
4556 }
4557 } 4921 }
4558 } 4922 }
4923 m_host.TaskInventory.LockItemsForRead(false);
4559 4924
4560 return result; 4925 return result;
4561 } 4926 }
@@ -4728,23 +5093,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5093 {
4729 m_host.AddScriptLPS(1); 5094 m_host.AddScriptLPS(1);
4730 5095
4731 lock (m_host.TaskInventory) 5096 m_host.TaskInventory.LockItemsForRead(true);
5097 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4732 { 5098 {
4733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5099 if (inv.Value.Name == name)
4734 { 5100 {
4735 if (inv.Value.Name == name) 5101 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4736 { 5102 {
4737 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5103 m_host.TaskInventory.LockItemsForRead(false);
4738 { 5104 return inv.Value.AssetID.ToString();
4739 return inv.Value.AssetID.ToString(); 5105 }
4740 } 5106 else
4741 else 5107 {
4742 { 5108 m_host.TaskInventory.LockItemsForRead(false);
4743 return UUID.Zero.ToString(); 5109 return UUID.Zero.ToString();
4744 }
4745 } 5110 }
4746 } 5111 }
4747 } 5112 }
5113 m_host.TaskInventory.LockItemsForRead(false);
4748 5114
4749 return UUID.Zero.ToString(); 5115 return UUID.Zero.ToString();
4750 } 5116 }
@@ -4897,14 +5263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 { 5263 {
4898 m_host.AddScriptLPS(1); 5264 m_host.AddScriptLPS(1);
4899 5265
4900 if (src == null) 5266 return src.Length;
4901 {
4902 return 0;
4903 }
4904 else
4905 {
4906 return src.Length;
4907 }
4908 } 5267 }
4909 5268
4910 public LSL_Integer llList2Integer(LSL_List src, int index) 5269 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4950,7 +5309,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 else if (src.Data[index] is LSL_Float) 5309 else if (src.Data[index] is LSL_Float)
4951 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5310 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4952 else if (src.Data[index] is LSL_String) 5311 else if (src.Data[index] is LSL_String)
4953 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5312 {
5313 string str = ((LSL_String) src.Data[index]).m_string;
5314 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5315 if (m != Match.Empty)
5316 {
5317 str = m.Value;
5318 double d = 0.0;
5319 if (!Double.TryParse(str, out d))
5320 return 0.0;
5321
5322 return d;
5323 }
5324 return 0.0;
5325 }
4954 return Convert.ToDouble(src.Data[index]); 5326 return Convert.ToDouble(src.Data[index]);
4955 } 5327 }
4956 catch (FormatException) 5328 catch (FormatException)
@@ -5223,7 +5595,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5223 } 5595 }
5224 } 5596 }
5225 } 5597 }
5226 else { 5598 else
5599 {
5227 object[] array = new object[src.Length]; 5600 object[] array = new object[src.Length];
5228 Array.Copy(src.Data, 0, array, 0, src.Length); 5601 Array.Copy(src.Data, 0, array, 0, src.Length);
5229 result = new LSL_List(array); 5602 result = new LSL_List(array);
@@ -5672,10 +6045,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5672 m_host.AddScriptLPS(1); 6045 m_host.AddScriptLPS(1);
5673 6046
5674 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6047 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5675 6048 if (parts.Count > 0)
5676 foreach (var part in parts)
5677 { 6049 {
5678 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6050 try
6051 {
6052 parts[0].ParentGroup.areUpdatesSuspended = true;
6053 foreach (var part in parts)
6054 {
6055 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6056 }
6057 }
6058 finally
6059 {
6060 parts[0].ParentGroup.areUpdatesSuspended = false;
6061 }
5679 } 6062 }
5680 } 6063 }
5681 6064
@@ -5729,6 +6112,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5729 ScriptSleep(5000); 6112 ScriptSleep(5000);
5730 } 6113 }
5731 6114
6115 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6116 {
6117 return ParseString2List(str, separators, in_spacers, false);
6118 }
6119
5732 public LSL_Integer llOverMyLand(string id) 6120 public LSL_Integer llOverMyLand(string id)
5733 { 6121 {
5734 m_host.AddScriptLPS(1); 6122 m_host.AddScriptLPS(1);
@@ -5793,8 +6181,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5793 UUID agentId = new UUID(); 6181 UUID agentId = new UUID();
5794 if (!UUID.TryParse(agent, out agentId)) 6182 if (!UUID.TryParse(agent, out agentId))
5795 return new LSL_Integer(0); 6183 return new LSL_Integer(0);
6184 if (agentId == m_host.GroupID)
6185 return new LSL_Integer(1);
5796 ScenePresence presence = World.GetScenePresence(agentId); 6186 ScenePresence presence = World.GetScenePresence(agentId);
5797 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6187 if (presence == null || presence.IsChildAgent) // Return false for child agents
5798 return new LSL_Integer(0); 6188 return new LSL_Integer(0);
5799 IClientAPI client = presence.ControllingClient; 6189 IClientAPI client = presence.ControllingClient;
5800 if (m_host.GroupID == client.ActiveGroupId) 6190 if (m_host.GroupID == client.ActiveGroupId)
@@ -5929,7 +6319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5929 return m_host.ParentGroup.AttachmentPoint; 6319 return m_host.ParentGroup.AttachmentPoint;
5930 } 6320 }
5931 6321
5932 public LSL_Integer llGetFreeMemory() 6322 public virtual LSL_Integer llGetFreeMemory()
5933 { 6323 {
5934 m_host.AddScriptLPS(1); 6324 m_host.AddScriptLPS(1);
5935 // Make scripts designed for LSO happy 6325 // Make scripts designed for LSO happy
@@ -6046,7 +6436,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6046 SetParticleSystem(m_host, rules); 6436 SetParticleSystem(m_host, rules);
6047 } 6437 }
6048 6438
6049 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6439 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6440 {
6050 6441
6051 6442
6052 if (rules.Length == 0) 6443 if (rules.Length == 0)
@@ -6240,14 +6631,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6240 6631
6241 protected UUID GetTaskInventoryItem(string name) 6632 protected UUID GetTaskInventoryItem(string name)
6242 { 6633 {
6243 lock (m_host.TaskInventory) 6634 m_host.TaskInventory.LockItemsForRead(true);
6635 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6244 { 6636 {
6245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6637 if (inv.Value.Name == name)
6246 { 6638 {
6247 if (inv.Value.Name == name) 6639 m_host.TaskInventory.LockItemsForRead(false);
6248 return inv.Key; 6640 return inv.Key;
6249 } 6641 }
6250 } 6642 }
6643 m_host.TaskInventory.LockItemsForRead(false);
6251 6644
6252 return UUID.Zero; 6645 return UUID.Zero;
6253 } 6646 }
@@ -6285,16 +6678,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6285 if (folderID == UUID.Zero) 6678 if (folderID == UUID.Zero)
6286 return; 6679 return;
6287 6680
6288 byte[] bucket = new byte[17]; 6681 byte[] bucket = new byte[1];
6289 bucket[0] = (byte)AssetType.Folder; 6682 bucket[0] = (byte)AssetType.Folder;
6290 byte[] objBytes = folderID.GetBytes(); 6683 //byte[] objBytes = folderID.GetBytes();
6291 Array.Copy(objBytes, 0, bucket, 1, 16); 6684 //Array.Copy(objBytes, 0, bucket, 1, 16);
6292 6685
6293 GridInstantMessage msg = new GridInstantMessage(World, 6686 GridInstantMessage msg = new GridInstantMessage(World,
6294 m_host.UUID, m_host.Name+", an object owned by "+ 6687 m_host.OwnerID, m_host.Name, destID,
6295 resolveName(m_host.OwnerID)+",", destID, 6688 (byte)InstantMessageDialog.TaskInventoryOffered,
6296 (byte)InstantMessageDialog.InventoryOffered, 6689 false, category+". "+m_host.Name+" is located at "+
6297 false, category+"\n"+m_host.Name+" is located at "+
6298 World.RegionInfo.RegionName+" "+ 6690 World.RegionInfo.RegionName+" "+
6299 m_host.AbsolutePosition.ToString(), 6691 m_host.AbsolutePosition.ToString(),
6300 folderID, true, m_host.AbsolutePosition, 6692 folderID, true, m_host.AbsolutePosition,
@@ -6497,13 +6889,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6497 UUID av = new UUID(); 6889 UUID av = new UUID();
6498 if (!UUID.TryParse(avatar,out av)) 6890 if (!UUID.TryParse(avatar,out av))
6499 { 6891 {
6500 LSLError("First parameter to llDialog needs to be a key"); 6892 //LSLError("First parameter to llDialog needs to be a key");
6501 return; 6893 return;
6502 } 6894 }
6503 if (buttons.Length < 1) 6895 if (buttons.Length < 1)
6504 { 6896 {
6505 LSLError("No less than 1 button can be shown"); 6897 buttons.Add("OK");
6506 return;
6507 } 6898 }
6508 if (buttons.Length > 12) 6899 if (buttons.Length > 12)
6509 { 6900 {
@@ -6520,7 +6911,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6520 } 6911 }
6521 if (buttons.Data[i].ToString().Length > 24) 6912 if (buttons.Data[i].ToString().Length > 24)
6522 { 6913 {
6523 LSLError("button label cannot be longer than 24 characters"); 6914 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6524 return; 6915 return;
6525 } 6916 }
6526 buts[i] = buttons.Data[i].ToString(); 6917 buts[i] = buttons.Data[i].ToString();
@@ -6579,22 +6970,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6579 } 6970 }
6580 6971
6581 // copy the first script found with this inventory name 6972 // copy the first script found with this inventory name
6582 lock (m_host.TaskInventory) 6973 TaskInventoryItem scriptItem = null;
6974 m_host.TaskInventory.LockItemsForRead(true);
6975 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6583 { 6976 {
6584 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6977 if (inv.Value.Name == name)
6585 { 6978 {
6586 if (inv.Value.Name == name) 6979 // make sure the object is a script
6980 if (10 == inv.Value.Type)
6587 { 6981 {
6588 // make sure the object is a script 6982 found = true;
6589 if (10 == inv.Value.Type) 6983 srcId = inv.Key;
6590 { 6984 scriptItem = inv.Value;
6591 found = true; 6985 break;
6592 srcId = inv.Key;
6593 break;
6594 }
6595 } 6986 }
6596 } 6987 }
6597 } 6988 }
6989 m_host.TaskInventory.LockItemsForRead(false);
6598 6990
6599 if (!found) 6991 if (!found)
6600 { 6992 {
@@ -6602,8 +6994,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6602 return; 6994 return;
6603 } 6995 }
6604 6996
6605 // the rest of the permission checks are done in RezScript, so check the pin there as well 6997 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6606 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6998 if (dest != null)
6999 {
7000 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7001 {
7002 // the rest of the permission checks are done in RezScript, so check the pin there as well
7003 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7004
7005 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7006 m_host.Inventory.RemoveInventoryItem(srcId);
7007 }
7008 }
6607 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7009 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6608 ScriptSleep(3000); 7010 ScriptSleep(3000);
6609 } 7011 }
@@ -6666,19 +7068,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6666 public LSL_String llMD5String(string src, int nonce) 7068 public LSL_String llMD5String(string src, int nonce)
6667 { 7069 {
6668 m_host.AddScriptLPS(1); 7070 m_host.AddScriptLPS(1);
6669 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7071 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6670 } 7072 }
6671 7073
6672 public LSL_String llSHA1String(string src) 7074 public LSL_String llSHA1String(string src)
6673 { 7075 {
6674 m_host.AddScriptLPS(1); 7076 m_host.AddScriptLPS(1);
6675 return Util.SHA1Hash(src).ToLower(); 7077 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6676 } 7078 }
6677 7079
6678 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7080 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6679 { 7081 {
6680 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7082 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6681 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7083 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7084 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7085 return shapeBlock;
6682 7086
6683 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7087 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6684 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7088 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6783,6 +7187,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6783 // Prim type box, cylinder and prism. 7187 // 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) 7188 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 { 7189 {
7190 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7191 return;
7192
6786 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7193 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6787 ObjectShapePacket.ObjectDataBlock shapeBlock; 7194 ObjectShapePacket.ObjectDataBlock shapeBlock;
6788 7195
@@ -6836,6 +7243,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6836 // Prim type sphere. 7243 // 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) 7244 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6838 { 7245 {
7246 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7247 return;
7248
6839 ObjectShapePacket.ObjectDataBlock shapeBlock; 7249 ObjectShapePacket.ObjectDataBlock shapeBlock;
6840 7250
6841 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7251 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6877,6 +7287,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 // Prim type torus, tube and ring. 7287 // 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) 7288 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 { 7289 {
7290 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7291 return;
7292
6880 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7293 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6881 ObjectShapePacket.ObjectDataBlock shapeBlock; 7294 ObjectShapePacket.ObjectDataBlock shapeBlock;
6882 7295
@@ -7012,6 +7425,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7012 // Prim type sculpt. 7425 // Prim type sculpt.
7013 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7426 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7014 { 7427 {
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return;
7430
7015 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7431 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7016 UUID sculptId; 7432 UUID sculptId;
7017 7433
@@ -7028,13 +7444,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7028 shapeBlock.PathScaleX = 100; 7444 shapeBlock.PathScaleX = 100;
7029 shapeBlock.PathScaleY = 150; 7445 shapeBlock.PathScaleY = 150;
7030 7446
7031 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7447 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7032 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7448 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7033 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7449 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7034 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7450 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7035 { 7451 {
7036 // default 7452 // default
7037 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7453 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7038 } 7454 }
7039 7455
7040 part.Shape.SetSculptProperties((byte)type, sculptId); 7456 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7050,32 +7466,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7050 ScriptSleep(200); 7466 ScriptSleep(200);
7051 } 7467 }
7052 7468
7053 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7469 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7054 { 7470 {
7055 m_host.AddScriptLPS(1); 7471 m_host.AddScriptLPS(1);
7056 7472
7057 setLinkPrimParams(linknumber, rules); 7473 setLinkPrimParams(linknumber, rules);
7058
7059 ScriptSleep(200);
7060 } 7474 }
7061 7475
7062 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7476 private void setLinkPrimParams(int linknumber, LSL_List rules)
7063 { 7477 {
7064 m_host.AddScriptLPS(1); 7478 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7479 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7480 if (parts.Count>0)
7481 {
7482 try
7483 {
7484 parts[0].ParentGroup.areUpdatesSuspended = true;
7485 foreach (SceneObjectPart part in parts)
7486 SetPrimParams(part, rules);
7487 }
7488 finally
7489 {
7490 parts[0].ParentGroup.areUpdatesSuspended = false;
7491 }
7492 }
7493 if (avatars.Count > 0)
7494 {
7495 foreach (ScenePresence avatar in avatars)
7496 SetPrimParams(avatar, rules);
7497 }
7498 }
7065 7499
7066 setLinkPrimParams(linknumber, rules); 7500 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7501 {
7502 llSetLinkPrimitiveParamsFast(linknumber, rules);
7503 ScriptSleep(200);
7067 } 7504 }
7068 7505
7069 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7506 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7070 { 7507 {
7071 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7508 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7509 //We only support PRIM_POSITION and PRIM_ROTATION
7072 7510
7073 foreach (SceneObjectPart part in parts) 7511 int idx = 0;
7074 SetPrimParams(part, rules); 7512
7513 while (idx < rules.Length)
7514 {
7515 int code = rules.GetLSLIntegerItem(idx++);
7516
7517 int remain = rules.Length - idx;
7518
7519
7520
7521 switch (code)
7522 {
7523 case (int)ScriptBaseClass.PRIM_POSITION:
7524 if (remain < 1)
7525 return;
7526 LSL_Vector v;
7527 v = rules.GetVector3Item(idx++);
7528 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7529 av.SendAvatarDataToAllAgents();
7530
7531 break;
7532
7533 case (int)ScriptBaseClass.PRIM_ROTATION:
7534 if (remain < 1)
7535 return;
7536 LSL_Rotation r;
7537 r = rules.GetQuaternionItem(idx++);
7538 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7539 av.SendAvatarDataToAllAgents();
7540 break;
7541 }
7542 }
7075 } 7543 }
7076 7544
7077 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7545 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7078 { 7546 {
7547 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7548 return;
7549
7079 int idx = 0; 7550 int idx = 0;
7080 7551
7081 bool positionChanged = false; 7552 bool positionChanged = false;
@@ -7103,6 +7574,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7103 currentPosition = GetSetPosTarget(part, v, currentPosition); 7574 currentPosition = GetSetPosTarget(part, v, currentPosition);
7104 7575
7105 break; 7576 break;
7577 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7578 if (remain < 1)
7579 return;
7580
7581 v=rules.GetVector3Item(idx++);
7582 positionChanged = true;
7583 currentPosition = GetSetPosTarget(part, v, currentPosition);
7584
7585 break;
7106 case (int)ScriptBaseClass.PRIM_SIZE: 7586 case (int)ScriptBaseClass.PRIM_SIZE:
7107 if (remain < 1) 7587 if (remain < 1)
7108 return; 7588 return;
@@ -7480,6 +7960,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7480 } 7960 }
7481 } 7961 }
7482 } 7962 }
7963
7964 if (positionChanged)
7965 {
7966 if (part.ParentGroup.RootPart == part)
7967 {
7968 SceneObjectGroup parent = part.ParentGroup;
7969 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7970 }
7971 else
7972 {
7973 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7974 SceneObjectGroup parent = part.ParentGroup;
7975 parent.HasGroupChanged = true;
7976 parent.ScheduleGroupForTerseUpdate();
7977 }
7978 }
7483 } 7979 }
7484 7980
7485 public LSL_String llStringToBase64(string str) 7981 public LSL_String llStringToBase64(string str)
@@ -7628,13 +8124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7628 public LSL_Integer llGetNumberOfPrims() 8124 public LSL_Integer llGetNumberOfPrims()
7629 { 8125 {
7630 m_host.AddScriptLPS(1); 8126 m_host.AddScriptLPS(1);
7631 int avatarCount = 0; 8127 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7632 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8128
7633 {
7634 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7635 avatarCount++;
7636 });
7637
7638 return m_host.ParentGroup.PrimCount + avatarCount; 8129 return m_host.ParentGroup.PrimCount + avatarCount;
7639 } 8130 }
7640 8131
@@ -7650,55 +8141,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7650 m_host.AddScriptLPS(1); 8141 m_host.AddScriptLPS(1);
7651 UUID objID = UUID.Zero; 8142 UUID objID = UUID.Zero;
7652 LSL_List result = new LSL_List(); 8143 LSL_List result = new LSL_List();
8144
8145 // If the ID is not valid, return null result
7653 if (!UUID.TryParse(obj, out objID)) 8146 if (!UUID.TryParse(obj, out objID))
7654 { 8147 {
7655 result.Add(new LSL_Vector()); 8148 result.Add(new LSL_Vector());
7656 result.Add(new LSL_Vector()); 8149 result.Add(new LSL_Vector());
7657 return result; 8150 return result;
7658 } 8151 }
8152
8153 // Check if this is an attached prim. If so, replace
8154 // the UUID with the avatar UUID and report it's bounding box
8155 SceneObjectPart part = World.GetSceneObjectPart(objID);
8156 if (part != null && part.ParentGroup.IsAttachment)
8157 objID = part.ParentGroup.AttachedAvatar;
8158
8159 // Find out if this is an avatar ID. If so, return it's box
7659 ScenePresence presence = World.GetScenePresence(objID); 8160 ScenePresence presence = World.GetScenePresence(objID);
7660 if (presence != null) 8161 if (presence != null)
7661 { 8162 {
7662 if (presence.ParentID == 0) // not sat on an object 8163 // As per LSL Wiki, there is no difference between sitting
8164 // and standing avatar since server 1.36
8165 LSL_Vector lower;
8166 LSL_Vector upper;
8167 if (presence.Animator.Animations.DefaultAnimation.AnimID
8168 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7663 { 8169 {
7664 LSL_Vector lower; 8170 // This is for ground sitting avatars
7665 LSL_Vector upper; 8171 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7666 if (presence.Animator.Animations.DefaultAnimation.AnimID 8172 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7667 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8173 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 } 8174 }
7685 else 8175 else
7686 { 8176 {
7687 // sitting on an object so we need the bounding box of that 8177 // This is for standing/flying avatars
7688 // which should include the avatar so set the UUID to the 8178 float height = presence.Appearance.AvatarHeight / 2.0f;
7689 // UUID of the object the avatar is sat on and allow it to fall through 8179 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7690 // to processing an object 8180 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7691 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7692 objID = p.UUID;
7693 } 8181 }
8182
8183 // Adjust to the documented error offsets (see LSL Wiki)
8184 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8185 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8186
8187 if (lower.x > upper.x)
8188 lower.x = upper.x;
8189 if (lower.y > upper.y)
8190 lower.y = upper.y;
8191 if (lower.z > upper.z)
8192 lower.z = upper.z;
8193
8194 result.Add(lower);
8195 result.Add(upper);
8196 return result;
7694 } 8197 }
7695 SceneObjectPart part = World.GetSceneObjectPart(objID); 8198
8199 part = World.GetSceneObjectPart(objID);
7696 // Currently only works for single prims without a sitting avatar 8200 // Currently only works for single prims without a sitting avatar
7697 if (part != null) 8201 if (part != null)
7698 { 8202 {
7699 Vector3 halfSize = part.Scale / 2.0f; 8203 float minX;
7700 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8204 float maxX;
7701 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8205 float minY;
8206 float maxY;
8207 float minZ;
8208 float maxZ;
8209
8210 // This BBox is in sim coordinates, with the offset being
8211 // a contained point.
8212 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8213 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8214
8215 minX -= offsets[0].X;
8216 maxX -= offsets[0].X;
8217 minY -= offsets[0].Y;
8218 maxY -= offsets[0].Y;
8219 minZ -= offsets[0].Z;
8220 maxZ -= offsets[0].Z;
8221
8222 LSL_Vector lower;
8223 LSL_Vector upper;
8224
8225 // Adjust to the documented error offsets (see LSL Wiki)
8226 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8227 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8228
8229 if (lower.x > upper.x)
8230 lower.x = upper.x;
8231 if (lower.y > upper.y)
8232 lower.y = upper.y;
8233 if (lower.z > upper.z)
8234 lower.z = upper.z;
8235
7702 result.Add(lower); 8236 result.Add(lower);
7703 result.Add(upper); 8237 result.Add(upper);
7704 return result; 8238 return result;
@@ -7778,13 +8312,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7778 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8312 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7779 part.AbsolutePosition.Y, 8313 part.AbsolutePosition.Y,
7780 part.AbsolutePosition.Z); 8314 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); 8315 res.Add(v);
7789 break; 8316 break;
7790 8317
@@ -7955,56 +8482,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8482 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7956 if (remain < 1) 8483 if (remain < 1)
7957 return res; 8484 return res;
7958 8485 face = (int)rules.GetLSLIntegerItem(idx++);
7959 face=(int)rules.GetLSLIntegerItem(idx++);
7960 8486
7961 tex = part.Shape.Textures; 8487 tex = part.Shape.Textures;
8488 int shiny;
7962 if (face == ScriptBaseClass.ALL_SIDES) 8489 if (face == ScriptBaseClass.ALL_SIDES)
7963 { 8490 {
7964 for (face = 0; face < GetNumberOfSides(part); face++) 8491 for (face = 0; face < GetNumberOfSides(part); face++)
7965 { 8492 {
7966 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8493 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7967 // Convert Shininess to PRIM_SHINY_* 8494 if (shinyness == Shininess.High)
7968 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8495 {
7969 // PRIM_BUMP_* 8496 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7970 res.Add(new LSL_Integer((int)texface.Bump)); 8497 }
8498 else if (shinyness == Shininess.Medium)
8499 {
8500 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8501 }
8502 else if (shinyness == Shininess.Low)
8503 {
8504 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8505 }
8506 else
8507 {
8508 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8509 }
8510 res.Add(new LSL_Integer(shiny));
8511 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7971 } 8512 }
7972 } 8513 }
7973 else 8514 else
7974 { 8515 {
7975 if (face >= 0 && face < GetNumberOfSides(part)) 8516 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8517 if (shinyness == Shininess.High)
7976 { 8518 {
7977 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8519 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7978 // Convert Shininess to PRIM_SHINY_* 8520 }
7979 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8521 else if (shinyness == Shininess.Medium)
7980 // PRIM_BUMP_* 8522 {
7981 res.Add(new LSL_Integer((int)texface.Bump)); 8523 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8524 }
8525 else if (shinyness == Shininess.Low)
8526 {
8527 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
7982 } 8528 }
8529 else
8530 {
8531 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8532 }
8533 res.Add(new LSL_Integer(shiny));
8534 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7983 } 8535 }
7984 break; 8536 break;
7985 8537
7986 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8538 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7987 if (remain < 1) 8539 if (remain < 1)
7988 return res; 8540 return res;
7989 8541 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8542
7992 tex = part.Shape.Textures; 8543 tex = part.Shape.Textures;
8544 int fullbright;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8545 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8546 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8547 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8548 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8549 if (tex.GetFace((uint)face).Fullbright == true)
7998 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8550 {
8551 fullbright = ScriptBaseClass.TRUE;
8552 }
8553 else
8554 {
8555 fullbright = ScriptBaseClass.FALSE;
8556 }
8557 res.Add(new LSL_Integer(fullbright));
7999 } 8558 }
8000 } 8559 }
8001 else 8560 else
8002 { 8561 {
8003 if (face >= 0 && face < GetNumberOfSides(part)) 8562 if (tex.GetFace((uint)face).Fullbright == true)
8004 { 8563 {
8005 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8564 fullbright = ScriptBaseClass.TRUE;
8006 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8007 } 8565 }
8566 else
8567 {
8568 fullbright = ScriptBaseClass.FALSE;
8569 }
8570 res.Add(new LSL_Integer(fullbright));
8008 } 8571 }
8009 break; 8572 break;
8010 8573
@@ -8026,27 +8589,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8026 break; 8589 break;
8027 8590
8028 case (int)ScriptBaseClass.PRIM_TEXGEN: 8591 case (int)ScriptBaseClass.PRIM_TEXGEN:
8592 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8029 if (remain < 1) 8593 if (remain < 1)
8030 return res; 8594 return res;
8031 8595 face = (int)rules.GetLSLIntegerItem(idx++);
8032 face=(int)rules.GetLSLIntegerItem(idx++);
8033 8596
8034 tex = part.Shape.Textures; 8597 tex = part.Shape.Textures;
8035 if (face == ScriptBaseClass.ALL_SIDES) 8598 if (face == ScriptBaseClass.ALL_SIDES)
8036 { 8599 {
8037 for (face = 0; face < GetNumberOfSides(part); face++) 8600 for (face = 0; face < GetNumberOfSides(part); face++)
8038 { 8601 {
8039 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8602 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8040 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8603 {
8041 res.Add(new LSL_Integer((uint)texgen >> 1)); 8604 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8605 }
8606 else
8607 {
8608 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8609 }
8042 } 8610 }
8043 } 8611 }
8044 else 8612 else
8045 { 8613 {
8046 if (face >= 0 && face < GetNumberOfSides(part)) 8614 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8615 {
8616 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8617 }
8618 else
8047 { 8619 {
8048 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8620 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8049 res.Add(new LSL_Integer((uint)texgen >> 1));
8050 } 8621 }
8051 } 8622 }
8052 break; 8623 break;
@@ -8069,28 +8640,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8069 case (int)ScriptBaseClass.PRIM_GLOW: 8640 case (int)ScriptBaseClass.PRIM_GLOW:
8070 if (remain < 1) 8641 if (remain < 1)
8071 return res; 8642 return res;
8072 8643 face = (int)rules.GetLSLIntegerItem(idx++);
8073 face=(int)rules.GetLSLIntegerItem(idx++);
8074 8644
8075 tex = part.Shape.Textures; 8645 tex = part.Shape.Textures;
8646 float primglow;
8076 if (face == ScriptBaseClass.ALL_SIDES) 8647 if (face == ScriptBaseClass.ALL_SIDES)
8077 { 8648 {
8078 for (face = 0; face < GetNumberOfSides(part); face++) 8649 for (face = 0; face < GetNumberOfSides(part); face++)
8079 { 8650 {
8080 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8651 primglow = tex.GetFace((uint)face).Glow;
8081 res.Add(new LSL_Float(texface.Glow)); 8652 res.Add(new LSL_Float(primglow));
8082 } 8653 }
8083 } 8654 }
8084 else 8655 else
8085 { 8656 {
8086 if (face >= 0 && face < GetNumberOfSides(part)) 8657 primglow = tex.GetFace((uint)face).Glow;
8087 { 8658 res.Add(new LSL_Float(primglow));
8088 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8089 res.Add(new LSL_Float(texface.Glow));
8090 }
8091 } 8659 }
8092 break; 8660 break;
8093
8094 case (int)ScriptBaseClass.PRIM_TEXT: 8661 case (int)ScriptBaseClass.PRIM_TEXT:
8095 Color4 textColor = part.GetTextColor(); 8662 Color4 textColor = part.GetTextColor();
8096 res.Add(new LSL_String(part.Text)); 8663 res.Add(new LSL_String(part.Text));
@@ -8642,8 +9209,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8642 // The function returns an ordered list 9209 // The function returns an ordered list
8643 // representing the tokens found in the supplied 9210 // representing the tokens found in the supplied
8644 // sources string. If two successive tokenizers 9211 // sources string. If two successive tokenizers
8645 // are encountered, then a NULL entry is added 9212 // are encountered, then a null-string entry is
8646 // to the list. 9213 // added to the list.
8647 // 9214 //
8648 // It is a precondition that the source and 9215 // It is a precondition that the source and
8649 // toekizer lisst are non-null. If they are null, 9216 // toekizer lisst are non-null. If they are null,
@@ -8651,7 +9218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8651 // while their lengths are being determined. 9218 // while their lengths are being determined.
8652 // 9219 //
8653 // A small amount of working memoryis required 9220 // A small amount of working memoryis required
8654 // of approximately 8*#tokenizers. 9221 // of approximately 8*#tokenizers + 8*srcstrlen.
8655 // 9222 //
8656 // There are many ways in which this function 9223 // There are many ways in which this function
8657 // can be implemented, this implementation is 9224 // can be implemented, this implementation is
@@ -8667,155 +9234,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8667 // and eliminates redundant tokenizers as soon 9234 // and eliminates redundant tokenizers as soon
8668 // as is possible. 9235 // as is possible.
8669 // 9236 //
8670 // The implementation tries to avoid any copying 9237 // The implementation tries to minimize temporary
8671 // of arrays or other objects. 9238 // garbage generation.
8672 // </remarks> 9239 // </remarks>
8673 9240
8674 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9241 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8675 { 9242 {
8676 int beginning = 0; 9243 return ParseString2List(src, separators, spacers, true);
8677 int srclen = src.Length; 9244 }
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 9245
8692 LSL_List tokens = new LSL_List(); 9246 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9247 {
9248 int srclen = src.Length;
9249 int seplen = separators.Length;
9250 object[] separray = separators.Data;
9251 int spclen = spacers.Length;
9252 object[] spcarray = spacers.Data;
9253 int dellen = 0;
9254 string[] delarray = new string[seplen+spclen];
8693 9255
8694 // All entries are initially valid 9256 int outlen = 0;
9257 string[] outarray = new string[srclen*2+1];
8695 9258
8696 for (int i = 0; i < mlen; i++) 9259 int i, j;
8697 active[i] = true; 9260 string d;
8698 9261
8699 offset[mlen] = srclen; 9262 m_host.AddScriptLPS(1);
8700 9263
8701 while (beginning < srclen) 9264 /*
9265 * Convert separator and spacer lists to C# strings.
9266 * Also filter out null strings so we don't hang.
9267 */
9268 for (i = 0; i < seplen; i ++)
8702 { 9269 {
9270 d = separray[i].ToString();
9271 if (d.Length > 0)
9272 {
9273 delarray[dellen++] = d;
9274 }
9275 }
9276 seplen = dellen;
8703 9277
8704 best = mlen; // as bad as it gets 9278 for (i = 0; i < spclen; i ++)
9279 {
9280 d = spcarray[i].ToString();
9281 if (d.Length > 0)
9282 {
9283 delarray[dellen++] = d;
9284 }
9285 }
8705 9286
8706 // Scan for separators 9287 /*
9288 * Scan through source string from beginning to end.
9289 */
9290 for (i = 0;;)
9291 {
8707 9292
8708 for (j = 0; j < seplen; j++) 9293 /*
9294 * Find earliest delimeter in src starting at i (if any).
9295 */
9296 int earliestDel = -1;
9297 int earliestSrc = srclen;
9298 string earliestStr = null;
9299 for (j = 0; j < dellen; j ++)
8709 { 9300 {
8710 if (separray[j].ToString() == String.Empty) 9301 d = delarray[j];
8711 active[j] = false; 9302 if (d != null)
8712
8713 if (active[j])
8714 { 9303 {
8715 // scan all of the markers 9304 int index = src.IndexOf(d, i);
8716 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9305 if (index < 0)
8717 { 9306 {
8718 // not present at all 9307 delarray[j] = null; // delim nowhere in src, don't check it anymore
8719 active[j] = false;
8720 } 9308 }
8721 else 9309 else if (index < earliestSrc)
8722 { 9310 {
8723 // present and correct 9311 earliestSrc = index; // where delimeter starts in source string
8724 if (offset[j] < offset[best]) 9312 earliestDel = j; // where delimeter is in delarray[]
8725 { 9313 earliestStr = d; // the delimeter string from delarray[]
8726 // closest so far 9314 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 } 9315 }
8732 } 9316 }
8733 } 9317 }
8734 9318
8735 // Scan for spacers 9319 /*
8736 9320 * Output source string starting at i through start of earliest delimeter.
8737 if (offset[best] != beginning) 9321 */
9322 if (keepNulls || (earliestSrc > i))
8738 { 9323 {
8739 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9324 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 } 9325 }
8764 9326
8765 // This is the normal exit from the scanning loop 9327 /*
9328 * If no delimeter found at or after i, we're done scanning.
9329 */
9330 if (earliestDel < 0) break;
8766 9331
8767 if (best == mlen) 9332 /*
9333 * If delimeter was a spacer, output the spacer.
9334 */
9335 if (earliestDel >= seplen)
8768 { 9336 {
8769 // no markers were found on this pass 9337 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 } 9338 }
8775 9339
8776 // Otherwise we just add the newly delimited token 9340 /*
8777 // and recalculate where the search should continue. 9341 * Look at rest of src string following delimeter.
8778 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9342 */
8779 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9343 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 } 9344 }
8793 9345
8794 // This an awkward an not very intuitive boundary case. If the 9346 /*
8795 // last substring is a tokenizer, then there is an implied trailing 9347 * 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 9348 */
8797 // arduous. Alternatively the 'break' could be replced with a return 9349 object[] outlist = new object[outlen];
8798 // but that's shabby programming. 9350 for (i = 0; i < outlen; i ++)
8799
8800 if ((beginning == srclen) && (keepNulls))
8801 { 9351 {
8802 if (srclen != 0) 9352 outlist[i] = new LSL_String(outarray[i]);
8803 tokens.Add(new LSL_String(""));
8804 } 9353 }
8805 9354 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 } 9355 }
8820 9356
8821 public LSL_Integer llGetObjectPermMask(int mask) 9357 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8892,28 +9428,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8892 { 9428 {
8893 m_host.AddScriptLPS(1); 9429 m_host.AddScriptLPS(1);
8894 9430
8895 lock (m_host.TaskInventory) 9431 m_host.TaskInventory.LockItemsForRead(true);
9432 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8896 { 9433 {
8897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9434 if (inv.Value.Name == item)
8898 { 9435 {
8899 if (inv.Value.Name == item) 9436 m_host.TaskInventory.LockItemsForRead(false);
9437 switch (mask)
8900 { 9438 {
8901 switch (mask) 9439 case 0:
8902 { 9440 return (int)inv.Value.BasePermissions;
8903 case 0: 9441 case 1:
8904 return (int)inv.Value.BasePermissions; 9442 return (int)inv.Value.CurrentPermissions;
8905 case 1: 9443 case 2:
8906 return (int)inv.Value.CurrentPermissions; 9444 return (int)inv.Value.GroupPermissions;
8907 case 2: 9445 case 3:
8908 return (int)inv.Value.GroupPermissions; 9446 return (int)inv.Value.EveryonePermissions;
8909 case 3: 9447 case 4:
8910 return (int)inv.Value.EveryonePermissions; 9448 return (int)inv.Value.NextPermissions;
8911 case 4:
8912 return (int)inv.Value.NextPermissions;
8913 }
8914 } 9449 }
8915 } 9450 }
8916 } 9451 }
9452 m_host.TaskInventory.LockItemsForRead(false);
8917 9453
8918 return -1; 9454 return -1;
8919 } 9455 }
@@ -8960,16 +9496,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8960 { 9496 {
8961 m_host.AddScriptLPS(1); 9497 m_host.AddScriptLPS(1);
8962 9498
8963 lock (m_host.TaskInventory) 9499 m_host.TaskInventory.LockItemsForRead(true);
9500 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8964 { 9501 {
8965 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9502 if (inv.Value.Name == item)
8966 { 9503 {
8967 if (inv.Value.Name == item) 9504 m_host.TaskInventory.LockItemsForRead(false);
8968 { 9505 return inv.Value.CreatorID.ToString();
8969 return inv.Value.CreatorID.ToString();
8970 }
8971 } 9506 }
8972 } 9507 }
9508 m_host.TaskInventory.LockItemsForRead(false);
8973 9509
8974 llSay(0, "No item name '" + item + "'"); 9510 llSay(0, "No item name '" + item + "'");
8975 9511
@@ -9117,7 +9653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 } 9653 }
9118 9654
9119 /// <summary> 9655 /// <summary>
9120 /// illListReplaceList removes the sub-list defined by the inclusive indices 9656 /// llListReplaceList removes the sub-list defined by the inclusive indices
9121 /// start and end and inserts the src list in its place. The inclusive 9657 /// 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 9658 /// 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 9659 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9174,16 +9710,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9174 // based upon end. Note that if end exceeds the upper 9710 // based upon end. Note that if end exceeds the upper
9175 // bound in this case, the entire destination list 9711 // bound in this case, the entire destination list
9176 // is removed. 9712 // is removed.
9177 else 9713 else if (start == 0)
9178 { 9714 {
9179 if (end + 1 < dest.Length) 9715 if (end + 1 < dest.Length)
9180 {
9181 return src + dest.GetSublist(end + 1, -1); 9716 return src + dest.GetSublist(end + 1, -1);
9182 }
9183 else 9717 else
9184 {
9185 return src; 9718 return src;
9186 } 9719 }
9720 else // Start < 0
9721 {
9722 if (end + 1 < dest.Length)
9723 return dest.GetSublist(end + 1, -1);
9724 else
9725 return new LSL_List();
9187 } 9726 }
9188 } 9727 }
9189 // Finally, if start > end, we strip away a prefix and 9728 // Finally, if start > end, we strip away a prefix and
@@ -9234,17 +9773,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9234 int width = 0; 9773 int width = 0;
9235 int height = 0; 9774 int height = 0;
9236 9775
9237 ParcelMediaCommandEnum? commandToSend = null; 9776 uint commandToSend = 0;
9238 float time = 0.0f; // default is from start 9777 float time = 0.0f; // default is from start
9239 9778
9240 ScenePresence presence = null; 9779 ScenePresence presence = null;
9241 9780
9242 for (int i = 0; i < commandList.Data.Length; i++) 9781 for (int i = 0; i < commandList.Data.Length; i++)
9243 { 9782 {
9244 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9783 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9245 switch (command) 9784 switch (command)
9246 { 9785 {
9247 case ParcelMediaCommandEnum.Agent: 9786 case (uint)ParcelMediaCommandEnum.Agent:
9248 // we send only to one agent 9787 // we send only to one agent
9249 if ((i + 1) < commandList.Length) 9788 if ((i + 1) < commandList.Length)
9250 { 9789 {
@@ -9261,25 +9800,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 } 9800 }
9262 break; 9801 break;
9263 9802
9264 case ParcelMediaCommandEnum.Loop: 9803 case (uint)ParcelMediaCommandEnum.Loop:
9265 loop = 1; 9804 loop = 1;
9266 commandToSend = command; 9805 commandToSend = command;
9267 update = true; //need to send the media update packet to set looping 9806 update = true; //need to send the media update packet to set looping
9268 break; 9807 break;
9269 9808
9270 case ParcelMediaCommandEnum.Play: 9809 case (uint)ParcelMediaCommandEnum.Play:
9271 loop = 0; 9810 loop = 0;
9272 commandToSend = command; 9811 commandToSend = command;
9273 update = true; //need to send the media update packet to make sure it doesn't loop 9812 update = true; //need to send the media update packet to make sure it doesn't loop
9274 break; 9813 break;
9275 9814
9276 case ParcelMediaCommandEnum.Pause: 9815 case (uint)ParcelMediaCommandEnum.Pause:
9277 case ParcelMediaCommandEnum.Stop: 9816 case (uint)ParcelMediaCommandEnum.Stop:
9278 case ParcelMediaCommandEnum.Unload: 9817 case (uint)ParcelMediaCommandEnum.Unload:
9279 commandToSend = command; 9818 commandToSend = command;
9280 break; 9819 break;
9281 9820
9282 case ParcelMediaCommandEnum.Url: 9821 case (uint)ParcelMediaCommandEnum.Url:
9283 if ((i + 1) < commandList.Length) 9822 if ((i + 1) < commandList.Length)
9284 { 9823 {
9285 if (commandList.Data[i + 1] is LSL_String) 9824 if (commandList.Data[i + 1] is LSL_String)
@@ -9292,7 +9831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9831 }
9293 break; 9832 break;
9294 9833
9295 case ParcelMediaCommandEnum.Texture: 9834 case (uint)ParcelMediaCommandEnum.Texture:
9296 if ((i + 1) < commandList.Length) 9835 if ((i + 1) < commandList.Length)
9297 { 9836 {
9298 if (commandList.Data[i + 1] is LSL_String) 9837 if (commandList.Data[i + 1] is LSL_String)
@@ -9305,7 +9844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9305 } 9844 }
9306 break; 9845 break;
9307 9846
9308 case ParcelMediaCommandEnum.Time: 9847 case (uint)ParcelMediaCommandEnum.Time:
9309 if ((i + 1) < commandList.Length) 9848 if ((i + 1) < commandList.Length)
9310 { 9849 {
9311 if (commandList.Data[i + 1] is LSL_Float) 9850 if (commandList.Data[i + 1] is LSL_Float)
@@ -9317,7 +9856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9317 } 9856 }
9318 break; 9857 break;
9319 9858
9320 case ParcelMediaCommandEnum.AutoAlign: 9859 case (uint)ParcelMediaCommandEnum.AutoAlign:
9321 if ((i + 1) < commandList.Length) 9860 if ((i + 1) < commandList.Length)
9322 { 9861 {
9323 if (commandList.Data[i + 1] is LSL_Integer) 9862 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9331,7 +9870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9331 } 9870 }
9332 break; 9871 break;
9333 9872
9334 case ParcelMediaCommandEnum.Type: 9873 case (uint)ParcelMediaCommandEnum.Type:
9335 if ((i + 1) < commandList.Length) 9874 if ((i + 1) < commandList.Length)
9336 { 9875 {
9337 if (commandList.Data[i + 1] is LSL_String) 9876 if (commandList.Data[i + 1] is LSL_String)
@@ -9344,7 +9883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9344 } 9883 }
9345 break; 9884 break;
9346 9885
9347 case ParcelMediaCommandEnum.Desc: 9886 case (uint)ParcelMediaCommandEnum.Desc:
9348 if ((i + 1) < commandList.Length) 9887 if ((i + 1) < commandList.Length)
9349 { 9888 {
9350 if (commandList.Data[i + 1] is LSL_String) 9889 if (commandList.Data[i + 1] is LSL_String)
@@ -9357,7 +9896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 } 9896 }
9358 break; 9897 break;
9359 9898
9360 case ParcelMediaCommandEnum.Size: 9899 case (uint)ParcelMediaCommandEnum.Size:
9361 if ((i + 2) < commandList.Length) 9900 if ((i + 2) < commandList.Length)
9362 { 9901 {
9363 if (commandList.Data[i + 1] is LSL_Integer) 9902 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9427,7 +9966,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9427 } 9966 }
9428 } 9967 }
9429 9968
9430 if (commandToSend != null) 9969 if (commandToSend != 0)
9431 { 9970 {
9432 // the commandList contained a start/stop/... command, too 9971 // the commandList contained a start/stop/... command, too
9433 if (presence == null) 9972 if (presence == null)
@@ -9464,7 +10003,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 10003
9465 if (aList.Data[i] != null) 10004 if (aList.Data[i] != null)
9466 { 10005 {
9467 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10006 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9468 { 10007 {
9469 case ParcelMediaCommandEnum.Url: 10008 case ParcelMediaCommandEnum.Url:
9470 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10009 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9507,16 +10046,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9507 { 10046 {
9508 m_host.AddScriptLPS(1); 10047 m_host.AddScriptLPS(1);
9509 10048
9510 lock (m_host.TaskInventory) 10049 m_host.TaskInventory.LockItemsForRead(true);
10050 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9511 { 10051 {
9512 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10052 if (inv.Value.Name == name)
9513 { 10053 {
9514 if (inv.Value.Name == name) 10054 m_host.TaskInventory.LockItemsForRead(false);
9515 { 10055 return inv.Value.Type;
9516 return inv.Value.Type;
9517 }
9518 } 10056 }
9519 } 10057 }
10058 m_host.TaskInventory.LockItemsForRead(false);
9520 10059
9521 return -1; 10060 return -1;
9522 } 10061 }
@@ -9527,15 +10066,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 10066
9528 if (quick_pay_buttons.Data.Length < 4) 10067 if (quick_pay_buttons.Data.Length < 4)
9529 { 10068 {
9530 LSLError("List must have at least 4 elements"); 10069 int x;
9531 return; 10070 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10071 {
10072 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10073 }
9532 } 10074 }
9533 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10075 int[] nPrice = new int[5];
9534 10076 nPrice[0] = price;
9535 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10077 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9536 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10078 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9537 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10079 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9538 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10080 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10081 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9539 m_host.ParentGroup.HasGroupChanged = true; 10082 m_host.ParentGroup.HasGroupChanged = true;
9540 } 10083 }
9541 10084
@@ -9547,17 +10090,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9547 if (invItemID == UUID.Zero) 10090 if (invItemID == UUID.Zero)
9548 return new LSL_Vector(); 10091 return new LSL_Vector();
9549 10092
9550 lock (m_host.TaskInventory) 10093 m_host.TaskInventory.LockItemsForRead(true);
10094 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9551 { 10095 {
9552 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10096 m_host.TaskInventory.LockItemsForRead(false);
9553 return new LSL_Vector(); 10097 return new LSL_Vector();
10098 }
9554 10099
9555 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10100 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9556 { 10101 {
9557 ShoutError("No permissions to track the camera"); 10102 ShoutError("No permissions to track the camera");
9558 return new LSL_Vector(); 10103 m_host.TaskInventory.LockItemsForRead(false);
9559 } 10104 return new LSL_Vector();
9560 } 10105 }
10106 m_host.TaskInventory.LockItemsForRead(false);
9561 10107
9562 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10108 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9563 if (presence != null) 10109 if (presence != null)
@@ -9575,17 +10121,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9575 if (invItemID == UUID.Zero) 10121 if (invItemID == UUID.Zero)
9576 return new LSL_Rotation(); 10122 return new LSL_Rotation();
9577 10123
9578 lock (m_host.TaskInventory) 10124 m_host.TaskInventory.LockItemsForRead(true);
10125 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9579 { 10126 {
9580 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10127 m_host.TaskInventory.LockItemsForRead(false);
9581 return new LSL_Rotation(); 10128 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 } 10129 }
10130 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10131 {
10132 ShoutError("No permissions to track the camera");
10133 m_host.TaskInventory.LockItemsForRead(false);
10134 return new LSL_Rotation();
10135 }
10136 m_host.TaskInventory.LockItemsForRead(false);
9589 10137
9590 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10138 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9591 if (presence != null) 10139 if (presence != null)
@@ -9647,8 +10195,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 { 10195 {
9648 m_host.AddScriptLPS(1); 10196 m_host.AddScriptLPS(1);
9649 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10197 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9650 if (detectedParams == null) return; // only works on the first detected avatar 10198 if (detectedParams == null)
9651 10199 {
10200 if (m_host.ParentGroup.IsAttachment == true)
10201 {
10202 detectedParams = new DetectParams();
10203 detectedParams.Key = m_host.OwnerID;
10204 }
10205 else
10206 {
10207 return;
10208 }
10209 }
10210
9652 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10211 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9653 if (avatar != null) 10212 if (avatar != null)
9654 { 10213 {
@@ -9656,6 +10215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10215 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9657 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10216 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9658 } 10217 }
10218
9659 ScriptSleep(1000); 10219 ScriptSleep(1000);
9660 } 10220 }
9661 10221
@@ -9748,14 +10308,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9748 if (objectID == UUID.Zero) return; 10308 if (objectID == UUID.Zero) return;
9749 10309
9750 UUID agentID; 10310 UUID agentID;
9751 lock (m_host.TaskInventory) 10311 m_host.TaskInventory.LockItemsForRead(true);
9752 { 10312 // 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 10313 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9754 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9755 10314
9756 if (agentID == UUID.Zero) return; 10315 if (agentID == UUID.Zero)
9757 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10316 {
10317 m_host.TaskInventory.LockItemsForRead(false);
10318 return;
10319 }
10320 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10321 {
10322 m_host.TaskInventory.LockItemsForRead(false);
10323 return;
9758 } 10324 }
10325 m_host.TaskInventory.LockItemsForRead(false);
9759 10326
9760 ScenePresence presence = World.GetScenePresence(agentID); 10327 ScenePresence presence = World.GetScenePresence(agentID);
9761 10328
@@ -9764,12 +10331,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9764 10331
9765 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10332 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9766 object[] data = rules.Data; 10333 object[] data = rules.Data;
9767 for (int i = 0; i < data.Length; ++i) { 10334 for (int i = 0; i < data.Length; ++i)
10335 {
9768 int type = Convert.ToInt32(data[i++].ToString()); 10336 int type = Convert.ToInt32(data[i++].ToString());
9769 if (i >= data.Length) break; // odd number of entries => ignore the last 10337 if (i >= data.Length) break; // odd number of entries => ignore the last
9770 10338
9771 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10339 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9772 switch (type) { 10340 switch (type)
10341 {
9773 case ScriptBaseClass.CAMERA_FOCUS: 10342 case ScriptBaseClass.CAMERA_FOCUS:
9774 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10343 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9775 case ScriptBaseClass.CAMERA_POSITION: 10344 case ScriptBaseClass.CAMERA_POSITION:
@@ -9805,12 +10374,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 10374
9806 // we need the permission first, to know which avatar we want to clear the camera for 10375 // we need the permission first, to know which avatar we want to clear the camera for
9807 UUID agentID; 10376 UUID agentID;
9808 lock (m_host.TaskInventory) 10377 m_host.TaskInventory.LockItemsForRead(true);
10378 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10379 if (agentID == UUID.Zero)
10380 {
10381 m_host.TaskInventory.LockItemsForRead(false);
10382 return;
10383 }
10384 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9809 { 10385 {
9810 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10386 m_host.TaskInventory.LockItemsForRead(false);
9811 if (agentID == UUID.Zero) return; 10387 return;
9812 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9813 } 10388 }
10389 m_host.TaskInventory.LockItemsForRead(false);
9814 10390
9815 ScenePresence presence = World.GetScenePresence(agentID); 10391 ScenePresence presence = World.GetScenePresence(agentID);
9816 10392
@@ -9877,19 +10453,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9877 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10453 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9878 { 10454 {
9879 m_host.AddScriptLPS(1); 10455 m_host.AddScriptLPS(1);
9880 string ret = String.Empty; 10456
9881 string src1 = llBase64ToString(str1); 10457 if (str1 == String.Empty)
9882 string src2 = llBase64ToString(str2); 10458 return String.Empty;
9883 int c = 0; 10459 if (str2 == String.Empty)
9884 for (int i = 0; i < src1.Length; i++) 10460 return str1;
10461
10462 int len = str2.Length;
10463 if ((len % 4) != 0) // LL is EVIL!!!!
10464 {
10465 while (str2.EndsWith("="))
10466 str2 = str2.Substring(0, str2.Length - 1);
10467
10468 len = str2.Length;
10469 int mod = len % 4;
10470
10471 if (mod == 1)
10472 str2 = str2.Substring(0, str2.Length - 1);
10473 else if (mod == 2)
10474 str2 += "==";
10475 else if (mod == 3)
10476 str2 += "=";
10477 }
10478
10479 byte[] data1;
10480 byte[] data2;
10481 try
9885 { 10482 {
9886 ret += (char) (src1[i] ^ src2[c]); 10483 data1 = Convert.FromBase64String(str1);
10484 data2 = Convert.FromBase64String(str2);
10485 }
10486 catch (Exception)
10487 {
10488 return new LSL_String(String.Empty);
10489 }
9887 10490
9888 c++; 10491 byte[] d2 = new Byte[data1.Length];
9889 if (c >= src2.Length) 10492 int pos = 0;
9890 c = 0; 10493
10494 if (data1.Length <= data2.Length)
10495 {
10496 Array.Copy(data2, 0, d2, 0, data1.Length);
9891 } 10497 }
9892 return llStringToBase64(ret); 10498 else
10499 {
10500 while (pos < data1.Length)
10501 {
10502 len = data1.Length - pos;
10503 if (len > data2.Length)
10504 len = data2.Length;
10505
10506 Array.Copy(data2, 0, d2, pos, len);
10507 pos += len;
10508 }
10509 }
10510
10511 for (pos = 0 ; pos < data1.Length ; pos++ )
10512 data1[pos] ^= d2[pos];
10513
10514 return Convert.ToBase64String(data1);
9893 } 10515 }
9894 10516
9895 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10517 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9946,12 +10568,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9946 Regex r = new Regex(authregex); 10568 Regex r = new Regex(authregex);
9947 int[] gnums = r.GetGroupNumbers(); 10569 int[] gnums = r.GetGroupNumbers();
9948 Match m = r.Match(url); 10570 Match m = r.Match(url);
9949 if (m.Success) { 10571 if (m.Success)
9950 for (int i = 1; i < gnums.Length; i++) { 10572 {
10573 for (int i = 1; i < gnums.Length; i++)
10574 {
9951 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10575 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9952 //CaptureCollection cc = g.Captures; 10576 //CaptureCollection cc = g.Captures;
9953 } 10577 }
9954 if (m.Groups.Count == 5) { 10578 if (m.Groups.Count == 5)
10579 {
9955 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10580 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(); 10581 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9957 } 10582 }
@@ -10237,15 +10862,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10237 10862
10238 internal UUID ScriptByName(string name) 10863 internal UUID ScriptByName(string name)
10239 { 10864 {
10240 lock (m_host.TaskInventory) 10865 m_host.TaskInventory.LockItemsForRead(true);
10866
10867 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10241 { 10868 {
10242 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10869 if (item.Type == 10 && item.Name == name)
10243 { 10870 {
10244 if (item.Type == 10 && item.Name == name) 10871 m_host.TaskInventory.LockItemsForRead(false);
10245 return item.ItemID; 10872 return item.ItemID;
10246 } 10873 }
10247 } 10874 }
10248 10875
10876 m_host.TaskInventory.LockItemsForRead(false);
10877
10249 return UUID.Zero; 10878 return UUID.Zero;
10250 } 10879 }
10251 10880
@@ -10286,6 +10915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10286 { 10915 {
10287 m_host.AddScriptLPS(1); 10916 m_host.AddScriptLPS(1);
10288 10917
10918 //Clone is thread safe
10289 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10919 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10290 10920
10291 UUID assetID = UUID.Zero; 10921 UUID assetID = UUID.Zero;
@@ -10348,6 +10978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10348 { 10978 {
10349 m_host.AddScriptLPS(1); 10979 m_host.AddScriptLPS(1);
10350 10980
10981 //Clone is thread safe
10351 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10982 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10352 10983
10353 UUID assetID = UUID.Zero; 10984 UUID assetID = UUID.Zero;
@@ -10428,15 +11059,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10428 return GetLinkPrimitiveParams(obj, rules); 11059 return GetLinkPrimitiveParams(obj, rules);
10429 } 11060 }
10430 11061
10431 public void print(string str) 11062 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10432 { 11063 {
10433 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11064 List<SceneObjectPart> parts = GetLinkParts(link);
10434 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11065 if (parts.Count < 1)
10435 if (ossl != null) 11066 return 0;
10436 { 11067
10437 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11068 return GetNumberOfSides(parts[0]);
10438 m_log.Info("LSL print():" + str);
10439 }
10440 } 11069 }
10441 11070
10442 private string Name2Username(string name) 11071 private string Name2Username(string name)
@@ -10482,153 +11111,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10482 return rq.ToString(); 11111 return rq.ToString();
10483 } 11112 }
10484 11113
11114 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11115 {
11116 m_SayShoutCount = 0;
11117 }
11118
11119 private struct Tri
11120 {
11121 public Vector3 p1;
11122 public Vector3 p2;
11123 public Vector3 p3;
11124 }
11125
11126 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11127 {
11128 float height = avatar.Appearance.AvatarHeight;
11129 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11130 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11131
11132 if (point.X > b1.X && point.X < b2.X &&
11133 point.Y > b1.Y && point.Y < b2.Y &&
11134 point.Z > b1.Z && point.Z < b2.Z)
11135 return true;
11136 return false;
11137 }
11138
11139 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11140 {
11141 List<ContactResult> contacts = new List<ContactResult>();
11142
11143 Vector3 ab = rayEnd - rayStart;
11144
11145 World.ForEachScenePresence(delegate(ScenePresence sp)
11146 {
11147 Vector3 ac = sp.AbsolutePosition - rayStart;
11148 Vector3 bc = sp.AbsolutePosition - rayEnd;
11149
11150 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11151
11152 if (d > 1.5)
11153 return;
11154
11155 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11156
11157 if (d2 > 0)
11158 return;
11159
11160 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11161 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11162
11163 if (!InBoundingBox(sp, p))
11164 return;
11165
11166 ContactResult result = new ContactResult ();
11167 result.ConsumerID = sp.LocalId;
11168 result.Depth = Vector3.Distance(rayStart, p);
11169 result.Normal = Vector3.Zero;
11170 result.Pos = p;
11171
11172 contacts.Add(result);
11173 });
11174
11175 return contacts.ToArray();
11176 }
11177
11178 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11179 {
11180 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11181 List<ContactResult> contacts = new List<ContactResult>();
11182
11183 Vector3 ab = rayEnd - rayStart;
11184
11185 World.ForEachSOG(delegate(SceneObjectGroup group)
11186 {
11187 if (m_host.ParentGroup == group)
11188 return;
11189
11190 if (group.IsAttachment)
11191 return;
11192
11193 if (group.RootPart.PhysActor == null)
11194 {
11195 if (!includePhantom)
11196 return;
11197 }
11198 else
11199 {
11200 if (group.RootPart.PhysActor.IsPhysical)
11201 {
11202 if (!includePhysical)
11203 return;
11204 }
11205 else
11206 {
11207 if (!includeNonPhysical)
11208 return;
11209 }
11210 }
11211
11212 // Find the radius ouside of which we don't even need to hit test
11213 float minX;
11214 float maxX;
11215 float minY;
11216 float maxY;
11217 float minZ;
11218 float maxZ;
11219
11220 float radius = 0.0f;
11221
11222 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11223
11224 if (Math.Abs(minX) > radius)
11225 radius = Math.Abs(minX);
11226 if (Math.Abs(minY) > radius)
11227 radius = Math.Abs(minY);
11228 if (Math.Abs(minZ) > radius)
11229 radius = Math.Abs(minZ);
11230 if (Math.Abs(maxX) > radius)
11231 radius = Math.Abs(maxX);
11232 if (Math.Abs(maxY) > radius)
11233 radius = Math.Abs(maxY);
11234 if (Math.Abs(maxZ) > radius)
11235 radius = Math.Abs(maxZ);
11236
11237 Vector3 ac = group.AbsolutePosition - rayStart;
11238 Vector3 bc = group.AbsolutePosition - rayEnd;
11239
11240 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11241
11242 // Too far off ray, don't bother
11243 if (d > radius)
11244 return;
11245
11246 // Behind ray, drop
11247 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11248 if (d2 > 0)
11249 return;
11250
11251 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11252 // Miss.
11253 if (!intersection.HitTF)
11254 return;
11255
11256 ContactResult result = new ContactResult ();
11257 result.ConsumerID = group.LocalId;
11258 result.Depth = intersection.distance;
11259 result.Normal = intersection.normal;
11260 result.Pos = intersection.ipoint;
11261
11262 contacts.Add(result);
11263 });
11264
11265 return contacts.ToArray();
11266 }
11267
11268 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11269 {
11270 double[,] heightfield = World.Heightmap.GetDoubles();
11271 List<ContactResult> contacts = new List<ContactResult>();
11272
11273 double min = 2048.0;
11274 double max = 0.0;
11275
11276 // Find the min and max of the heightfield
11277 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11278 {
11279 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11280 {
11281 if (heightfield[x, y] > max)
11282 max = heightfield[x, y];
11283 if (heightfield[x, y] < min)
11284 min = heightfield[x, y];
11285 }
11286 }
11287
11288
11289 // A ray extends past rayEnd, but doesn't go back before
11290 // rayStart. If the start is above the highest point of the ground
11291 // and the ray goes up, we can't hit the ground. Ever.
11292 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11293 return null;
11294
11295 // Same for going down
11296 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11297 return null;
11298
11299 List<Tri> trilist = new List<Tri>();
11300
11301 // Create our triangle list
11302 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11303 {
11304 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11305 {
11306 Tri t1 = new Tri();
11307 Tri t2 = new Tri();
11308
11309 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11310 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11311 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11312 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11313
11314 t1.p1 = p1;
11315 t1.p2 = p2;
11316 t1.p3 = p3;
11317
11318 t2.p1 = p3;
11319 t2.p2 = p4;
11320 t2.p3 = p1;
11321
11322 trilist.Add(t1);
11323 trilist.Add(t2);
11324 }
11325 }
11326
11327 // Ray direction
11328 Vector3 rayDirection = rayEnd - rayStart;
11329
11330 foreach (Tri t in trilist)
11331 {
11332 // Compute triangle plane normal and edges
11333 Vector3 u = t.p2 - t.p1;
11334 Vector3 v = t.p3 - t.p1;
11335 Vector3 n = Vector3.Cross(u, v);
11336
11337 if (n == Vector3.Zero)
11338 continue;
11339
11340 Vector3 w0 = rayStart - t.p1;
11341 double a = -Vector3.Dot(n, w0);
11342 double b = Vector3.Dot(n, rayDirection);
11343
11344 // Not intersecting the plane, or in plane (same thing)
11345 // Ignoring this MAY cause the ground to not be detected
11346 // sometimes
11347 if (Math.Abs(b) < 0.000001)
11348 continue;
11349
11350 double r = a / b;
11351
11352 // ray points away from plane
11353 if (r < 0.0)
11354 continue;
11355
11356 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11357
11358 float uu = Vector3.Dot(u, u);
11359 float uv = Vector3.Dot(u, v);
11360 float vv = Vector3.Dot(v, v);
11361 Vector3 w = ip - t.p1;
11362 float wu = Vector3.Dot(w, u);
11363 float wv = Vector3.Dot(w, v);
11364 float d = uv * uv - uu * vv;
11365
11366 float cs = (uv * wv - vv * wu) / d;
11367 if (cs < 0 || cs > 1.0)
11368 continue;
11369 float ct = (uv * wu - uu * wv) / d;
11370 if (ct < 0 || (cs + ct) > 1.0)
11371 continue;
11372
11373 // Add contact point
11374 ContactResult result = new ContactResult ();
11375 result.ConsumerID = 0;
11376 result.Depth = Vector3.Distance(rayStart, ip);
11377 result.Normal = n;
11378 result.Pos = ip;
11379
11380 contacts.Add(result);
11381 }
11382
11383 if (contacts.Count == 0)
11384 return null;
11385
11386 contacts.Sort(delegate(ContactResult a, ContactResult b)
11387 {
11388 return (int)(a.Depth - b.Depth);
11389 });
11390
11391 return contacts[0];
11392 }
11393
10485 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11394 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10486 { 11395 {
11396 LSL_List list = new LSL_List();
11397
10487 m_host.AddScriptLPS(1); 11398 m_host.AddScriptLPS(1);
10488 11399
10489 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11400 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); 11401 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); 11402 Vector3 dir = rayEnd - rayStart;
10492 11403
10493 int count = 0; 11404 int count = 1;
10494// int detectPhantom = 0; 11405 bool detectPhantom = false;
10495 int dataFlags = 0; 11406 int dataFlags = 0;
10496 int rejectTypes = 0; 11407 int rejectTypes = 0;
10497 11408
10498 for (int i = 0; i < options.Length; i += 2) 11409 for (int i = 0; i < options.Length; i += 2)
10499 { 11410 {
10500 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11411 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10501 {
10502 count = options.GetLSLIntegerItem(i + 1); 11412 count = options.GetLSLIntegerItem(i + 1);
10503 } 11413 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10504// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11414 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10505// {
10506// detectPhantom = options.GetLSLIntegerItem(i + 1);
10507// }
10508 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11415 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10509 {
10510 dataFlags = options.GetLSLIntegerItem(i + 1); 11416 dataFlags = options.GetLSLIntegerItem(i + 1);
10511 }
10512 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11417 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10513 {
10514 rejectTypes = options.GetLSLIntegerItem(i + 1); 11418 rejectTypes = options.GetLSLIntegerItem(i + 1);
10515 }
10516 } 11419 }
10517 11420
10518 LSL_List list = new LSL_List(); 11421 if (count > 16)
10519 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11422 count = 16;
10520
10521 double distance = Util.GetDistanceTo(startvector, endvector);
10522 11423
10523 if (distance == 0) 11424 List<ContactResult> results = new List<ContactResult>();
10524 distance = 0.001;
10525
10526 Vector3 posToCheck = startvector;
10527 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10528 11425
10529 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11426 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10530 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11427 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10531 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11428 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10532 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11429 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10533 11430
10534 for (float i = 0; i <= distance; i += 0.1f) 11431 if (checkTerrain)
10535 { 11432 {
10536 posToCheck = startvector + (dir * (i / (float)distance)); 11433 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11434 if (groundContact != null)
11435 results.Add((ContactResult)groundContact);
11436 }
10537 11437
10538 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11438 if (checkAgents)
10539 { 11439 {
10540 ContactResult result = new ContactResult(); 11440 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10541 result.ConsumerID = 0; 11441 foreach (ContactResult r in agentHits)
10542 result.Depth = 0; 11442 results.Add(r);
10543 result.Normal = Vector3.Zero; 11443 }
10544 result.Pos = posToCheck;
10545 results.Add(result);
10546 checkTerrain = false;
10547 }
10548 11444
10549 if (checkAgents) 11445 if (checkPhysical || checkNonPhysical)
10550 { 11446 {
10551 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11447 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10552 { 11448 foreach (ContactResult r in objectHits)
10553 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11449 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 } 11450 }
10565 11451
10566 int refcount = 0; 11452 results.Sort(delegate(ContactResult a, ContactResult b)
11453 {
11454 return (int)(a.Depth - b.Depth);
11455 });
11456
11457 int values = 0;
10567 foreach (ContactResult result in results) 11458 foreach (ContactResult result in results)
10568 { 11459 {
10569 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11460 UUID itemID = UUID.Zero;
10570 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11461 int linkNum = 0;
10571 continue;
10572
10573 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10574 11462
10575 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11463 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10576 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11464 // It's a prim!
10577 11465 if (part != null)
10578 if (entity == null)
10579 { 11466 {
10580 list.Add(UUID.Zero); 11467 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10581 11468 itemID = part.ParentGroup.UUID;
10582 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11469 else
10583 list.Add(0); 11470 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 11471
10590 continue; //Can't find it, so add UUID.Zero 11472 linkNum = part.LinkNum;
10591 } 11473 }
10592 11474 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 { 11475 {
10599 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11476 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10600 { 11477 /// It it a boy? a girl?
10601 if (!checkPhysical) 11478 if (sp != null)
10602 continue; 11479 itemID = sp.UUID;
10603 }
10604 else
10605 {
10606 if (!checkNonPhysical)
10607 continue;
10608 }
10609 } 11480 }
10610 11481
10611 refcount++; 11482 list.Add(new LSL_String(itemID.ToString()));
10612 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11483 list.Add(new LSL_String(result.Pos.ToString()));
10613 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10614 else
10615 list.Add(entity.UUID);
10616 11484
10617 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11485 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10618 { 11486 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 11487
10625 list.Add(result.Pos);
10626 11488
10627 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11489 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10628 list.Add(result.Normal); 11490 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11491
11492 values++;
11493 count--;
11494
11495 if (count == 0)
11496 break;
10629 } 11497 }
10630 11498
10631 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11499 list.Add(new LSL_Integer(values));
10632 11500
10633 return list; 11501 return list;
10634 } 11502 }
@@ -10651,22 +11519,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 NotImplemented("llGetSPMaxMemory"); 11519 NotImplemented("llGetSPMaxMemory");
10652 } 11520 }
10653 11521
10654 public void llGetUsedMemory() 11522 public virtual LSL_Integer llGetUsedMemory()
10655 { 11523 {
10656 m_host.AddScriptLPS(1); 11524 m_host.AddScriptLPS(1);
10657 NotImplemented("llGetUsedMemory"); 11525 NotImplemented("llGetUsedMemory");
11526 return 0;
10658 } 11527 }
10659 11528
10660 public void llScriptProfiler(LSL_Integer flags) 11529 public void llScriptProfiler(LSL_Integer flags)
10661 { 11530 {
10662 m_host.AddScriptLPS(1); 11531 m_host.AddScriptLPS(1);
10663 NotImplemented("llScriptProfiler"); 11532 //NotImplemented("llScriptProfiler");
10664 } 11533 }
10665 11534
10666 public void llSetSoundQueueing(int queue) 11535 public void llSetSoundQueueing(int queue)
10667 { 11536 {
10668 m_host.AddScriptLPS(1); 11537 m_host.AddScriptLPS(1);
10669 NotImplemented("llSetSoundQueueing");
10670 } 11538 }
10671 11539
10672 public void llCollisionSprite(string impact_sprite) 11540 public void llCollisionSprite(string impact_sprite)
@@ -10678,7 +11546,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10678 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11546 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10679 { 11547 {
10680 m_host.AddScriptLPS(1); 11548 m_host.AddScriptLPS(1);
10681 NotImplemented("llGodLikeRezObject"); 11549
11550 if (!World.Permissions.IsGod(m_host.OwnerID))
11551 NotImplemented("llGodLikeRezObject");
11552
11553 AssetBase rezAsset = World.AssetService.Get(inventory);
11554 if (rezAsset == null)
11555 {
11556 llSay(0, "Asset not found");
11557 return;
11558 }
11559
11560 SceneObjectGroup group = null;
11561
11562 try
11563 {
11564 string xmlData = Utils.BytesToString(rezAsset.Data);
11565 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11566 }
11567 catch
11568 {
11569 llSay(0, "Asset not found");
11570 return;
11571 }
11572
11573 if (group == null)
11574 {
11575 llSay(0, "Asset not found");
11576 return;
11577 }
11578
11579 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11580 group.RootPart.AttachOffset = group.AbsolutePosition;
11581
11582 group.ResetIDs();
11583
11584 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11585 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11586 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11587 group.ScheduleGroupForFullUpdate();
11588
11589 // objects rezzed with this method are die_at_edge by default.
11590 group.RootPart.SetDieAtEdge(true);
11591
11592 group.ResumeScripts();
11593
11594 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11595 "object_rez", new Object[] {
11596 new LSL_String(
11597 group.RootPart.UUID.ToString()) },
11598 new DetectParams[0]));
11599 }
11600
11601 public LSL_String llTransferLindenDollars(string destination, int amount)
11602 {
11603 UUID txn = UUID.Random();
11604
11605 Util.FireAndForget(delegate(object x)
11606 {
11607 int replycode = 0;
11608 string replydata = destination + "," + amount.ToString();
11609
11610 try
11611 {
11612 UUID invItemID=InventorySelf();
11613 if (invItemID == UUID.Zero)
11614 {
11615 replydata = "SERVICE_ERROR";
11616 return;
11617 }
11618
11619 m_host.AddScriptLPS(1);
11620
11621 m_host.TaskInventory.LockItemsForRead(true);
11622 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11623 m_host.TaskInventory.LockItemsForRead(false);
11624
11625 if (item.PermsGranter == UUID.Zero)
11626 {
11627 replydata = "MISSING_PERMISSION_DEBIT";
11628 return;
11629 }
11630
11631 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11632 {
11633 replydata = "MISSING_PERMISSION_DEBIT";
11634 return;
11635 }
11636
11637 UUID toID = new UUID();
11638
11639 if (!UUID.TryParse(destination, out toID))
11640 {
11641 replydata = "INVALID_AGENT";
11642 return;
11643 }
11644
11645 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11646
11647 if (money == null)
11648 {
11649 replydata = "TRANSFERS_DISABLED";
11650 return;
11651 }
11652
11653 bool result = money.ObjectGiveMoney(
11654 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11655
11656 if (result)
11657 {
11658 replycode = 1;
11659 return;
11660 }
11661
11662 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11663 }
11664 finally
11665 {
11666 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11667 "transaction_result", new Object[] {
11668 new LSL_String(txn.ToString()),
11669 new LSL_Integer(replycode),
11670 new LSL_String(replydata) },
11671 new DetectParams[0]));
11672 }
11673 });
11674
11675 return txn.ToString();
10682 } 11676 }
10683 11677
10684 #endregion 11678 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7792ab5..4831377 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)
@@ -2216,18 +2225,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2225
2217 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned) 2226 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned)
2218 { 2227 {
2228 if (!owned)
2229 OSSLError("Unowned NPCs are unsupported");
2230
2231 string groupTitle = String.Empty;
2232
2233 if (firstname != String.Empty || lastname != String.Empty)
2234 {
2235 if (firstname != "Shown outfit:")
2236 groupTitle = "- NPC -";
2237 }
2238
2219 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2239 INPCModule module = World.RequestModuleInterface<INPCModule>();
2220 if (module != null) 2240 if (module != null)
2221 { 2241 {
2222 AvatarAppearance appearance = null; 2242 AvatarAppearance appearance = null;
2223 2243
2224 UUID id; 2244// UUID id;
2225 if (UUID.TryParse(notecard, out id)) 2245// if (UUID.TryParse(notecard, out id))
2226 { 2246// {
2227 ScenePresence clonePresence = World.GetScenePresence(id); 2247// ScenePresence clonePresence = World.GetScenePresence(id);
2228 if (clonePresence != null) 2248// if (clonePresence != null)
2229 appearance = clonePresence.Appearance; 2249// appearance = clonePresence.Appearance;
2230 } 2250// }
2231 2251
2232 if (appearance == null) 2252 if (appearance == null)
2233 { 2253 {
@@ -2253,6 +2273,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2253 ownerID, 2273 ownerID,
2254 World,appearance); 2274 World,appearance);
2255 2275
2276 ScenePresence sp;
2277 if (World.TryGetScenePresence(x, out sp))
2278 {
2279 sp.Grouptitle = groupTitle;
2280 sp.SendAvatarDataToAllAgents();
2281 }
2256 return new LSL_Key(x.ToString()); 2282 return new LSL_Key(x.ToString());
2257 } 2283 }
2258 2284
@@ -2495,7 +2521,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2495 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2521 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2496 return; 2522 return;
2497 2523
2498 module.DeleteNPC(npcId, World); 2524 Util.FireAndForget(delegate(object x) {
2525 module.DeleteNPC(npcId, World);
2526 });
2499 } 2527 }
2500 } 2528 }
2501 2529
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 0f8cbdc..6388704 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 {