aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3087
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs7
-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.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs36
-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.cs85
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs361
19 files changed, 2915 insertions, 1161 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 786ae6e..6d4072c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -156,6 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
156 get { return m_ScriptEngine.World; } 170 get { return m_ScriptEngine.World; }
157 } 171 }
158 172
173 [DebuggerNonUserCode]
159 public void state(string newState) 174 public void state(string newState)
160 { 175 {
161 m_ScriptEngine.SetState(m_itemID, newState); 176 m_ScriptEngine.SetState(m_itemID, newState);
@@ -165,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
165 /// Reset the named script. The script must be present 180 /// Reset the named script. The script must be present
166 /// in the same prim. 181 /// in the same prim.
167 /// </summary> 182 /// </summary>
183 [DebuggerNonUserCode]
168 public void llResetScript() 184 public void llResetScript()
169 { 185 {
170 m_host.AddScriptLPS(1); 186 m_host.AddScriptLPS(1);
@@ -221,9 +237,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 } 237 }
222 } 238 }
223 239
240 public List<ScenePresence> GetLinkAvatars(int linkType)
241 {
242 List<ScenePresence> ret = new List<ScenePresence>();
243 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
244 return ret;
245
246 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
247
248 switch (linkType)
249 {
250 case ScriptBaseClass.LINK_SET:
251 return avs;
252
253 case ScriptBaseClass.LINK_ROOT:
254 return ret;
255
256 case ScriptBaseClass.LINK_ALL_OTHERS:
257 return avs;
258
259 case ScriptBaseClass.LINK_ALL_CHILDREN:
260 return avs;
261
262 case ScriptBaseClass.LINK_THIS:
263 return ret;
264
265 default:
266 if (linkType < 0)
267 return ret;
268
269 int partCount = m_host.ParentGroup.GetPartCount();
270
271 if (linkType <= partCount)
272 {
273 return ret;
274 }
275 else
276 {
277 linkType = linkType - partCount;
278 if (linkType > avs.Count)
279 {
280 return ret;
281 }
282 else
283 {
284 ret.Add(avs[linkType-1]);
285 return ret;
286 }
287 }
288 }
289 }
290
224 public List<SceneObjectPart> GetLinkParts(int linkType) 291 public List<SceneObjectPart> GetLinkParts(int linkType)
225 { 292 {
226 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 293 List<SceneObjectPart> ret = new List<SceneObjectPart>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
227 ret.Add(m_host); 296 ret.Add(m_host);
228 297
229 switch (linkType) 298 switch (linkType)
@@ -270,40 +339,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
270 protected UUID InventorySelf() 339 protected UUID InventorySelf()
271 { 340 {
272 UUID invItemID = new UUID(); 341 UUID invItemID = new UUID();
273 342 bool unlock = false;
274 lock (m_host.TaskInventory) 343 if (!m_host.TaskInventory.IsReadLockedByMe())
275 { 344 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
349 {
350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
277 { 351 {
278 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 352 invItemID = inv.Key;
279 { 353 break;
280 invItemID = inv.Key;
281 break;
282 }
283 } 354 }
284 } 355 }
285 356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
286 return invItemID; 360 return invItemID;
287 } 361 }
288 362
289 protected UUID InventoryKey(string name, int type) 363 protected UUID InventoryKey(string name, int type)
290 { 364 {
291 m_host.AddScriptLPS(1); 365 m_host.AddScriptLPS(1);
292 366 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 369 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 370 if (inv.Value.Name == name)
296 { 371 {
297 if (inv.Value.Name == name) 372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
298 { 375 {
299 if (inv.Value.Type != type) 376 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 377 }
378
379 return inv.Value.AssetID;
304 } 380 }
305 } 381 }
306 382
383 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 384 return UUID.Zero;
308 } 385 }
309 386
@@ -311,17 +388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 388 {
312 m_host.AddScriptLPS(1); 389 m_host.AddScriptLPS(1);
313 390
314 lock (m_host.TaskInventory) 391
392 m_host.TaskInventory.LockItemsForRead(true);
393
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 395 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 396 if (inv.Value.Name == name)
317 { 397 {
318 if (inv.Value.Name == name) 398 m_host.TaskInventory.LockItemsForRead(false);
319 { 399 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 400 }
323 } 401 }
324 402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
325 return UUID.Zero; 406 return UUID.Zero;
326 } 407 }
327 408
@@ -463,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 544
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 546
466 /// <summary> 547 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 548
468 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 550 protected double NormalizeAngle(double angle)
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
475 public LSL_Vector llRot2Euler(LSL_Rotation r)
476 { 551 {
477 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
478 554
479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 555 int numPis = (int)(Math.PI / angle);
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
481 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
482 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
483 double sin = v.x / m; 559 return remainder;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
485 double y = Math.Asin(sin);
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
487 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
488 double z = Math.Atan2(v.y, v.x);
489 561
490 return new LSL_Vector(x, y, z); 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
563 {
564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
566
567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
491 } 589 }
492 590
493 /* From wiki: 591 /* From wiki:
@@ -689,77 +787,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 787 {
690 //A and B should both be normalized 788 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 789 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 790 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 791 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 792
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 793 double dotProduct = LSL_Vector.Dot(a, b);
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
796 double angle = Math.Acos(dotProduct / magProduct);
797 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
798 double s = Math.Sin(angle / 2);
799
800 double x = axis.x * s;
801 double y = axis.y * s;
802 double z = axis.z * s;
803 double w = Math.Cos(angle / 2);
804
805 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
806 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
807
808 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
809 */
810
811 // This method mimics the 180 errors found in SL
812 // See www.euclideanspace.com... angleBetween
813 LSL_Vector vec_a = a;
814 LSL_Vector vec_b = b;
815
816 // Eliminate zero length
817 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
818 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
819 if (vec_a_mag < 0.00001 ||
820 vec_b_mag < 0.00001)
696 { 821 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 823 }
699 else 824
825 // Normalize
826 vec_a = llVecNorm(vec_a);
827 vec_b = llVecNorm(vec_b);
828
829 // Calculate axis and rotation angle
830 LSL_Vector axis = vec_a % vec_b;
831 LSL_Float cos_theta = vec_a * vec_b;
832
833 // Check if parallel
834 if (cos_theta > 0.99999)
700 { 835 {
701 a = LSL_Vector.Norm(a); 836 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 837 }
703 double dotProduct = LSL_Vector.Dot(a, b); 838
704 // There are two degenerate cases possible. These are for vectors 180 or 839 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 840 else if (cos_theta < -0.99999)
706 // 841 {
707 // Check for vectors 180 degrees apart. 842 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 843 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 844 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 845 }
711 // First assume X axis is orthogonal to the vectors. 846 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 847 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 848 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 849 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 850 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 851 s = Math.Cos(theta);
717 { 852 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 853 x = axis.x * t;
719 } 854 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 855 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 856 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 857 }
760 return rotBetween;
761 } 858 }
762 859
763 public void llWhisper(int channelID, string text) 860 public void llWhisper(int channelID, string text)
764 { 861 {
765 m_host.AddScriptLPS(1); 862 m_host.AddScriptLPS(1);
@@ -779,6 +876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 876 {
780 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
781 878
879 if (channelID == 0)
880 m_SayShoutCount++;
881
882 if (m_SayShoutCount >= 11)
883 ScriptSleep(2000);
884
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 885 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 886 {
784 Console.WriteLine(text); 887 Console.WriteLine(text);
@@ -801,6 +904,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 904 {
802 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
803 906
907 if (channelID == 0)
908 m_SayShoutCount++;
909
910 if (m_SayShoutCount >= 11)
911 ScriptSleep(2000);
912
804 if (text.Length > 1023) 913 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 914 text = text.Substring(0, 1023);
806 915
@@ -1101,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1102 } 1211 }
1103 1212
1213 [DebuggerNonUserCode]
1104 public virtual void llDie() 1214 public virtual void llDie()
1105 { 1215 {
1106 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1217 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1218 }
1109 1219
1110 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1287
1178 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1179 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1180 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1181 1293
1182 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -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 {
@@ -1978,26 +2177,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1978 return real_vec; 2177 return real_vec;
1979 } 2178 }
1980 2179
2180 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2181 {
2182 return new LSL_Integer(SetRegionPos(m_host, pos));
2183 }
2184
2185 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2186 {
2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2188 return 0;
2189
2190 SceneObjectGroup grp = part.ParentGroup;
2191
2192 if (grp.IsAttachment)
2193 return 0;
2194
2195 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2196 return 0;
2197
2198 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2199 return 0;
2200
2201 float constrainedX = (float)targetPos.x;
2202 float constrainedY = (float)targetPos.y;
2203
2204 if (constrainedX < 0.0f)
2205 constrainedX = 0.0f;
2206 if (constrainedY < 0.0f)
2207 constrainedY = 0.0f;
2208 if (constrainedX >= (float)Constants.RegionSize)
2209 constrainedX = (float)Constants.RegionSize - 0.1f;
2210 if (constrainedY >= (float)Constants.RegionSize)
2211 constrainedY = (float)Constants.RegionSize -0.1f;
2212
2213 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2214
2215 if (targetPos.z < ground)
2216 targetPos.z = ground;
2217
2218 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2219
2220 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2221 return 0;
2222
2223 grp.UpdateGroupPosition(dest);
2224
2225 return 1;
2226 }
2227
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2228 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2229 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2230 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2231 return;
2232
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2233 LSL_Vector currentPos = GetPartLocalPos(part);
2234 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1985 2235
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1988 2236
1989 if (part.ParentGroup.RootPart == part) 2237 if (part.ParentGroup.RootPart == part)
1990 { 2238 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2239 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2240 Vector3 dest = 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)); 2241 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2242 return;
2243 Util.FireAndForget(delegate(object x) {
2244 parent.UpdateGroupPosition(dest);
2245 });
1996 } 2246 }
1997 else 2247 else
1998 { 2248 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2249 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; 2250 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2251 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2252 parent.ScheduleGroupForTerseUpdate();
@@ -2028,11 +2277,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 } 2277 }
2029 else 2278 else
2030 { 2279 {
2031 if (m_host.IsRoot) 2280 if (part.IsRoot)
2032 { 2281 {
2033 return new LSL_Vector(m_host.AttachedPos.X, 2282 return new LSL_Vector(part.AttachedPos.X,
2034 m_host.AttachedPos.Y, 2283 part.AttachedPos.Y,
2035 m_host.AttachedPos.Z); 2284 part.AttachedPos.Z);
2036 } 2285 }
2037 else 2286 else
2038 { 2287 {
@@ -2048,9 +2297,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2297 m_host.AddScriptLPS(1);
2049 2298
2050 // try to let this work as in SL... 2299 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2300 if (m_host.LinkNum < 2)
2052 { 2301 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2302 // Special case: If we are root, rotate complete SOG to new
2303 // rotation.
2304 // We are root if the link number is 0 (single prim) or 1
2305 // (root prim). ParentID may be nonzero in attachments and
2306 // using it would cause attachments and HUDs to rotate
2307 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2308 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2309 }
2056 else 2310 else
@@ -2075,6 +2329,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2329
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2330 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2331 {
2332 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2333 return;
2334
2078 part.UpdateRotation(rot); 2335 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2336 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2337
@@ -2227,13 +2484,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2227 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2484 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2228 { 2485 {
2229 m_host.AddScriptLPS(1); 2486 m_host.AddScriptLPS(1);
2230 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2487 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2231 } 2488 }
2232 2489
2233 public void llSetTorque(LSL_Vector torque, int local) 2490 public void llSetTorque(LSL_Vector torque, int local)
2234 { 2491 {
2235 m_host.AddScriptLPS(1); 2492 m_host.AddScriptLPS(1);
2236 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2493 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2237 } 2494 }
2238 2495
2239 public LSL_Vector llGetTorque() 2496 public LSL_Vector llGetTorque()
@@ -2698,12 +2955,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2955
2699 m_host.AddScriptLPS(1); 2956 m_host.AddScriptLPS(1);
2700 2957
2958 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2959 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2960 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2961
2708 if (item.PermsGranter == UUID.Zero) 2962 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2963 return 0;
@@ -2844,34 +3098,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 public void llLookAt(LSL_Vector target, double strength, double damping) 3098 public void llLookAt(LSL_Vector target, double strength, double damping)
2845 { 3099 {
2846 m_host.AddScriptLPS(1); 3100 m_host.AddScriptLPS(1);
2847 // Determine where we are looking from
2848 LSL_Vector from = llGetPos();
2849 3101
2850 // Work out the normalised vector from the source to the target 3102 // Get the normalized vector to the target
2851 LSL_Vector delta = llVecNorm(target - from); 3103 LSL_Vector d1 = llVecNorm(target - llGetPos());
2852 LSL_Vector angle = new LSL_Vector(0,0,0);
2853 3104
2854 // Calculate the yaw 3105 // Get the bearing (yaw)
2855 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3106 LSL_Vector a1 = new LSL_Vector(0,0,0);
2856 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3107 a1.z = llAtan2(d1.y, d1.x);
2857 3108
2858 // Calculate pitch 3109 // Get the elevation (pitch)
2859 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3110 LSL_Vector a2 = new LSL_Vector(0,0,0);
3111 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2860 3112
2861 // we need to convert from a vector describing 3113 LSL_Rotation r1 = llEuler2Rot(a1);
2862 // the angles of rotation in radians into rotation value 3114 LSL_Rotation r2 = llEuler2Rot(a2);
3115 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2863 3116
2864 LSL_Rotation rot = llEuler2Rot(angle); 3117 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2865
2866 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2867 // set the rotation of the object, copy that behavior
2868 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2869 { 3118 {
2870 llSetRot(rot); 3119 // Do nothing if either value is 0 (this has been checked in SL)
3120 if (strength <= 0.0 || damping <= 0.0)
3121 return;
3122
3123 llSetRot(r3 * r2 * r1);
2871 } 3124 }
2872 else 3125 else
2873 { 3126 {
2874 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3127 if (strength == 0)
3128 {
3129 llSetRot(r3 * r2 * r1);
3130 return;
3131 }
3132
3133 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2875 } 3134 }
2876 } 3135 }
2877 3136
@@ -2921,13 +3180,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2921 { 3180 {
2922 TaskInventoryItem item; 3181 TaskInventoryItem item;
2923 3182
2924 lock (m_host.TaskInventory) 3183 m_host.TaskInventory.LockItemsForRead(true);
3184 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2925 { 3185 {
2926 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3186 m_host.TaskInventory.LockItemsForRead(false);
2927 return; 3187 return;
2928 else
2929 item = m_host.TaskInventory[InventorySelf()];
2930 } 3188 }
3189 else
3190 {
3191 item = m_host.TaskInventory[InventorySelf()];
3192 }
3193 m_host.TaskInventory.LockItemsForRead(false);
2931 3194
2932 if (item.PermsGranter != UUID.Zero) 3195 if (item.PermsGranter != UUID.Zero)
2933 { 3196 {
@@ -2949,13 +3212,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2949 { 3212 {
2950 TaskInventoryItem item; 3213 TaskInventoryItem item;
2951 3214
3215 m_host.TaskInventory.LockItemsForRead(true);
2952 lock (m_host.TaskInventory) 3216 lock (m_host.TaskInventory)
2953 { 3217 {
3218
2954 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3220 {
3221 m_host.TaskInventory.LockItemsForRead(false);
2955 return; 3222 return;
3223 }
2956 else 3224 else
3225 {
2957 item = m_host.TaskInventory[InventorySelf()]; 3226 item = m_host.TaskInventory[InventorySelf()];
3227 }
2958 } 3228 }
3229 m_host.TaskInventory.LockItemsForRead(false);
2959 3230
2960 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
2961 3232
@@ -2987,18 +3258,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2987 { 3258 {
2988 m_host.AddScriptLPS(1); 3259 m_host.AddScriptLPS(1);
2989 3260
2990// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2991// return;
2992
2993 TaskInventoryItem item; 3261 TaskInventoryItem item;
2994 3262
2995 lock (m_host.TaskInventory) 3263 m_host.TaskInventory.LockItemsForRead(true);
3264
3265 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2996 { 3266 {
2997 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3267 m_host.TaskInventory.LockItemsForRead(false);
2998 return; 3268 return;
2999 else
3000 item = m_host.TaskInventory[InventorySelf()];
3001 } 3269 }
3270 else
3271 {
3272 item = m_host.TaskInventory[InventorySelf()];
3273 }
3274
3275 m_host.TaskInventory.LockItemsForRead(false);
3002 3276
3003 if (item.PermsGranter != m_host.OwnerID) 3277 if (item.PermsGranter != m_host.OwnerID)
3004 return; 3278 return;
@@ -3024,13 +3298,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3024 3298
3025 TaskInventoryItem item; 3299 TaskInventoryItem item;
3026 3300
3027 lock (m_host.TaskInventory) 3301 m_host.TaskInventory.LockItemsForRead(true);
3302
3303 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3028 { 3304 {
3029 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3305 m_host.TaskInventory.LockItemsForRead(false);
3030 return; 3306 return;
3031 else 3307 }
3032 item = m_host.TaskInventory[InventorySelf()]; 3308 else
3309 {
3310 item = m_host.TaskInventory[InventorySelf()];
3033 } 3311 }
3312 m_host.TaskInventory.LockItemsForRead(false);
3313
3034 3314
3035 if (item.PermsGranter != m_host.OwnerID) 3315 if (item.PermsGranter != m_host.OwnerID)
3036 return; 3316 return;
@@ -3077,6 +3357,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3077 3357
3078 public void llInstantMessage(string user, string message) 3358 public void llInstantMessage(string user, string message)
3079 { 3359 {
3360 UUID result;
3361 if (!UUID.TryParse(user, out result))
3362 {
3363 ShoutError("An invalid key was passed to llInstantMessage");
3364 ScriptSleep(2000);
3365 return;
3366 }
3367
3368
3080 m_host.AddScriptLPS(1); 3369 m_host.AddScriptLPS(1);
3081 3370
3082 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3371 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3091,14 +3380,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3091 UUID friendTransactionID = UUID.Random(); 3380 UUID friendTransactionID = UUID.Random();
3092 3381
3093 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3382 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3094 3383
3095 GridInstantMessage msg = new GridInstantMessage(); 3384 GridInstantMessage msg = new GridInstantMessage();
3096 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3385 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3097 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3386 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3098 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3387 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3099// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3388// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3100// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3389// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3101 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3390// DateTime dt = DateTime.UtcNow;
3391//
3392// // Ticks from UtcNow, but make it look like local. Evil, huh?
3393// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3394//
3395// try
3396// {
3397// // Convert that to the PST timezone
3398// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3399// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3400// }
3401// catch
3402// {
3403// // No logging here, as it could be VERY spammy
3404// }
3405//
3406// // And make it look local again to fool the unix time util
3407// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3408
3409 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3410
3102 //if (client != null) 3411 //if (client != null)
3103 //{ 3412 //{
3104 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3413 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3112,12 +3421,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 msg.message = message.Substring(0, 1024); 3421 msg.message = message.Substring(0, 1024);
3113 else 3422 else
3114 msg.message = message; 3423 msg.message = message;
3115 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3424 msg.dialog = (byte)19; // MessageFromObject
3116 msg.fromGroup = false;// fromGroup; 3425 msg.fromGroup = false;// fromGroup;
3117 msg.offline = (byte)0; //offline; 3426 msg.offline = (byte)0; //offline;
3118 msg.ParentEstateID = 0; //ParentEstateID; 3427 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3119 msg.Position = new Vector3(m_host.AbsolutePosition); 3428 msg.Position = new Vector3(m_host.AbsolutePosition);
3120 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3429 msg.RegionID = World.RegionInfo.RegionID.Guid;
3121 msg.binaryBucket 3430 msg.binaryBucket
3122 = Util.StringToBytes256( 3431 = Util.StringToBytes256(
3123 "{0}/{1}/{2}/{3}", 3432 "{0}/{1}/{2}/{3}",
@@ -3145,7 +3454,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3145 } 3454 }
3146 3455
3147 emailModule.SendEmail(m_host.UUID, address, subject, message); 3456 emailModule.SendEmail(m_host.UUID, address, subject, message);
3148 ScriptSleep(20000); 3457 ScriptSleep(15000);
3149 } 3458 }
3150 3459
3151 public void llGetNextEmail(string address, string subject) 3460 public void llGetNextEmail(string address, string subject)
@@ -3284,14 +3593,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3284 3593
3285 TaskInventoryItem item; 3594 TaskInventoryItem item;
3286 3595
3287 lock (m_host.TaskInventory) 3596 m_host.TaskInventory.LockItemsForRead(true);
3597 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3288 { 3598 {
3289 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3599 m_host.TaskInventory.LockItemsForRead(false);
3290 return; 3600 return;
3291 else
3292 item = m_host.TaskInventory[InventorySelf()];
3293 } 3601 }
3294 3602 else
3603 {
3604 item = m_host.TaskInventory[InventorySelf()];
3605 }
3606 m_host.TaskInventory.LockItemsForRead(false);
3295 if (item.PermsGranter == UUID.Zero) 3607 if (item.PermsGranter == UUID.Zero)
3296 return; 3608 return;
3297 3609
@@ -3321,13 +3633,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3321 3633
3322 TaskInventoryItem item; 3634 TaskInventoryItem item;
3323 3635
3324 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForRead(true);
3637 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3325 { 3638 {
3326 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3639 m_host.TaskInventory.LockItemsForRead(false);
3327 return; 3640 return;
3328 else
3329 item = m_host.TaskInventory[InventorySelf()];
3330 } 3641 }
3642 else
3643 {
3644 item = m_host.TaskInventory[InventorySelf()];
3645 }
3646 m_host.TaskInventory.LockItemsForRead(false);
3647
3331 3648
3332 if (item.PermsGranter == UUID.Zero) 3649 if (item.PermsGranter == UUID.Zero)
3333 return; 3650 return;
@@ -3394,10 +3711,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3394 3711
3395 TaskInventoryItem item; 3712 TaskInventoryItem item;
3396 3713
3397 lock (m_host.TaskInventory) 3714
3715 m_host.TaskInventory.LockItemsForRead(true);
3716 if (!m_host.TaskInventory.ContainsKey(invItemID))
3717 {
3718 m_host.TaskInventory.LockItemsForRead(false);
3719 return;
3720 }
3721 else
3398 { 3722 {
3399 item = m_host.TaskInventory[invItemID]; 3723 item = m_host.TaskInventory[invItemID];
3400 } 3724 }
3725 m_host.TaskInventory.LockItemsForRead(false);
3401 3726
3402 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3727 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3403 { 3728 {
@@ -3425,15 +3750,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3425 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3750 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3426 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3751 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3427 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3752 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3753 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3428 ScriptBaseClass.PERMISSION_ATTACH; 3754 ScriptBaseClass.PERMISSION_ATTACH;
3429 3755
3430 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3756 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3431 { 3757 {
3432 lock (m_host.TaskInventory) 3758 m_host.TaskInventory.LockItemsForWrite(true);
3433 { 3759 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3434 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3760 m_host.TaskInventory[invItemID].PermsMask = perm;
3435 m_host.TaskInventory[invItemID].PermsMask = perm; 3761 m_host.TaskInventory.LockItemsForWrite(false);
3436 }
3437 3762
3438 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3763 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3439 "run_time_permissions", new Object[] { 3764 "run_time_permissions", new Object[] {
@@ -3443,28 +3768,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3443 return; 3768 return;
3444 } 3769 }
3445 } 3770 }
3446 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3771 else
3447 { 3772 {
3448 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3773 bool sitting = false;
3449 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3774 if (m_host.SitTargetAvatar == agentID)
3450 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3775 {
3451 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3776 sitting = true;
3452 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3777 }
3778 else
3779 {
3780 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3781 {
3782 if (p.SitTargetAvatar == agentID)
3783 sitting = true;
3784 }
3785 }
3453 3786
3454 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3787 if (sitting)
3455 { 3788 {
3456 lock (m_host.TaskInventory) 3789 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3790 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3791 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3792 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3793 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3794
3795 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3457 { 3796 {
3797 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3798 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3459 m_host.TaskInventory[invItemID].PermsMask = perm; 3799 m_host.TaskInventory[invItemID].PermsMask = perm;
3460 } 3800 m_host.TaskInventory.LockItemsForWrite(false);
3461 3801
3462 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3802 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3463 "run_time_permissions", new Object[] { 3803 "run_time_permissions", new Object[] {
3464 new LSL_Integer(perm) }, 3804 new LSL_Integer(perm) },
3465 new DetectParams[0])); 3805 new DetectParams[0]));
3466 3806
3467 return; 3807 return;
3808 }
3468 } 3809 }
3469 } 3810 }
3470 3811
@@ -3478,11 +3819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 3819
3479 if (!m_waitingForScriptAnswer) 3820 if (!m_waitingForScriptAnswer)
3480 { 3821 {
3481 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForWrite(true);
3482 { 3823 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3483 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3824 m_host.TaskInventory[invItemID].PermsMask = 0;
3484 m_host.TaskInventory[invItemID].PermsMask = 0; 3825 m_host.TaskInventory.LockItemsForWrite(false);
3485 }
3486 3826
3487 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3827 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3488 m_waitingForScriptAnswer=true; 3828 m_waitingForScriptAnswer=true;
@@ -3517,10 +3857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3857 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3518 llReleaseControls(); 3858 llReleaseControls();
3519 3859
3520 lock (m_host.TaskInventory) 3860
3521 { 3861 m_host.TaskInventory.LockItemsForWrite(true);
3522 m_host.TaskInventory[invItemID].PermsMask = answer; 3862 m_host.TaskInventory[invItemID].PermsMask = answer;
3523 } 3863 m_host.TaskInventory.LockItemsForWrite(false);
3864
3524 3865
3525 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3866 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3526 "run_time_permissions", new Object[] { 3867 "run_time_permissions", new Object[] {
@@ -3532,16 +3873,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3532 { 3873 {
3533 m_host.AddScriptLPS(1); 3874 m_host.AddScriptLPS(1);
3534 3875
3535 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForRead(true);
3877
3878 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3536 { 3879 {
3537 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3880 if (item.Type == 10 && item.ItemID == m_itemID)
3538 { 3881 {
3539 if (item.Type == 10 && item.ItemID == m_itemID) 3882 m_host.TaskInventory.LockItemsForRead(false);
3540 { 3883 return item.PermsGranter.ToString();
3541 return item.PermsGranter.ToString();
3542 }
3543 } 3884 }
3544 } 3885 }
3886 m_host.TaskInventory.LockItemsForRead(false);
3545 3887
3546 return UUID.Zero.ToString(); 3888 return UUID.Zero.ToString();
3547 } 3889 }
@@ -3550,19 +3892,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3550 { 3892 {
3551 m_host.AddScriptLPS(1); 3893 m_host.AddScriptLPS(1);
3552 3894
3553 lock (m_host.TaskInventory) 3895 m_host.TaskInventory.LockItemsForRead(true);
3896
3897 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3554 { 3898 {
3555 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3899 if (item.Type == 10 && item.ItemID == m_itemID)
3556 { 3900 {
3557 if (item.Type == 10 && item.ItemID == m_itemID) 3901 int perms = item.PermsMask;
3558 { 3902 if (m_automaticLinkPermission)
3559 int perms = item.PermsMask; 3903 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3560 if (m_automaticLinkPermission) 3904 m_host.TaskInventory.LockItemsForRead(false);
3561 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3905 return perms;
3562 return perms;
3563 }
3564 } 3906 }
3565 } 3907 }
3908 m_host.TaskInventory.LockItemsForRead(false);
3566 3909
3567 return 0; 3910 return 0;
3568 } 3911 }
@@ -3584,9 +3927,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3584 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3927 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3585 { 3928 {
3586 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3587 3930 if (parts.Count > 0)
3588 foreach (SceneObjectPart part in parts) 3931 {
3589 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3932 try
3933 {
3934 parts[0].ParentGroup.areUpdatesSuspended = true;
3935 foreach (SceneObjectPart part in parts)
3936 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3937 }
3938 finally
3939 {
3940 parts[0].ParentGroup.areUpdatesSuspended = false;
3941 }
3942 }
3590 } 3943 }
3591 3944
3592 public void llCreateLink(string target, int parent) 3945 public void llCreateLink(string target, int parent)
@@ -3599,11 +3952,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3599 return; 3952 return;
3600 3953
3601 TaskInventoryItem item; 3954 TaskInventoryItem item;
3602 lock (m_host.TaskInventory) 3955 m_host.TaskInventory.LockItemsForRead(true);
3603 { 3956 item = m_host.TaskInventory[invItemID];
3604 item = m_host.TaskInventory[invItemID]; 3957 m_host.TaskInventory.LockItemsForRead(false);
3605 } 3958
3606
3607 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3959 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3608 && !m_automaticLinkPermission) 3960 && !m_automaticLinkPermission)
3609 { 3961 {
@@ -3620,11 +3972,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3620 3972
3621 if (targetPart.ParentGroup.AttachmentPoint != 0) 3973 if (targetPart.ParentGroup.AttachmentPoint != 0)
3622 return; // Fail silently if attached 3974 return; // Fail silently if attached
3975
3976 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3977 return;
3978
3623 SceneObjectGroup parentPrim = null, childPrim = null; 3979 SceneObjectGroup parentPrim = null, childPrim = null;
3624 3980
3625 if (targetPart != null) 3981 if (targetPart != null)
3626 { 3982 {
3627 if (parent != 0) { 3983 if (parent != 0)
3984 {
3628 parentPrim = m_host.ParentGroup; 3985 parentPrim = m_host.ParentGroup;
3629 childPrim = targetPart.ParentGroup; 3986 childPrim = targetPart.ParentGroup;
3630 } 3987 }
@@ -3636,7 +3993,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3636 3993
3637 // Required for linking 3994 // Required for linking
3638 childPrim.RootPart.ClearUpdateSchedule(); 3995 childPrim.RootPart.ClearUpdateSchedule();
3639 parentPrim.LinkToGroup(childPrim); 3996 parentPrim.LinkToGroup(childPrim, true);
3640 } 3997 }
3641 3998
3642 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3999 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3655,16 +4012,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3655 m_host.AddScriptLPS(1); 4012 m_host.AddScriptLPS(1);
3656 UUID invItemID = InventorySelf(); 4013 UUID invItemID = InventorySelf();
3657 4014
3658 lock (m_host.TaskInventory) 4015 m_host.TaskInventory.LockItemsForRead(true);
3659 {
3660 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4016 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3661 && !m_automaticLinkPermission) 4017 && !m_automaticLinkPermission)
3662 { 4018 {
3663 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4019 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4020 m_host.TaskInventory.LockItemsForRead(false);
3664 return; 4021 return;
3665 } 4022 }
3666 } 4023 m_host.TaskInventory.LockItemsForRead(false);
3667 4024
3668 if (linknum < ScriptBaseClass.LINK_THIS) 4025 if (linknum < ScriptBaseClass.LINK_THIS)
3669 return; 4026 return;
3670 4027
@@ -3703,10 +4060,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3703 // Restructuring Multiple Prims. 4060 // Restructuring Multiple Prims.
3704 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4061 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3705 parts.Remove(parentPrim.RootPart); 4062 parts.Remove(parentPrim.RootPart);
3706 foreach (SceneObjectPart part in parts) 4063 if (parts.Count > 0)
3707 { 4064 {
3708 parentPrim.DelinkFromGroup(part.LocalId, true); 4065 try
4066 {
4067 parts[0].ParentGroup.areUpdatesSuspended = true;
4068 foreach (SceneObjectPart part in parts)
4069 {
4070 parentPrim.DelinkFromGroup(part.LocalId, true);
4071 }
4072 }
4073 finally
4074 {
4075 parts[0].ParentGroup.areUpdatesSuspended = false;
4076 }
3709 } 4077 }
4078
3710 parentPrim.HasGroupChanged = true; 4079 parentPrim.HasGroupChanged = true;
3711 parentPrim.ScheduleGroupForFullUpdate(); 4080 parentPrim.ScheduleGroupForFullUpdate();
3712 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4081 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3715,12 +4084,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3715 { 4084 {
3716 SceneObjectPart newRoot = parts[0]; 4085 SceneObjectPart newRoot = parts[0];
3717 parts.Remove(newRoot); 4086 parts.Remove(newRoot);
3718 foreach (SceneObjectPart part in parts) 4087
4088 try
3719 { 4089 {
3720 // Required for linking 4090 parts[0].ParentGroup.areUpdatesSuspended = true;
3721 part.ClearUpdateSchedule(); 4091 foreach (SceneObjectPart part in parts)
3722 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4092 {
4093 part.ClearUpdateSchedule();
4094 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4095 }
3723 } 4096 }
4097 finally
4098 {
4099 parts[0].ParentGroup.areUpdatesSuspended = false;
4100 }
4101
4102
3724 newRoot.ParentGroup.HasGroupChanged = true; 4103 newRoot.ParentGroup.HasGroupChanged = true;
3725 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4104 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3726 } 4105 }
@@ -3740,6 +4119,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3740 public void llBreakAllLinks() 4119 public void llBreakAllLinks()
3741 { 4120 {
3742 m_host.AddScriptLPS(1); 4121 m_host.AddScriptLPS(1);
4122
4123 UUID invItemID = InventorySelf();
4124
4125 TaskInventoryItem item;
4126 m_host.TaskInventory.LockItemsForRead(true);
4127 item = m_host.TaskInventory[invItemID];
4128 m_host.TaskInventory.LockItemsForRead(false);
4129
4130 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4131 && !m_automaticLinkPermission)
4132 {
4133 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4134 return;
4135 }
4136
3743 SceneObjectGroup parentPrim = m_host.ParentGroup; 4137 SceneObjectGroup parentPrim = m_host.ParentGroup;
3744 if (parentPrim.AttachmentPoint != 0) 4138 if (parentPrim.AttachmentPoint != 0)
3745 return; // Fail silently if attached 4139 return; // Fail silently if attached
@@ -3759,25 +4153,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3759 public LSL_String llGetLinkKey(int linknum) 4153 public LSL_String llGetLinkKey(int linknum)
3760 { 4154 {
3761 m_host.AddScriptLPS(1); 4155 m_host.AddScriptLPS(1);
3762 List<UUID> keytable = new List<UUID>();
3763 // parse for sitting avatare-uuids
3764 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3765 {
3766 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
3767 keytable.Add(presence.UUID);
3768 });
3769
3770 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3771 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3772 {
3773 return keytable[totalprims - linknum].ToString();
3774 }
3775
3776 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3777 {
3778 return m_host.UUID.ToString();
3779 }
3780
3781 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4156 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3782 if (part != null) 4157 if (part != null)
3783 { 4158 {
@@ -3785,6 +4160,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3785 } 4160 }
3786 else 4161 else
3787 { 4162 {
4163 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4164 {
4165 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4166
4167 if (linknum < 0)
4168 return UUID.Zero.ToString();
4169
4170 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4171 if (avatars.Count > linknum)
4172 {
4173 return avatars[linknum].UUID.ToString();
4174 }
4175 }
3788 return UUID.Zero.ToString(); 4176 return UUID.Zero.ToString();
3789 } 4177 }
3790 } 4178 }
@@ -3883,17 +4271,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3883 m_host.AddScriptLPS(1); 4271 m_host.AddScriptLPS(1);
3884 int count = 0; 4272 int count = 0;
3885 4273
3886 lock (m_host.TaskInventory) 4274 m_host.TaskInventory.LockItemsForRead(true);
4275 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3887 { 4276 {
3888 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4277 if (inv.Value.Type == type || type == -1)
3889 { 4278 {
3890 if (inv.Value.Type == type || type == -1) 4279 count = count + 1;
3891 {
3892 count = count + 1;
3893 }
3894 } 4280 }
3895 } 4281 }
3896 4282
4283 m_host.TaskInventory.LockItemsForRead(false);
3897 return count; 4284 return count;
3898 } 4285 }
3899 4286
@@ -3902,16 +4289,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3902 m_host.AddScriptLPS(1); 4289 m_host.AddScriptLPS(1);
3903 ArrayList keys = new ArrayList(); 4290 ArrayList keys = new ArrayList();
3904 4291
3905 lock (m_host.TaskInventory) 4292 m_host.TaskInventory.LockItemsForRead(true);
4293 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3906 { 4294 {
3907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4295 if (inv.Value.Type == type || type == -1)
3908 { 4296 {
3909 if (inv.Value.Type == type || type == -1) 4297 keys.Add(inv.Value.Name);
3910 {
3911 keys.Add(inv.Value.Name);
3912 }
3913 } 4298 }
3914 } 4299 }
4300 m_host.TaskInventory.LockItemsForRead(false);
3915 4301
3916 if (keys.Count == 0) 4302 if (keys.Count == 0)
3917 { 4303 {
@@ -3948,25 +4334,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3948 } 4334 }
3949 4335
3950 // move the first object found with this inventory name 4336 // move the first object found with this inventory name
3951 lock (m_host.TaskInventory) 4337 m_host.TaskInventory.LockItemsForRead(true);
4338 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3952 { 4339 {
3953 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4340 if (inv.Value.Name == inventory)
3954 { 4341 {
3955 if (inv.Value.Name == inventory) 4342 found = true;
3956 { 4343 objId = inv.Key;
3957 found = true; 4344 assetType = inv.Value.Type;
3958 objId = inv.Key; 4345 objName = inv.Value.Name;
3959 assetType = inv.Value.Type; 4346 break;
3960 objName = inv.Value.Name;
3961 break;
3962 }
3963 } 4347 }
3964 } 4348 }
4349 m_host.TaskInventory.LockItemsForRead(false);
3965 4350
3966 if (!found) 4351 if (!found)
3967 { 4352 {
3968 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4353 llSay(0, String.Format("Could not find object '{0}'", inventory));
3969 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4354 return;
4355// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3970 } 4356 }
3971 4357
3972 // check if destination is an object 4358 // check if destination is an object
@@ -3992,48 +4378,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3992 return; 4378 return;
3993 } 4379 }
3994 } 4380 }
4381
3995 // destination is an avatar 4382 // destination is an avatar
3996 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4383 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3997 4384
3998 if (agentItem == null) 4385 if (agentItem == null)
3999 return; 4386 return;
4000 4387
4001 byte[] bucket = new byte[17]; 4388 byte[] bucket = new byte[1];
4002 bucket[0] = (byte)assetType; 4389 bucket[0] = (byte)assetType;
4003 byte[] objBytes = agentItem.ID.GetBytes(); 4390 //byte[] objBytes = agentItem.ID.GetBytes();
4004 Array.Copy(objBytes, 0, bucket, 1, 16); 4391 //Array.Copy(objBytes, 0, bucket, 1, 16);
4005 4392
4006 GridInstantMessage msg = new GridInstantMessage(World, 4393 GridInstantMessage msg = new GridInstantMessage(World,
4007 m_host.UUID, m_host.Name+", an object owned by "+ 4394 m_host.OwnerID, m_host.Name, destId,
4008 resolveName(m_host.OwnerID)+",", destId,
4009 (byte)InstantMessageDialog.TaskInventoryOffered, 4395 (byte)InstantMessageDialog.TaskInventoryOffered,
4010 false, objName+"\n"+m_host.Name+" is located at "+ 4396 false, objName+". "+m_host.Name+" is located at "+
4011 World.RegionInfo.RegionName+" "+ 4397 World.RegionInfo.RegionName+" "+
4012 m_host.AbsolutePosition.ToString(), 4398 m_host.AbsolutePosition.ToString(),
4013 agentItem.ID, true, m_host.AbsolutePosition, 4399 agentItem.ID, true, m_host.AbsolutePosition,
4014 bucket); 4400 bucket);
4015 if (m_TransferModule != null) 4401
4016 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4402 ScenePresence sp;
4403
4404 if (World.TryGetScenePresence(destId, out sp))
4405 {
4406 sp.ControllingClient.SendInstantMessage(msg);
4407 }
4408 else
4409 {
4410 if (m_TransferModule != null)
4411 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4412 }
4413
4414 //This delay should only occur when giving inventory to avatars.
4017 ScriptSleep(3000); 4415 ScriptSleep(3000);
4018 } 4416 }
4019 } 4417 }
4020 4418
4419 [DebuggerNonUserCode]
4021 public void llRemoveInventory(string name) 4420 public void llRemoveInventory(string name)
4022 { 4421 {
4023 m_host.AddScriptLPS(1); 4422 m_host.AddScriptLPS(1);
4024 4423
4025 lock (m_host.TaskInventory) 4424 List<TaskInventoryItem> inv;
4425 try
4026 { 4426 {
4027 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4427 m_host.TaskInventory.LockItemsForRead(true);
4428 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4429 }
4430 finally
4431 {
4432 m_host.TaskInventory.LockItemsForRead(false);
4433 }
4434 foreach (TaskInventoryItem item in inv)
4435 {
4436 if (item.Name == name)
4028 { 4437 {
4029 if (item.Name == name) 4438 if (item.ItemID == m_itemID)
4030 { 4439 throw new ScriptDeleteException();
4031 if (item.ItemID == m_itemID) 4440 else
4032 throw new ScriptDeleteException(); 4441 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4033 else 4442 return;
4034 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4035 return;
4036 }
4037 } 4443 }
4038 } 4444 }
4039 } 4445 }
@@ -4068,112 +4474,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4068 { 4474 {
4069 m_host.AddScriptLPS(1); 4475 m_host.AddScriptLPS(1);
4070 4476
4071 UUID uuid = (UUID)id; 4477 UUID uuid;
4072 PresenceInfo pinfo = null; 4478 if (UUID.TryParse(id, out uuid))
4073 UserAccount account;
4074
4075 UserInfoCacheEntry ce;
4076 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4077 { 4479 {
4078 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4480 PresenceInfo pinfo = null;
4079 if (account == null) 4481 UserAccount account;
4482
4483 UserInfoCacheEntry ce;
4484 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4080 { 4485 {
4081 m_userInfoCache[uuid] = null; // Cache negative 4486 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4082 return UUID.Zero.ToString(); 4487 if (account == null)
4083 } 4488 {
4489 m_userInfoCache[uuid] = null; // Cache negative
4490 return UUID.Zero.ToString();
4491 }
4084 4492
4085 4493
4086 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4494 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4087 if (pinfos != null && pinfos.Length > 0) 4495 if (pinfos != null && pinfos.Length > 0)
4088 {
4089 foreach (PresenceInfo p in pinfos)
4090 { 4496 {
4091 if (p.RegionID != UUID.Zero) 4497 foreach (PresenceInfo p in pinfos)
4092 { 4498 {
4093 pinfo = p; 4499 if (p.RegionID != UUID.Zero)
4500 {
4501 pinfo = p;
4502 }
4094 } 4503 }
4095 } 4504 }
4096 }
4097 4505
4098 ce = new UserInfoCacheEntry(); 4506 ce = new UserInfoCacheEntry();
4099 ce.time = Util.EnvironmentTickCount(); 4507 ce.time = Util.EnvironmentTickCount();
4100 ce.account = account; 4508 ce.account = account;
4101 ce.pinfo = pinfo; 4509 ce.pinfo = pinfo;
4102 } 4510 m_userInfoCache[uuid] = ce;
4103 else 4511 }
4104 { 4512 else
4105 if (ce == null) 4513 {
4106 return UUID.Zero.ToString(); 4514 if (ce == null)
4515 return UUID.Zero.ToString();
4107 4516
4108 account = ce.account; 4517 account = ce.account;
4109 pinfo = ce.pinfo; 4518 pinfo = ce.pinfo;
4110 } 4519 }
4111 4520
4112 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4521 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4113 {
4114 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4115 if (pinfos != null && pinfos.Length > 0)
4116 { 4522 {
4117 foreach (PresenceInfo p in pinfos) 4523 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4524 if (pinfos != null && pinfos.Length > 0)
4118 { 4525 {
4119 if (p.RegionID != UUID.Zero) 4526 foreach (PresenceInfo p in pinfos)
4120 { 4527 {
4121 pinfo = p; 4528 if (p.RegionID != UUID.Zero)
4529 {
4530 pinfo = p;
4531 }
4122 } 4532 }
4123 } 4533 }
4124 } 4534 else
4125 else 4535 pinfo = null;
4126 pinfo = null;
4127 4536
4128 ce.time = Util.EnvironmentTickCount(); 4537 ce.time = Util.EnvironmentTickCount();
4129 ce.pinfo = pinfo; 4538 ce.pinfo = pinfo;
4130 } 4539 }
4131 4540
4132 string reply = String.Empty; 4541 string reply = String.Empty;
4133 4542
4134 switch (data) 4543 switch (data)
4135 { 4544 {
4136 case 1: // DATA_ONLINE (0|1) 4545 case 1: // DATA_ONLINE (0|1)
4137 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4546 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4138 reply = "1"; 4547 reply = "1";
4139 else 4548 else
4140 reply = "0"; 4549 reply = "0";
4141 break; 4550 break;
4142 case 2: // DATA_NAME (First Last) 4551 case 2: // DATA_NAME (First Last)
4143 reply = account.FirstName + " " + account.LastName; 4552 reply = account.FirstName + " " + account.LastName;
4144 break; 4553 break;
4145 case 3: // DATA_BORN (YYYY-MM-DD) 4554 case 3: // DATA_BORN (YYYY-MM-DD)
4146 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4555 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4147 born = born.AddSeconds(account.Created); 4556 born = born.AddSeconds(account.Created);
4148 reply = born.ToString("yyyy-MM-dd"); 4557 reply = born.ToString("yyyy-MM-dd");
4149 break; 4558 break;
4150 case 4: // DATA_RATING (0,0,0,0,0,0) 4559 case 4: // DATA_RATING (0,0,0,0,0,0)
4151 reply = "0,0,0,0,0,0"; 4560 reply = "0,0,0,0,0,0";
4152 break; 4561 break;
4153 case 8: // DATA_PAYINFO (0|1|2|3) 4562 case 8: // DATA_PAYINFO (0|1|2|3)
4154 reply = "0"; 4563 reply = "0";
4155 break; 4564 break;
4156 default: 4565 default:
4157 return UUID.Zero.ToString(); // Raise no event 4566 return UUID.Zero.ToString(); // Raise no event
4158 } 4567 }
4159 4568
4160 UUID rq = UUID.Random(); 4569 UUID rq = UUID.Random();
4161 4570
4162 UUID tid = AsyncCommands. 4571 UUID tid = AsyncCommands.
4163 DataserverPlugin.RegisterRequest(m_localID, 4572 DataserverPlugin.RegisterRequest(m_localID,
4164 m_itemID, rq.ToString()); 4573 m_itemID, rq.ToString());
4165 4574
4166 AsyncCommands. 4575 AsyncCommands.
4167 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4576 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4168 4577
4169 ScriptSleep(100); 4578 ScriptSleep(100);
4170 return tid.ToString(); 4579 return tid.ToString();
4580 }
4581 else
4582 {
4583 ShoutError("Invalid UUID passed to llRequestAgentData.");
4584 }
4585 return "";
4171 } 4586 }
4172 4587
4173 public LSL_String llRequestInventoryData(string name) 4588 public LSL_String llRequestInventoryData(string name)
4174 { 4589 {
4175 m_host.AddScriptLPS(1); 4590 m_host.AddScriptLPS(1);
4176 4591
4592 //Clone is thread safe
4177 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4593 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4178 4594
4179 foreach (TaskInventoryItem item in itemDictionary.Values) 4595 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4225,19 +4641,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4225 if (UUID.TryParse(agent, out agentId)) 4641 if (UUID.TryParse(agent, out agentId))
4226 { 4642 {
4227 ScenePresence presence = World.GetScenePresence(agentId); 4643 ScenePresence presence = World.GetScenePresence(agentId);
4228 if (presence != null) 4644 if (presence != null && presence.PresenceType != PresenceType.Npc)
4229 { 4645 {
4646 // agent must not be a god
4647 if (presence.UserLevel >= 200) return;
4648
4230 // agent must be over the owners land 4649 // agent must be over the owners land
4231 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4650 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4232 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4651 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4233 { 4652 {
4234 World.TeleportClientHome(agentId, presence.ControllingClient); 4653 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4654 {
4655 // They can't be teleported home for some reason
4656 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4657 if (regionInfo != null)
4658 {
4659 World.RequestTeleportLocation(
4660 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4661 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4662 }
4663 }
4235 } 4664 }
4236 } 4665 }
4237 } 4666 }
4238 ScriptSleep(5000); 4667 ScriptSleep(5000);
4239 } 4668 }
4240 4669
4670 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4671 {
4672 m_host.AddScriptLPS(1);
4673 UUID agentId = new UUID();
4674 if (UUID.TryParse(agent, out agentId))
4675 {
4676 ScenePresence presence = World.GetScenePresence(agentId);
4677 if (presence != null && presence.PresenceType != PresenceType.Npc)
4678 {
4679 // agent must not be a god
4680 if (presence.UserLevel >= 200) return;
4681
4682 // agent must be over the owners land
4683 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4684 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4685 {
4686 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4687 }
4688 }
4689 }
4690 }
4691
4241 public void llTextBox(string agent, string message, int chatChannel) 4692 public void llTextBox(string agent, string message, int chatChannel)
4242 { 4693 {
4243 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4694 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4249,7 +4700,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4249 UUID av = new UUID(); 4700 UUID av = new UUID();
4250 if (!UUID.TryParse(agent,out av)) 4701 if (!UUID.TryParse(agent,out av))
4251 { 4702 {
4252 LSLError("First parameter to llDialog needs to be a key"); 4703 //LSLError("First parameter to llDialog needs to be a key");
4253 return; 4704 return;
4254 } 4705 }
4255 4706
@@ -4286,17 +4737,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4286 UUID soundId = UUID.Zero; 4737 UUID soundId = UUID.Zero;
4287 if (!UUID.TryParse(impact_sound, out soundId)) 4738 if (!UUID.TryParse(impact_sound, out soundId))
4288 { 4739 {
4289 lock (m_host.TaskInventory) 4740 m_host.TaskInventory.LockItemsForRead(true);
4741 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4290 { 4742 {
4291 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4743 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4292 { 4744 {
4293 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4745 soundId = item.AssetID;
4294 { 4746 break;
4295 soundId = item.AssetID;
4296 break;
4297 }
4298 } 4747 }
4299 } 4748 }
4749 m_host.TaskInventory.LockItemsForRead(false);
4300 } 4750 }
4301 m_host.CollisionSound = soundId; 4751 m_host.CollisionSound = soundId;
4302 m_host.CollisionSoundVolume = (float)impact_volume; 4752 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4336,6 +4786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4336 UUID partItemID; 4786 UUID partItemID;
4337 foreach (SceneObjectPart part in parts) 4787 foreach (SceneObjectPart part in parts)
4338 { 4788 {
4789 //Clone is thread safe
4339 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4790 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4340 4791
4341 foreach (TaskInventoryItem item in itemsDictionary.Values) 4792 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4550,17 +5001,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4550 5001
4551 m_host.AddScriptLPS(1); 5002 m_host.AddScriptLPS(1);
4552 5003
4553 lock (m_host.TaskInventory) 5004 m_host.TaskInventory.LockItemsForRead(true);
5005 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4554 { 5006 {
4555 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5007 if (item.Type == 10 && item.ItemID == m_itemID)
4556 { 5008 {
4557 if (item.Type == 10 && item.ItemID == m_itemID) 5009 result = item.Name!=null?item.Name:String.Empty;
4558 { 5010 break;
4559 result = item.Name != null ? item.Name : String.Empty;
4560 break;
4561 }
4562 } 5011 }
4563 } 5012 }
5013 m_host.TaskInventory.LockItemsForRead(false);
4564 5014
4565 return result; 5015 return result;
4566 } 5016 }
@@ -4733,23 +5183,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4733 { 5183 {
4734 m_host.AddScriptLPS(1); 5184 m_host.AddScriptLPS(1);
4735 5185
4736 lock (m_host.TaskInventory) 5186 m_host.TaskInventory.LockItemsForRead(true);
5187 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4737 { 5188 {
4738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5189 if (inv.Value.Name == name)
4739 { 5190 {
4740 if (inv.Value.Name == name) 5191 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4741 { 5192 {
4742 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5193 m_host.TaskInventory.LockItemsForRead(false);
4743 { 5194 return inv.Value.AssetID.ToString();
4744 return inv.Value.AssetID.ToString(); 5195 }
4745 } 5196 else
4746 else 5197 {
4747 { 5198 m_host.TaskInventory.LockItemsForRead(false);
4748 return UUID.Zero.ToString(); 5199 return UUID.Zero.ToString();
4749 }
4750 } 5200 }
4751 } 5201 }
4752 } 5202 }
5203 m_host.TaskInventory.LockItemsForRead(false);
4753 5204
4754 return UUID.Zero.ToString(); 5205 return UUID.Zero.ToString();
4755 } 5206 }
@@ -4902,14 +5353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4902 { 5353 {
4903 m_host.AddScriptLPS(1); 5354 m_host.AddScriptLPS(1);
4904 5355
4905 if (src == null) 5356 return src.Length;
4906 {
4907 return 0;
4908 }
4909 else
4910 {
4911 return src.Length;
4912 }
4913 } 5357 }
4914 5358
4915 public LSL_Integer llList2Integer(LSL_List src, int index) 5359 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4955,7 +5399,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4955 else if (src.Data[index] is LSL_Float) 5399 else if (src.Data[index] is LSL_Float)
4956 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5400 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4957 else if (src.Data[index] is LSL_String) 5401 else if (src.Data[index] is LSL_String)
4958 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5402 {
5403 string str = ((LSL_String) src.Data[index]).m_string;
5404 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5405 if (m != Match.Empty)
5406 {
5407 str = m.Value;
5408 double d = 0.0;
5409 if (!Double.TryParse(str, out d))
5410 return 0.0;
5411
5412 return d;
5413 }
5414 return 0.0;
5415 }
4959 return Convert.ToDouble(src.Data[index]); 5416 return Convert.ToDouble(src.Data[index]);
4960 } 5417 }
4961 catch (FormatException) 5418 catch (FormatException)
@@ -5228,7 +5685,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5228 } 5685 }
5229 } 5686 }
5230 } 5687 }
5231 else { 5688 else
5689 {
5232 object[] array = new object[src.Length]; 5690 object[] array = new object[src.Length];
5233 Array.Copy(src.Data, 0, array, 0, src.Length); 5691 Array.Copy(src.Data, 0, array, 0, src.Length);
5234 result = new LSL_List(array); 5692 result = new LSL_List(array);
@@ -5335,7 +5793,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5335 public LSL_Integer llGetRegionAgentCount() 5793 public LSL_Integer llGetRegionAgentCount()
5336 { 5794 {
5337 m_host.AddScriptLPS(1); 5795 m_host.AddScriptLPS(1);
5338 return new LSL_Integer(World.GetRootAgentCount()); 5796
5797 int count = 0;
5798 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5799 count++;
5800 });
5801
5802 return new LSL_Integer(count);
5339 } 5803 }
5340 5804
5341 public LSL_Vector llGetRegionCorner() 5805 public LSL_Vector llGetRegionCorner()
@@ -5677,10 +6141,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5677 m_host.AddScriptLPS(1); 6141 m_host.AddScriptLPS(1);
5678 6142
5679 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6143 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5680 6144 if (parts.Count > 0)
5681 foreach (var part in parts)
5682 { 6145 {
5683 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6146 try
6147 {
6148 parts[0].ParentGroup.areUpdatesSuspended = true;
6149 foreach (var part in parts)
6150 {
6151 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6152 }
6153 }
6154 finally
6155 {
6156 parts[0].ParentGroup.areUpdatesSuspended = false;
6157 }
5684 } 6158 }
5685 } 6159 }
5686 6160
@@ -5732,13 +6206,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5732 6206
5733 if (m_host.OwnerID == land.LandData.OwnerID) 6207 if (m_host.OwnerID == land.LandData.OwnerID)
5734 { 6208 {
5735 World.TeleportClientHome(agentID, presence.ControllingClient); 6209 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6210 presence.TeleportWithMomentum(pos);
6211 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5736 } 6212 }
5737 } 6213 }
5738 } 6214 }
5739 ScriptSleep(5000); 6215 ScriptSleep(5000);
5740 } 6216 }
5741 6217
6218 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6219 {
6220 return ParseString2List(str, separators, in_spacers, false);
6221 }
6222
5742 public LSL_Integer llOverMyLand(string id) 6223 public LSL_Integer llOverMyLand(string id)
5743 { 6224 {
5744 m_host.AddScriptLPS(1); 6225 m_host.AddScriptLPS(1);
@@ -5803,8 +6284,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5803 UUID agentId = new UUID(); 6284 UUID agentId = new UUID();
5804 if (!UUID.TryParse(agent, out agentId)) 6285 if (!UUID.TryParse(agent, out agentId))
5805 return new LSL_Integer(0); 6286 return new LSL_Integer(0);
6287 if (agentId == m_host.GroupID)
6288 return new LSL_Integer(1);
5806 ScenePresence presence = World.GetScenePresence(agentId); 6289 ScenePresence presence = World.GetScenePresence(agentId);
5807 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6290 if (presence == null || presence.IsChildAgent) // Return false for child agents
5808 return new LSL_Integer(0); 6291 return new LSL_Integer(0);
5809 IClientAPI client = presence.ControllingClient; 6292 IClientAPI client = presence.ControllingClient;
5810 if (m_host.GroupID == client.ActiveGroupId) 6293 if (m_host.GroupID == client.ActiveGroupId)
@@ -5939,7 +6422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5939 return m_host.ParentGroup.AttachmentPoint; 6422 return m_host.ParentGroup.AttachmentPoint;
5940 } 6423 }
5941 6424
5942 public LSL_Integer llGetFreeMemory() 6425 public virtual LSL_Integer llGetFreeMemory()
5943 { 6426 {
5944 m_host.AddScriptLPS(1); 6427 m_host.AddScriptLPS(1);
5945 // Make scripts designed for LSO happy 6428 // Make scripts designed for LSO happy
@@ -6056,7 +6539,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6056 SetParticleSystem(m_host, rules); 6539 SetParticleSystem(m_host, rules);
6057 } 6540 }
6058 6541
6059 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6542 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6543 {
6060 6544
6061 6545
6062 if (rules.Length == 0) 6546 if (rules.Length == 0)
@@ -6250,14 +6734,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6250 6734
6251 protected UUID GetTaskInventoryItem(string name) 6735 protected UUID GetTaskInventoryItem(string name)
6252 { 6736 {
6253 lock (m_host.TaskInventory) 6737 m_host.TaskInventory.LockItemsForRead(true);
6738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6254 { 6739 {
6255 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6740 if (inv.Value.Name == name)
6256 { 6741 {
6257 if (inv.Value.Name == name) 6742 m_host.TaskInventory.LockItemsForRead(false);
6258 return inv.Key; 6743 return inv.Key;
6259 } 6744 }
6260 } 6745 }
6746 m_host.TaskInventory.LockItemsForRead(false);
6261 6747
6262 return UUID.Zero; 6748 return UUID.Zero;
6263 } 6749 }
@@ -6295,16 +6781,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6295 if (folderID == UUID.Zero) 6781 if (folderID == UUID.Zero)
6296 return; 6782 return;
6297 6783
6298 byte[] bucket = new byte[17]; 6784 byte[] bucket = new byte[1];
6299 bucket[0] = (byte)AssetType.Folder; 6785 bucket[0] = (byte)AssetType.Folder;
6300 byte[] objBytes = folderID.GetBytes(); 6786 //byte[] objBytes = folderID.GetBytes();
6301 Array.Copy(objBytes, 0, bucket, 1, 16); 6787 //Array.Copy(objBytes, 0, bucket, 1, 16);
6302 6788
6303 GridInstantMessage msg = new GridInstantMessage(World, 6789 GridInstantMessage msg = new GridInstantMessage(World,
6304 m_host.UUID, m_host.Name+", an object owned by "+ 6790 m_host.OwnerID, m_host.Name, destID,
6305 resolveName(m_host.OwnerID)+",", destID, 6791 (byte)InstantMessageDialog.TaskInventoryOffered,
6306 (byte)InstantMessageDialog.InventoryOffered, 6792 false, category+". "+m_host.Name+" is located at "+
6307 false, category+"\n"+m_host.Name+" is located at "+
6308 World.RegionInfo.RegionName+" "+ 6793 World.RegionInfo.RegionName+" "+
6309 m_host.AbsolutePosition.ToString(), 6794 m_host.AbsolutePosition.ToString(),
6310 folderID, true, m_host.AbsolutePosition, 6795 folderID, true, m_host.AbsolutePosition,
@@ -6542,13 +7027,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6542 UUID av = new UUID(); 7027 UUID av = new UUID();
6543 if (!UUID.TryParse(avatar,out av)) 7028 if (!UUID.TryParse(avatar,out av))
6544 { 7029 {
6545 LSLError("First parameter to llDialog needs to be a key"); 7030 //LSLError("First parameter to llDialog needs to be a key");
6546 return; 7031 return;
6547 } 7032 }
6548 if (buttons.Length < 1) 7033 if (buttons.Length < 1)
6549 { 7034 {
6550 LSLError("No less than 1 button can be shown"); 7035 buttons.Add("OK");
6551 return;
6552 } 7036 }
6553 if (buttons.Length > 12) 7037 if (buttons.Length > 12)
6554 { 7038 {
@@ -6565,7 +7049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6565 } 7049 }
6566 if (buttons.Data[i].ToString().Length > 24) 7050 if (buttons.Data[i].ToString().Length > 24)
6567 { 7051 {
6568 LSLError("button label cannot be longer than 24 characters"); 7052 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6569 return; 7053 return;
6570 } 7054 }
6571 buts[i] = buttons.Data[i].ToString(); 7055 buts[i] = buttons.Data[i].ToString();
@@ -6624,22 +7108,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6624 } 7108 }
6625 7109
6626 // copy the first script found with this inventory name 7110 // copy the first script found with this inventory name
6627 lock (m_host.TaskInventory) 7111 TaskInventoryItem scriptItem = null;
7112 m_host.TaskInventory.LockItemsForRead(true);
7113 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6628 { 7114 {
6629 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7115 if (inv.Value.Name == name)
6630 { 7116 {
6631 if (inv.Value.Name == name) 7117 // make sure the object is a script
7118 if (10 == inv.Value.Type)
6632 { 7119 {
6633 // make sure the object is a script 7120 found = true;
6634 if (10 == inv.Value.Type) 7121 srcId = inv.Key;
6635 { 7122 scriptItem = inv.Value;
6636 found = true; 7123 break;
6637 srcId = inv.Key;
6638 break;
6639 }
6640 } 7124 }
6641 } 7125 }
6642 } 7126 }
7127 m_host.TaskInventory.LockItemsForRead(false);
6643 7128
6644 if (!found) 7129 if (!found)
6645 { 7130 {
@@ -6647,9 +7132,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6647 return; 7132 return;
6648 } 7133 }
6649 7134
6650 // the rest of the permission checks are done in RezScript, so check the pin there as well 7135 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6651 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7136 if (dest != null)
7137 {
7138 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7139 {
7140 // the rest of the permission checks are done in RezScript, so check the pin there as well
7141 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6652 7142
7143 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7144 m_host.Inventory.RemoveInventoryItem(srcId);
7145 }
7146 }
6653 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7147 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6654 ScriptSleep(3000); 7148 ScriptSleep(3000);
6655 } 7149 }
@@ -6712,19 +7206,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6712 public LSL_String llMD5String(string src, int nonce) 7206 public LSL_String llMD5String(string src, int nonce)
6713 { 7207 {
6714 m_host.AddScriptLPS(1); 7208 m_host.AddScriptLPS(1);
6715 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7209 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6716 } 7210 }
6717 7211
6718 public LSL_String llSHA1String(string src) 7212 public LSL_String llSHA1String(string src)
6719 { 7213 {
6720 m_host.AddScriptLPS(1); 7214 m_host.AddScriptLPS(1);
6721 return Util.SHA1Hash(src).ToLower(); 7215 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6722 } 7216 }
6723 7217
6724 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7218 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6725 { 7219 {
6726 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7220 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6727 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7221 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7222 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7223 return shapeBlock;
6728 7224
6729 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7225 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6730 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7226 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6829,6 +7325,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6829 // Prim type box, cylinder and prism. 7325 // Prim type box, cylinder and prism.
6830 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) 7326 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)
6831 { 7327 {
7328 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7329 return;
7330
6832 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7331 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6833 ObjectShapePacket.ObjectDataBlock shapeBlock; 7332 ObjectShapePacket.ObjectDataBlock shapeBlock;
6834 7333
@@ -6882,6 +7381,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6882 // Prim type sphere. 7381 // Prim type sphere.
6883 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7382 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6884 { 7383 {
7384 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7385 return;
7386
6885 ObjectShapePacket.ObjectDataBlock shapeBlock; 7387 ObjectShapePacket.ObjectDataBlock shapeBlock;
6886 7388
6887 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7389 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6923,6 +7425,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6923 // Prim type torus, tube and ring. 7425 // Prim type torus, tube and ring.
6924 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) 7426 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)
6925 { 7427 {
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return;
7430
6926 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7431 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6927 ObjectShapePacket.ObjectDataBlock shapeBlock; 7432 ObjectShapePacket.ObjectDataBlock shapeBlock;
6928 7433
@@ -7058,6 +7563,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7058 // Prim type sculpt. 7563 // Prim type sculpt.
7059 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7564 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7060 { 7565 {
7566 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7567 return;
7568
7061 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7569 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7062 UUID sculptId; 7570 UUID sculptId;
7063 7571
@@ -7082,7 +7590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7082 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7590 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7083 { 7591 {
7084 // default 7592 // default
7085 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7593 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7086 } 7594 }
7087 7595
7088 part.Shape.SetSculptProperties((byte)type, sculptId); 7596 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7098,32 +7606,119 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7098 ScriptSleep(200); 7606 ScriptSleep(200);
7099 } 7607 }
7100 7608
7101 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7609 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7102 { 7610 {
7103 m_host.AddScriptLPS(1); 7611 m_host.AddScriptLPS(1);
7104 7612
7105 setLinkPrimParams(linknumber, rules); 7613 setLinkPrimParams(linknumber, rules);
7106
7107 ScriptSleep(200);
7108 } 7614 }
7109 7615
7110 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7616 private void setLinkPrimParams(int linknumber, LSL_List rules)
7111 { 7617 {
7112 m_host.AddScriptLPS(1); 7618 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7619 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7620 if (parts.Count>0)
7621 {
7622 try
7623 {
7624 parts[0].ParentGroup.areUpdatesSuspended = true;
7625 foreach (SceneObjectPart part in parts)
7626 SetPrimParams(part, rules);
7627 }
7628 finally
7629 {
7630 parts[0].ParentGroup.areUpdatesSuspended = false;
7631 }
7632 }
7633 if (avatars.Count > 0)
7634 {
7635 foreach (ScenePresence avatar in avatars)
7636 SetPrimParams(avatar, rules);
7637 }
7638 }
7113 7639
7114 setLinkPrimParams(linknumber, rules); 7640 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7641 {
7642 llSetLinkPrimitiveParamsFast(linknumber, rules);
7643 ScriptSleep(200);
7115 } 7644 }
7116 7645
7117 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7646 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7118 { 7647 {
7119 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7648 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7649 //We only support PRIM_POSITION and PRIM_ROTATION
7120 7650
7121 foreach (SceneObjectPart part in parts) 7651 int idx = 0;
7122 SetPrimParams(part, rules); 7652
7653 while (idx < rules.Length)
7654 {
7655 int code = rules.GetLSLIntegerItem(idx++);
7656
7657 int remain = rules.Length - idx;
7658
7659 switch (code)
7660 {
7661 case (int)ScriptBaseClass.PRIM_POSITION:
7662 {
7663 if (remain < 1)
7664 return;
7665 LSL_Vector v;
7666 v = rules.GetVector3Item(idx++);
7667
7668 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7669 if (part == null)
7670 break;
7671
7672 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7673 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7674 if (llGetLinkNumber() > 1)
7675 {
7676 localRot = llGetLocalRot();
7677 localPos = llGetLocalPos();
7678 }
7679
7680 v -= localPos;
7681 v /= localRot;
7682
7683 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7684
7685 v = v + 2 * sitOffset;
7686
7687 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7688 av.SendAvatarDataToAllAgents();
7689
7690 }
7691 break;
7692
7693 case (int)ScriptBaseClass.PRIM_ROTATION:
7694 {
7695 if (remain < 1)
7696 return;
7697
7698 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7699 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7700 if (llGetLinkNumber() > 1)
7701 {
7702 localRot = llGetLocalRot();
7703 localPos = llGetLocalPos();
7704 }
7705
7706 LSL_Rotation r;
7707 r = rules.GetQuaternionItem(idx++);
7708 r = r * llGetRootRotation() / localRot;
7709 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7710 av.SendAvatarDataToAllAgents();
7711 }
7712 break;
7713 }
7714 }
7123 } 7715 }
7124 7716
7125 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7717 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7126 { 7718 {
7719 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7720 return;
7721
7127 int idx = 0; 7722 int idx = 0;
7128 7723
7129 bool positionChanged = false; 7724 bool positionChanged = false;
@@ -7151,6 +7746,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7151 currentPosition = GetSetPosTarget(part, v, currentPosition); 7746 currentPosition = GetSetPosTarget(part, v, currentPosition);
7152 7747
7153 break; 7748 break;
7749 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7750 if (remain < 1)
7751 return;
7752
7753 v=rules.GetVector3Item(idx++);
7754 positionChanged = true;
7755 currentPosition = GetSetPosTarget(part, v, currentPosition);
7756
7757 break;
7154 case (int)ScriptBaseClass.PRIM_SIZE: 7758 case (int)ScriptBaseClass.PRIM_SIZE:
7155 if (remain < 1) 7759 if (remain < 1)
7156 return; 7760 return;
@@ -7517,7 +8121,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7517 if (part.ParentGroup.RootPart == part) 8121 if (part.ParentGroup.RootPart == part)
7518 { 8122 {
7519 SceneObjectGroup parent = part.ParentGroup; 8123 SceneObjectGroup parent = part.ParentGroup;
7520 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8124 Util.FireAndForget(delegate(object x) {
8125 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8126 });
7521 } 8127 }
7522 else 8128 else
7523 { 8129 {
@@ -7528,6 +8134,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7528 } 8134 }
7529 } 8135 }
7530 } 8136 }
8137
8138 if (positionChanged)
8139 {
8140 if (part.ParentGroup.RootPart == part)
8141 {
8142 SceneObjectGroup parent = part.ParentGroup;
8143 Util.FireAndForget(delegate(object x) {
8144 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8145 });
8146 }
8147 else
8148 {
8149 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8150 SceneObjectGroup parent = part.ParentGroup;
8151 parent.HasGroupChanged = true;
8152 parent.ScheduleGroupForTerseUpdate();
8153 }
8154 }
7531 } 8155 }
7532 8156
7533 public LSL_String llStringToBase64(string str) 8157 public LSL_String llStringToBase64(string str)
@@ -7688,13 +8312,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7688 public LSL_Integer llGetNumberOfPrims() 8312 public LSL_Integer llGetNumberOfPrims()
7689 { 8313 {
7690 m_host.AddScriptLPS(1); 8314 m_host.AddScriptLPS(1);
7691 int avatarCount = 0; 8315 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7692 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8316
7693 {
7694 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7695 avatarCount++;
7696 });
7697
7698 return m_host.ParentGroup.PrimCount + avatarCount; 8317 return m_host.ParentGroup.PrimCount + avatarCount;
7699 } 8318 }
7700 8319
@@ -7710,55 +8329,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7710 m_host.AddScriptLPS(1); 8329 m_host.AddScriptLPS(1);
7711 UUID objID = UUID.Zero; 8330 UUID objID = UUID.Zero;
7712 LSL_List result = new LSL_List(); 8331 LSL_List result = new LSL_List();
8332
8333 // If the ID is not valid, return null result
7713 if (!UUID.TryParse(obj, out objID)) 8334 if (!UUID.TryParse(obj, out objID))
7714 { 8335 {
7715 result.Add(new LSL_Vector()); 8336 result.Add(new LSL_Vector());
7716 result.Add(new LSL_Vector()); 8337 result.Add(new LSL_Vector());
7717 return result; 8338 return result;
7718 } 8339 }
8340
8341 // Check if this is an attached prim. If so, replace
8342 // the UUID with the avatar UUID and report it's bounding box
8343 SceneObjectPart part = World.GetSceneObjectPart(objID);
8344 if (part != null && part.ParentGroup.IsAttachment)
8345 objID = part.ParentGroup.AttachedAvatar;
8346
8347 // Find out if this is an avatar ID. If so, return it's box
7719 ScenePresence presence = World.GetScenePresence(objID); 8348 ScenePresence presence = World.GetScenePresence(objID);
7720 if (presence != null) 8349 if (presence != null)
7721 { 8350 {
7722 if (presence.ParentID == 0) // not sat on an object 8351 // As per LSL Wiki, there is no difference between sitting
8352 // and standing avatar since server 1.36
8353 LSL_Vector lower;
8354 LSL_Vector upper;
8355 if (presence.Animator.Animations.DefaultAnimation.AnimID
8356 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7723 { 8357 {
7724 LSL_Vector lower; 8358 // This is for ground sitting avatars
7725 LSL_Vector upper; 8359 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7726 if (presence.Animator.Animations.DefaultAnimation.AnimID 8360 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7727 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8361 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7728 {
7729 // This is for ground sitting avatars
7730 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7731 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7732 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7733 }
7734 else
7735 {
7736 // This is for standing/flying avatars
7737 float height = presence.Appearance.AvatarHeight / 2.0f;
7738 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7739 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7740 }
7741 result.Add(lower);
7742 result.Add(upper);
7743 return result;
7744 } 8362 }
7745 else 8363 else
7746 { 8364 {
7747 // sitting on an object so we need the bounding box of that 8365 // This is for standing/flying avatars
7748 // which should include the avatar so set the UUID to the 8366 float height = presence.Appearance.AvatarHeight / 2.0f;
7749 // UUID of the object the avatar is sat on and allow it to fall through 8367 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7750 // to processing an object 8368 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7751 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7752 objID = p.UUID;
7753 } 8369 }
8370
8371 // Adjust to the documented error offsets (see LSL Wiki)
8372 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8373 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8374
8375 if (lower.x > upper.x)
8376 lower.x = upper.x;
8377 if (lower.y > upper.y)
8378 lower.y = upper.y;
8379 if (lower.z > upper.z)
8380 lower.z = upper.z;
8381
8382 result.Add(lower);
8383 result.Add(upper);
8384 return result;
7754 } 8385 }
7755 SceneObjectPart part = World.GetSceneObjectPart(objID); 8386
8387 part = World.GetSceneObjectPart(objID);
7756 // Currently only works for single prims without a sitting avatar 8388 // Currently only works for single prims without a sitting avatar
7757 if (part != null) 8389 if (part != null)
7758 { 8390 {
7759 Vector3 halfSize = part.Scale / 2.0f; 8391 float minX;
7760 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8392 float maxX;
7761 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8393 float minY;
8394 float maxY;
8395 float minZ;
8396 float maxZ;
8397
8398 // This BBox is in sim coordinates, with the offset being
8399 // a contained point.
8400 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8401 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8402
8403 minX -= offsets[0].X;
8404 maxX -= offsets[0].X;
8405 minY -= offsets[0].Y;
8406 maxY -= offsets[0].Y;
8407 minZ -= offsets[0].Z;
8408 maxZ -= offsets[0].Z;
8409
8410 LSL_Vector lower;
8411 LSL_Vector upper;
8412
8413 // Adjust to the documented error offsets (see LSL Wiki)
8414 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8415 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8416
8417 if (lower.x > upper.x)
8418 lower.x = upper.x;
8419 if (lower.y > upper.y)
8420 lower.y = upper.y;
8421 if (lower.z > upper.z)
8422 lower.z = upper.z;
8423
7762 result.Add(lower); 8424 result.Add(lower);
7763 result.Add(upper); 8425 result.Add(upper);
7764 return result; 8426 return result;
@@ -7838,13 +8500,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7838 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8500 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7839 part.AbsolutePosition.Y, 8501 part.AbsolutePosition.Y,
7840 part.AbsolutePosition.Z); 8502 part.AbsolutePosition.Z);
7841 // For some reason, the part.AbsolutePosition.* values do not change if the
7842 // linkset is rotated; they always reflect the child prim's world position
7843 // as though the linkset is unrotated. This is incompatible behavior with SL's
7844 // implementation, so will break scripts imported from there (not to mention it
7845 // makes it more difficult to determine a child prim's actual inworld position).
7846 if (part.ParentID != 0)
7847 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7848 res.Add(v); 8503 res.Add(v);
7849 break; 8504 break;
7850 8505
@@ -8015,56 +8670,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8015 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8670 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8016 if (remain < 1) 8671 if (remain < 1)
8017 return res; 8672 return res;
8018 8673 face = (int)rules.GetLSLIntegerItem(idx++);
8019 face=(int)rules.GetLSLIntegerItem(idx++);
8020 8674
8021 tex = part.Shape.Textures; 8675 tex = part.Shape.Textures;
8676 int shiny;
8022 if (face == ScriptBaseClass.ALL_SIDES) 8677 if (face == ScriptBaseClass.ALL_SIDES)
8023 { 8678 {
8024 for (face = 0; face < GetNumberOfSides(part); face++) 8679 for (face = 0; face < GetNumberOfSides(part); face++)
8025 { 8680 {
8026 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8681 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8027 // Convert Shininess to PRIM_SHINY_* 8682 if (shinyness == Shininess.High)
8028 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8683 {
8029 // PRIM_BUMP_* 8684 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8030 res.Add(new LSL_Integer((int)texface.Bump)); 8685 }
8686 else if (shinyness == Shininess.Medium)
8687 {
8688 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8689 }
8690 else if (shinyness == Shininess.Low)
8691 {
8692 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8693 }
8694 else
8695 {
8696 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8697 }
8698 res.Add(new LSL_Integer(shiny));
8699 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8031 } 8700 }
8032 } 8701 }
8033 else 8702 else
8034 { 8703 {
8035 if (face >= 0 && face < GetNumberOfSides(part)) 8704 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8705 if (shinyness == Shininess.High)
8036 { 8706 {
8037 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8707 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8038 // Convert Shininess to PRIM_SHINY_*
8039 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8040 // PRIM_BUMP_*
8041 res.Add(new LSL_Integer((int)texface.Bump));
8042 } 8708 }
8709 else if (shinyness == Shininess.Medium)
8710 {
8711 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8712 }
8713 else if (shinyness == Shininess.Low)
8714 {
8715 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8716 }
8717 else
8718 {
8719 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8720 }
8721 res.Add(new LSL_Integer(shiny));
8722 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8043 } 8723 }
8044 break; 8724 break;
8045 8725
8046 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8726 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8047 if (remain < 1) 8727 if (remain < 1)
8048 return res; 8728 return res;
8049 8729 face = (int)rules.GetLSLIntegerItem(idx++);
8050 face=(int)rules.GetLSLIntegerItem(idx++);
8051 8730
8052 tex = part.Shape.Textures; 8731 tex = part.Shape.Textures;
8732 int fullbright;
8053 if (face == ScriptBaseClass.ALL_SIDES) 8733 if (face == ScriptBaseClass.ALL_SIDES)
8054 { 8734 {
8055 for (face = 0; face < GetNumberOfSides(part); face++) 8735 for (face = 0; face < GetNumberOfSides(part); face++)
8056 { 8736 {
8057 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8737 if (tex.GetFace((uint)face).Fullbright == true)
8058 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8738 {
8739 fullbright = ScriptBaseClass.TRUE;
8740 }
8741 else
8742 {
8743 fullbright = ScriptBaseClass.FALSE;
8744 }
8745 res.Add(new LSL_Integer(fullbright));
8059 } 8746 }
8060 } 8747 }
8061 else 8748 else
8062 { 8749 {
8063 if (face >= 0 && face < GetNumberOfSides(part)) 8750 if (tex.GetFace((uint)face).Fullbright == true)
8064 { 8751 {
8065 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8752 fullbright = ScriptBaseClass.TRUE;
8066 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8753 }
8754 else
8755 {
8756 fullbright = ScriptBaseClass.FALSE;
8067 } 8757 }
8758 res.Add(new LSL_Integer(fullbright));
8068 } 8759 }
8069 break; 8760 break;
8070 8761
@@ -8086,27 +8777,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8086 break; 8777 break;
8087 8778
8088 case (int)ScriptBaseClass.PRIM_TEXGEN: 8779 case (int)ScriptBaseClass.PRIM_TEXGEN:
8780 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8089 if (remain < 1) 8781 if (remain < 1)
8090 return res; 8782 return res;
8091 8783 face = (int)rules.GetLSLIntegerItem(idx++);
8092 face=(int)rules.GetLSLIntegerItem(idx++);
8093 8784
8094 tex = part.Shape.Textures; 8785 tex = part.Shape.Textures;
8095 if (face == ScriptBaseClass.ALL_SIDES) 8786 if (face == ScriptBaseClass.ALL_SIDES)
8096 { 8787 {
8097 for (face = 0; face < GetNumberOfSides(part); face++) 8788 for (face = 0; face < GetNumberOfSides(part); face++)
8098 { 8789 {
8099 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8790 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8100 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8791 {
8101 res.Add(new LSL_Integer((uint)texgen >> 1)); 8792 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8793 }
8794 else
8795 {
8796 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8797 }
8102 } 8798 }
8103 } 8799 }
8104 else 8800 else
8105 { 8801 {
8106 if (face >= 0 && face < GetNumberOfSides(part)) 8802 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8803 {
8804 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8805 }
8806 else
8107 { 8807 {
8108 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8808 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8109 res.Add(new LSL_Integer((uint)texgen >> 1));
8110 } 8809 }
8111 } 8810 }
8112 break; 8811 break;
@@ -8129,28 +8828,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8129 case (int)ScriptBaseClass.PRIM_GLOW: 8828 case (int)ScriptBaseClass.PRIM_GLOW:
8130 if (remain < 1) 8829 if (remain < 1)
8131 return res; 8830 return res;
8132 8831 face = (int)rules.GetLSLIntegerItem(idx++);
8133 face=(int)rules.GetLSLIntegerItem(idx++);
8134 8832
8135 tex = part.Shape.Textures; 8833 tex = part.Shape.Textures;
8834 float primglow;
8136 if (face == ScriptBaseClass.ALL_SIDES) 8835 if (face == ScriptBaseClass.ALL_SIDES)
8137 { 8836 {
8138 for (face = 0; face < GetNumberOfSides(part); face++) 8837 for (face = 0; face < GetNumberOfSides(part); face++)
8139 { 8838 {
8140 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8839 primglow = tex.GetFace((uint)face).Glow;
8141 res.Add(new LSL_Float(texface.Glow)); 8840 res.Add(new LSL_Float(primglow));
8142 } 8841 }
8143 } 8842 }
8144 else 8843 else
8145 { 8844 {
8146 if (face >= 0 && face < GetNumberOfSides(part)) 8845 primglow = tex.GetFace((uint)face).Glow;
8147 { 8846 res.Add(new LSL_Float(primglow));
8148 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8149 res.Add(new LSL_Float(texface.Glow));
8150 }
8151 } 8847 }
8152 break; 8848 break;
8153
8154 case (int)ScriptBaseClass.PRIM_TEXT: 8849 case (int)ScriptBaseClass.PRIM_TEXT:
8155 Color4 textColor = part.GetTextColor(); 8850 Color4 textColor = part.GetTextColor();
8156 res.Add(new LSL_String(part.Text)); 8851 res.Add(new LSL_String(part.Text));
@@ -8762,8 +9457,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8762 // The function returns an ordered list 9457 // The function returns an ordered list
8763 // representing the tokens found in the supplied 9458 // representing the tokens found in the supplied
8764 // sources string. If two successive tokenizers 9459 // sources string. If two successive tokenizers
8765 // are encountered, then a NULL entry is added 9460 // are encountered, then a null-string entry is
8766 // to the list. 9461 // added to the list.
8767 // 9462 //
8768 // It is a precondition that the source and 9463 // It is a precondition that the source and
8769 // toekizer lisst are non-null. If they are null, 9464 // toekizer lisst are non-null. If they are null,
@@ -8771,7 +9466,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8771 // while their lengths are being determined. 9466 // while their lengths are being determined.
8772 // 9467 //
8773 // A small amount of working memoryis required 9468 // A small amount of working memoryis required
8774 // of approximately 8*#tokenizers. 9469 // of approximately 8*#tokenizers + 8*srcstrlen.
8775 // 9470 //
8776 // There are many ways in which this function 9471 // There are many ways in which this function
8777 // can be implemented, this implementation is 9472 // can be implemented, this implementation is
@@ -8787,155 +9482,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8787 // and eliminates redundant tokenizers as soon 9482 // and eliminates redundant tokenizers as soon
8788 // as is possible. 9483 // as is possible.
8789 // 9484 //
8790 // The implementation tries to avoid any copying 9485 // The implementation tries to minimize temporary
8791 // of arrays or other objects. 9486 // garbage generation.
8792 // </remarks> 9487 // </remarks>
8793 9488
8794 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9489 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8795 { 9490 {
8796 int beginning = 0; 9491 return ParseString2List(src, separators, spacers, true);
8797 int srclen = src.Length; 9492 }
8798 int seplen = separators.Length;
8799 object[] separray = separators.Data;
8800 int spclen = spacers.Length;
8801 object[] spcarray = spacers.Data;
8802 int mlen = seplen+spclen;
8803
8804 int[] offset = new int[mlen+1];
8805 bool[] active = new bool[mlen];
8806
8807 int best;
8808 int j;
8809
8810 // Initial capacity reduces resize cost
8811 9493
8812 LSL_List tokens = new LSL_List(); 9494 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9495 {
9496 int srclen = src.Length;
9497 int seplen = separators.Length;
9498 object[] separray = separators.Data;
9499 int spclen = spacers.Length;
9500 object[] spcarray = spacers.Data;
9501 int dellen = 0;
9502 string[] delarray = new string[seplen+spclen];
8813 9503
8814 // All entries are initially valid 9504 int outlen = 0;
9505 string[] outarray = new string[srclen*2+1];
8815 9506
8816 for (int i = 0; i < mlen; i++) 9507 int i, j;
8817 active[i] = true; 9508 string d;
8818 9509
8819 offset[mlen] = srclen; 9510 m_host.AddScriptLPS(1);
8820 9511
8821 while (beginning < srclen) 9512 /*
9513 * Convert separator and spacer lists to C# strings.
9514 * Also filter out null strings so we don't hang.
9515 */
9516 for (i = 0; i < seplen; i ++)
8822 { 9517 {
9518 d = separray[i].ToString();
9519 if (d.Length > 0)
9520 {
9521 delarray[dellen++] = d;
9522 }
9523 }
9524 seplen = dellen;
8823 9525
8824 best = mlen; // as bad as it gets 9526 for (i = 0; i < spclen; i ++)
9527 {
9528 d = spcarray[i].ToString();
9529 if (d.Length > 0)
9530 {
9531 delarray[dellen++] = d;
9532 }
9533 }
8825 9534
8826 // Scan for separators 9535 /*
9536 * Scan through source string from beginning to end.
9537 */
9538 for (i = 0;;)
9539 {
8827 9540
8828 for (j = 0; j < seplen; j++) 9541 /*
9542 * Find earliest delimeter in src starting at i (if any).
9543 */
9544 int earliestDel = -1;
9545 int earliestSrc = srclen;
9546 string earliestStr = null;
9547 for (j = 0; j < dellen; j ++)
8829 { 9548 {
8830 if (separray[j].ToString() == String.Empty) 9549 d = delarray[j];
8831 active[j] = false; 9550 if (d != null)
8832
8833 if (active[j])
8834 { 9551 {
8835 // scan all of the markers 9552 int index = src.IndexOf(d, i);
8836 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9553 if (index < 0)
8837 { 9554 {
8838 // not present at all 9555 delarray[j] = null; // delim nowhere in src, don't check it anymore
8839 active[j] = false;
8840 } 9556 }
8841 else 9557 else if (index < earliestSrc)
8842 { 9558 {
8843 // present and correct 9559 earliestSrc = index; // where delimeter starts in source string
8844 if (offset[j] < offset[best]) 9560 earliestDel = j; // where delimeter is in delarray[]
8845 { 9561 earliestStr = d; // the delimeter string from delarray[]
8846 // closest so far 9562 if (index == i) break; // can't do any better than found at beg of string
8847 best = j;
8848 if (offset[best] == beginning)
8849 break;
8850 }
8851 } 9563 }
8852 } 9564 }
8853 } 9565 }
8854 9566
8855 // Scan for spacers 9567 /*
8856 9568 * Output source string starting at i through start of earliest delimeter.
8857 if (offset[best] != beginning) 9569 */
9570 if (keepNulls || (earliestSrc > i))
8858 { 9571 {
8859 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9572 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8860 {
8861 if (spcarray[j-seplen].ToString() == String.Empty)
8862 active[j] = false;
8863
8864 if (active[j])
8865 {
8866 // scan all of the markers
8867 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8868 {
8869 // not present at all
8870 active[j] = false;
8871 }
8872 else
8873 {
8874 // present and correct
8875 if (offset[j] < offset[best])
8876 {
8877 // closest so far
8878 best = j;
8879 }
8880 }
8881 }
8882 }
8883 } 9573 }
8884 9574
8885 // This is the normal exit from the scanning loop 9575 /*
9576 * If no delimeter found at or after i, we're done scanning.
9577 */
9578 if (earliestDel < 0) break;
8886 9579
8887 if (best == mlen) 9580 /*
9581 * If delimeter was a spacer, output the spacer.
9582 */
9583 if (earliestDel >= seplen)
8888 { 9584 {
8889 // no markers were found on this pass 9585 outarray[outlen++] = earliestStr;
8890 // so we're pretty much done
8891 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8892 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8893 break;
8894 } 9586 }
8895 9587
8896 // Otherwise we just add the newly delimited token 9588 /*
8897 // and recalculate where the search should continue. 9589 * Look at rest of src string following delimeter.
8898 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9590 */
8899 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9591 i = earliestSrc + earliestStr.Length;
8900
8901 if (best < seplen)
8902 {
8903 beginning = offset[best] + (separray[best].ToString()).Length;
8904 }
8905 else
8906 {
8907 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8908 string str = spcarray[best - seplen].ToString();
8909 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8910 tokens.Add(new LSL_String(str));
8911 }
8912 } 9592 }
8913 9593
8914 // This an awkward an not very intuitive boundary case. If the 9594 /*
8915 // last substring is a tokenizer, then there is an implied trailing 9595 * Make up an exact-sized output array suitable for an LSL_List object.
8916 // null list entry. Hopefully the single comparison will not be too 9596 */
8917 // arduous. Alternatively the 'break' could be replced with a return 9597 object[] outlist = new object[outlen];
8918 // but that's shabby programming. 9598 for (i = 0; i < outlen; i ++)
8919
8920 if ((beginning == srclen) && (keepNulls))
8921 { 9599 {
8922 if (srclen != 0) 9600 outlist[i] = new LSL_String(outarray[i]);
8923 tokens.Add(new LSL_String(""));
8924 } 9601 }
8925 9602 return new LSL_List(outlist);
8926 return tokens;
8927 }
8928
8929 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8930 {
8931 m_host.AddScriptLPS(1);
8932 return this.ParseString(src, separators, spacers, false);
8933 }
8934
8935 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8936 {
8937 m_host.AddScriptLPS(1);
8938 return this.ParseString(src, separators, spacers, true);
8939 } 9603 }
8940 9604
8941 public LSL_Integer llGetObjectPermMask(int mask) 9605 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9012,28 +9676,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9012 { 9676 {
9013 m_host.AddScriptLPS(1); 9677 m_host.AddScriptLPS(1);
9014 9678
9015 lock (m_host.TaskInventory) 9679 m_host.TaskInventory.LockItemsForRead(true);
9680 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9016 { 9681 {
9017 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9682 if (inv.Value.Name == item)
9018 { 9683 {
9019 if (inv.Value.Name == item) 9684 m_host.TaskInventory.LockItemsForRead(false);
9685 switch (mask)
9020 { 9686 {
9021 switch (mask) 9687 case 0:
9022 { 9688 return (int)inv.Value.BasePermissions;
9023 case 0: 9689 case 1:
9024 return (int)inv.Value.BasePermissions; 9690 return (int)inv.Value.CurrentPermissions;
9025 case 1: 9691 case 2:
9026 return (int)inv.Value.CurrentPermissions; 9692 return (int)inv.Value.GroupPermissions;
9027 case 2: 9693 case 3:
9028 return (int)inv.Value.GroupPermissions; 9694 return (int)inv.Value.EveryonePermissions;
9029 case 3: 9695 case 4:
9030 return (int)inv.Value.EveryonePermissions; 9696 return (int)inv.Value.NextPermissions;
9031 case 4:
9032 return (int)inv.Value.NextPermissions;
9033 }
9034 } 9697 }
9035 } 9698 }
9036 } 9699 }
9700 m_host.TaskInventory.LockItemsForRead(false);
9037 9701
9038 return -1; 9702 return -1;
9039 } 9703 }
@@ -9080,16 +9744,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9080 { 9744 {
9081 m_host.AddScriptLPS(1); 9745 m_host.AddScriptLPS(1);
9082 9746
9083 lock (m_host.TaskInventory) 9747 m_host.TaskInventory.LockItemsForRead(true);
9748 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9084 { 9749 {
9085 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9750 if (inv.Value.Name == item)
9086 { 9751 {
9087 if (inv.Value.Name == item) 9752 m_host.TaskInventory.LockItemsForRead(false);
9088 { 9753 return inv.Value.CreatorID.ToString();
9089 return inv.Value.CreatorID.ToString();
9090 }
9091 } 9754 }
9092 } 9755 }
9756 m_host.TaskInventory.LockItemsForRead(false);
9093 9757
9094 llSay(0, "No item name '" + item + "'"); 9758 llSay(0, "No item name '" + item + "'");
9095 9759
@@ -9237,7 +9901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9237 } 9901 }
9238 9902
9239 /// <summary> 9903 /// <summary>
9240 /// illListReplaceList removes the sub-list defined by the inclusive indices 9904 /// llListReplaceList removes the sub-list defined by the inclusive indices
9241 /// start and end and inserts the src list in its place. The inclusive 9905 /// start and end and inserts the src list in its place. The inclusive
9242 /// nature of the indices means that at least one element must be deleted 9906 /// nature of the indices means that at least one element must be deleted
9243 /// if the indices are within the bounds of the existing list. I.e. 2,2 9907 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9294,16 +9958,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9294 // based upon end. Note that if end exceeds the upper 9958 // based upon end. Note that if end exceeds the upper
9295 // bound in this case, the entire destination list 9959 // bound in this case, the entire destination list
9296 // is removed. 9960 // is removed.
9297 else 9961 else if (start == 0)
9298 { 9962 {
9299 if (end + 1 < dest.Length) 9963 if (end + 1 < dest.Length)
9300 {
9301 return src + dest.GetSublist(end + 1, -1); 9964 return src + dest.GetSublist(end + 1, -1);
9302 }
9303 else 9965 else
9304 {
9305 return src; 9966 return src;
9306 } 9967 }
9968 else // Start < 0
9969 {
9970 if (end + 1 < dest.Length)
9971 return dest.GetSublist(end + 1, -1);
9972 else
9973 return new LSL_List();
9307 } 9974 }
9308 } 9975 }
9309 // Finally, if start > end, we strip away a prefix and 9976 // Finally, if start > end, we strip away a prefix and
@@ -9354,17 +10021,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9354 int width = 0; 10021 int width = 0;
9355 int height = 0; 10022 int height = 0;
9356 10023
9357 ParcelMediaCommandEnum? commandToSend = null; 10024 uint commandToSend = 0;
9358 float time = 0.0f; // default is from start 10025 float time = 0.0f; // default is from start
9359 10026
9360 ScenePresence presence = null; 10027 ScenePresence presence = null;
9361 10028
9362 for (int i = 0; i < commandList.Data.Length; i++) 10029 for (int i = 0; i < commandList.Data.Length; i++)
9363 { 10030 {
9364 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10031 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9365 switch (command) 10032 switch (command)
9366 { 10033 {
9367 case ParcelMediaCommandEnum.Agent: 10034 case (uint)ParcelMediaCommandEnum.Agent:
9368 // we send only to one agent 10035 // we send only to one agent
9369 if ((i + 1) < commandList.Length) 10036 if ((i + 1) < commandList.Length)
9370 { 10037 {
@@ -9381,25 +10048,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9381 } 10048 }
9382 break; 10049 break;
9383 10050
9384 case ParcelMediaCommandEnum.Loop: 10051 case (uint)ParcelMediaCommandEnum.Loop:
9385 loop = 1; 10052 loop = 1;
9386 commandToSend = command; 10053 commandToSend = command;
9387 update = true; //need to send the media update packet to set looping 10054 update = true; //need to send the media update packet to set looping
9388 break; 10055 break;
9389 10056
9390 case ParcelMediaCommandEnum.Play: 10057 case (uint)ParcelMediaCommandEnum.Play:
9391 loop = 0; 10058 loop = 0;
9392 commandToSend = command; 10059 commandToSend = command;
9393 update = true; //need to send the media update packet to make sure it doesn't loop 10060 update = true; //need to send the media update packet to make sure it doesn't loop
9394 break; 10061 break;
9395 10062
9396 case ParcelMediaCommandEnum.Pause: 10063 case (uint)ParcelMediaCommandEnum.Pause:
9397 case ParcelMediaCommandEnum.Stop: 10064 case (uint)ParcelMediaCommandEnum.Stop:
9398 case ParcelMediaCommandEnum.Unload: 10065 case (uint)ParcelMediaCommandEnum.Unload:
9399 commandToSend = command; 10066 commandToSend = command;
9400 break; 10067 break;
9401 10068
9402 case ParcelMediaCommandEnum.Url: 10069 case (uint)ParcelMediaCommandEnum.Url:
9403 if ((i + 1) < commandList.Length) 10070 if ((i + 1) < commandList.Length)
9404 { 10071 {
9405 if (commandList.Data[i + 1] is LSL_String) 10072 if (commandList.Data[i + 1] is LSL_String)
@@ -9412,7 +10079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9412 } 10079 }
9413 break; 10080 break;
9414 10081
9415 case ParcelMediaCommandEnum.Texture: 10082 case (uint)ParcelMediaCommandEnum.Texture:
9416 if ((i + 1) < commandList.Length) 10083 if ((i + 1) < commandList.Length)
9417 { 10084 {
9418 if (commandList.Data[i + 1] is LSL_String) 10085 if (commandList.Data[i + 1] is LSL_String)
@@ -9425,7 +10092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9425 } 10092 }
9426 break; 10093 break;
9427 10094
9428 case ParcelMediaCommandEnum.Time: 10095 case (uint)ParcelMediaCommandEnum.Time:
9429 if ((i + 1) < commandList.Length) 10096 if ((i + 1) < commandList.Length)
9430 { 10097 {
9431 if (commandList.Data[i + 1] is LSL_Float) 10098 if (commandList.Data[i + 1] is LSL_Float)
@@ -9437,7 +10104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 } 10104 }
9438 break; 10105 break;
9439 10106
9440 case ParcelMediaCommandEnum.AutoAlign: 10107 case (uint)ParcelMediaCommandEnum.AutoAlign:
9441 if ((i + 1) < commandList.Length) 10108 if ((i + 1) < commandList.Length)
9442 { 10109 {
9443 if (commandList.Data[i + 1] is LSL_Integer) 10110 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9451,7 +10118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9451 } 10118 }
9452 break; 10119 break;
9453 10120
9454 case ParcelMediaCommandEnum.Type: 10121 case (uint)ParcelMediaCommandEnum.Type:
9455 if ((i + 1) < commandList.Length) 10122 if ((i + 1) < commandList.Length)
9456 { 10123 {
9457 if (commandList.Data[i + 1] is LSL_String) 10124 if (commandList.Data[i + 1] is LSL_String)
@@ -9464,7 +10131,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 } 10131 }
9465 break; 10132 break;
9466 10133
9467 case ParcelMediaCommandEnum.Desc: 10134 case (uint)ParcelMediaCommandEnum.Desc:
9468 if ((i + 1) < commandList.Length) 10135 if ((i + 1) < commandList.Length)
9469 { 10136 {
9470 if (commandList.Data[i + 1] is LSL_String) 10137 if (commandList.Data[i + 1] is LSL_String)
@@ -9477,7 +10144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 } 10144 }
9478 break; 10145 break;
9479 10146
9480 case ParcelMediaCommandEnum.Size: 10147 case (uint)ParcelMediaCommandEnum.Size:
9481 if ((i + 2) < commandList.Length) 10148 if ((i + 2) < commandList.Length)
9482 { 10149 {
9483 if (commandList.Data[i + 1] is LSL_Integer) 10150 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9547,7 +10214,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9547 } 10214 }
9548 } 10215 }
9549 10216
9550 if (commandToSend != null) 10217 if (commandToSend != 0)
9551 { 10218 {
9552 // the commandList contained a start/stop/... command, too 10219 // the commandList contained a start/stop/... command, too
9553 if (presence == null) 10220 if (presence == null)
@@ -9584,7 +10251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9584 10251
9585 if (aList.Data[i] != null) 10252 if (aList.Data[i] != null)
9586 { 10253 {
9587 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10254 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9588 { 10255 {
9589 case ParcelMediaCommandEnum.Url: 10256 case ParcelMediaCommandEnum.Url:
9590 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10257 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9627,16 +10294,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 { 10294 {
9628 m_host.AddScriptLPS(1); 10295 m_host.AddScriptLPS(1);
9629 10296
9630 lock (m_host.TaskInventory) 10297 m_host.TaskInventory.LockItemsForRead(true);
10298 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9631 { 10299 {
9632 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10300 if (inv.Value.Name == name)
9633 { 10301 {
9634 if (inv.Value.Name == name) 10302 m_host.TaskInventory.LockItemsForRead(false);
9635 { 10303 return inv.Value.Type;
9636 return inv.Value.Type;
9637 }
9638 } 10304 }
9639 } 10305 }
10306 m_host.TaskInventory.LockItemsForRead(false);
9640 10307
9641 return -1; 10308 return -1;
9642 } 10309 }
@@ -9647,15 +10314,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 10314
9648 if (quick_pay_buttons.Data.Length < 4) 10315 if (quick_pay_buttons.Data.Length < 4)
9649 { 10316 {
9650 LSLError("List must have at least 4 elements"); 10317 int x;
9651 return; 10318 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10319 {
10320 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10321 }
9652 } 10322 }
9653 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10323 int[] nPrice = new int[5];
9654 10324 nPrice[0] = price;
9655 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10325 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9656 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10326 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9657 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10327 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9658 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10328 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10329 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9659 m_host.ParentGroup.HasGroupChanged = true; 10330 m_host.ParentGroup.HasGroupChanged = true;
9660 } 10331 }
9661 10332
@@ -9667,17 +10338,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9667 if (invItemID == UUID.Zero) 10338 if (invItemID == UUID.Zero)
9668 return new LSL_Vector(); 10339 return new LSL_Vector();
9669 10340
9670 lock (m_host.TaskInventory) 10341 m_host.TaskInventory.LockItemsForRead(true);
10342 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9671 { 10343 {
9672 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10344 m_host.TaskInventory.LockItemsForRead(false);
9673 return new LSL_Vector(); 10345 return new LSL_Vector();
10346 }
9674 10347
9675 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10348 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9676 { 10349 {
9677 ShoutError("No permissions to track the camera"); 10350 ShoutError("No permissions to track the camera");
9678 return new LSL_Vector(); 10351 m_host.TaskInventory.LockItemsForRead(false);
9679 } 10352 return new LSL_Vector();
9680 } 10353 }
10354 m_host.TaskInventory.LockItemsForRead(false);
9681 10355
9682 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10356 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9683 if (presence != null) 10357 if (presence != null)
@@ -9695,17 +10369,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 if (invItemID == UUID.Zero) 10369 if (invItemID == UUID.Zero)
9696 return new LSL_Rotation(); 10370 return new LSL_Rotation();
9697 10371
9698 lock (m_host.TaskInventory) 10372 m_host.TaskInventory.LockItemsForRead(true);
10373 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9699 { 10374 {
9700 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10375 m_host.TaskInventory.LockItemsForRead(false);
9701 return new LSL_Rotation(); 10376 return new LSL_Rotation();
9702 10377 }
9703 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10378 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9704 { 10379 {
9705 ShoutError("No permissions to track the camera"); 10380 ShoutError("No permissions to track the camera");
9706 return new LSL_Rotation(); 10381 m_host.TaskInventory.LockItemsForRead(false);
9707 } 10382 return new LSL_Rotation();
9708 } 10383 }
10384 m_host.TaskInventory.LockItemsForRead(false);
9709 10385
9710 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10386 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9711 if (presence != null) 10387 if (presence != null)
@@ -9767,8 +10443,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9767 { 10443 {
9768 m_host.AddScriptLPS(1); 10444 m_host.AddScriptLPS(1);
9769 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10445 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9770 if (detectedParams == null) return; // only works on the first detected avatar 10446 if (detectedParams == null)
9771 10447 {
10448 if (m_host.ParentGroup.IsAttachment == true)
10449 {
10450 detectedParams = new DetectParams();
10451 detectedParams.Key = m_host.OwnerID;
10452 }
10453 else
10454 {
10455 return;
10456 }
10457 }
10458
9772 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10459 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9773 if (avatar != null) 10460 if (avatar != null)
9774 { 10461 {
@@ -9776,6 +10463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9776 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10463 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9777 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10464 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9778 } 10465 }
10466
9779 ScriptSleep(1000); 10467 ScriptSleep(1000);
9780 } 10468 }
9781 10469
@@ -9887,14 +10575,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9887 if (objectID == UUID.Zero) return; 10575 if (objectID == UUID.Zero) return;
9888 10576
9889 UUID agentID; 10577 UUID agentID;
9890 lock (m_host.TaskInventory) 10578 m_host.TaskInventory.LockItemsForRead(true);
9891 { 10579 // we need the permission first, to know which avatar we want to set the camera for
9892 // we need the permission first, to know which avatar we want to set the camera for 10580 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9893 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9894 10581
9895 if (agentID == UUID.Zero) return; 10582 if (agentID == UUID.Zero)
9896 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10583 {
10584 m_host.TaskInventory.LockItemsForRead(false);
10585 return;
10586 }
10587 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10588 {
10589 m_host.TaskInventory.LockItemsForRead(false);
10590 return;
9897 } 10591 }
10592 m_host.TaskInventory.LockItemsForRead(false);
9898 10593
9899 ScenePresence presence = World.GetScenePresence(agentID); 10594 ScenePresence presence = World.GetScenePresence(agentID);
9900 10595
@@ -9903,12 +10598,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9903 10598
9904 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10599 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9905 object[] data = rules.Data; 10600 object[] data = rules.Data;
9906 for (int i = 0; i < data.Length; ++i) { 10601 for (int i = 0; i < data.Length; ++i)
10602 {
9907 int type = Convert.ToInt32(data[i++].ToString()); 10603 int type = Convert.ToInt32(data[i++].ToString());
9908 if (i >= data.Length) break; // odd number of entries => ignore the last 10604 if (i >= data.Length) break; // odd number of entries => ignore the last
9909 10605
9910 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10606 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9911 switch (type) { 10607 switch (type)
10608 {
9912 case ScriptBaseClass.CAMERA_FOCUS: 10609 case ScriptBaseClass.CAMERA_FOCUS:
9913 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10610 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9914 case ScriptBaseClass.CAMERA_POSITION: 10611 case ScriptBaseClass.CAMERA_POSITION:
@@ -9944,12 +10641,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9944 10641
9945 // we need the permission first, to know which avatar we want to clear the camera for 10642 // we need the permission first, to know which avatar we want to clear the camera for
9946 UUID agentID; 10643 UUID agentID;
9947 lock (m_host.TaskInventory) 10644 m_host.TaskInventory.LockItemsForRead(true);
10645 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10646 if (agentID == UUID.Zero)
10647 {
10648 m_host.TaskInventory.LockItemsForRead(false);
10649 return;
10650 }
10651 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9948 { 10652 {
9949 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10653 m_host.TaskInventory.LockItemsForRead(false);
9950 if (agentID == UUID.Zero) return; 10654 return;
9951 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9952 } 10655 }
10656 m_host.TaskInventory.LockItemsForRead(false);
9953 10657
9954 ScenePresence presence = World.GetScenePresence(agentID); 10658 ScenePresence presence = World.GetScenePresence(agentID);
9955 10659
@@ -10016,19 +10720,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10016 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10720 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10017 { 10721 {
10018 m_host.AddScriptLPS(1); 10722 m_host.AddScriptLPS(1);
10019 string ret = String.Empty; 10723
10020 string src1 = llBase64ToString(str1); 10724 if (str1 == String.Empty)
10021 string src2 = llBase64ToString(str2); 10725 return String.Empty;
10022 int c = 0; 10726 if (str2 == String.Empty)
10023 for (int i = 0; i < src1.Length; i++) 10727 return str1;
10728
10729 int len = str2.Length;
10730 if ((len % 4) != 0) // LL is EVIL!!!!
10731 {
10732 while (str2.EndsWith("="))
10733 str2 = str2.Substring(0, str2.Length - 1);
10734
10735 len = str2.Length;
10736 int mod = len % 4;
10737
10738 if (mod == 1)
10739 str2 = str2.Substring(0, str2.Length - 1);
10740 else if (mod == 2)
10741 str2 += "==";
10742 else if (mod == 3)
10743 str2 += "=";
10744 }
10745
10746 byte[] data1;
10747 byte[] data2;
10748 try
10749 {
10750 data1 = Convert.FromBase64String(str1);
10751 data2 = Convert.FromBase64String(str2);
10752 }
10753 catch (Exception)
10024 { 10754 {
10025 ret += (char) (src1[i] ^ src2[c]); 10755 return new LSL_String(String.Empty);
10756 }
10757
10758 byte[] d2 = new Byte[data1.Length];
10759 int pos = 0;
10760
10761 if (data1.Length <= data2.Length)
10762 {
10763 Array.Copy(data2, 0, d2, 0, data1.Length);
10764 }
10765 else
10766 {
10767 while (pos < data1.Length)
10768 {
10769 len = data1.Length - pos;
10770 if (len > data2.Length)
10771 len = data2.Length;
10026 10772
10027 c++; 10773 Array.Copy(data2, 0, d2, pos, len);
10028 if (c >= src2.Length) 10774 pos += len;
10029 c = 0; 10775 }
10030 } 10776 }
10031 return llStringToBase64(ret); 10777
10778 for (pos = 0 ; pos < data1.Length ; pos++ )
10779 data1[pos] ^= d2[pos];
10780
10781 return Convert.ToBase64String(data1);
10032 } 10782 }
10033 10783
10034 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10784 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10085,12 +10835,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 Regex r = new Regex(authregex); 10835 Regex r = new Regex(authregex);
10086 int[] gnums = r.GetGroupNumbers(); 10836 int[] gnums = r.GetGroupNumbers();
10087 Match m = r.Match(url); 10837 Match m = r.Match(url);
10088 if (m.Success) { 10838 if (m.Success)
10089 for (int i = 1; i < gnums.Length; i++) { 10839 {
10840 for (int i = 1; i < gnums.Length; i++)
10841 {
10090 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10842 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10091 //CaptureCollection cc = g.Captures; 10843 //CaptureCollection cc = g.Captures;
10092 } 10844 }
10093 if (m.Groups.Count == 5) { 10845 if (m.Groups.Count == 5)
10846 {
10094 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10847 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10095 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10848 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10096 } 10849 }
@@ -10376,15 +11129,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10376 11129
10377 internal UUID ScriptByName(string name) 11130 internal UUID ScriptByName(string name)
10378 { 11131 {
10379 lock (m_host.TaskInventory) 11132 m_host.TaskInventory.LockItemsForRead(true);
11133
11134 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10380 { 11135 {
10381 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11136 if (item.Type == 10 && item.Name == name)
10382 { 11137 {
10383 if (item.Type == 10 && item.Name == name) 11138 m_host.TaskInventory.LockItemsForRead(false);
10384 return item.ItemID; 11139 return item.ItemID;
10385 } 11140 }
10386 } 11141 }
10387 11142
11143 m_host.TaskInventory.LockItemsForRead(false);
11144
10388 return UUID.Zero; 11145 return UUID.Zero;
10389 } 11146 }
10390 11147
@@ -10425,6 +11182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10425 { 11182 {
10426 m_host.AddScriptLPS(1); 11183 m_host.AddScriptLPS(1);
10427 11184
11185 //Clone is thread safe
10428 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11186 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10429 11187
10430 UUID assetID = UUID.Zero; 11188 UUID assetID = UUID.Zero;
@@ -10487,6 +11245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10487 { 11245 {
10488 m_host.AddScriptLPS(1); 11246 m_host.AddScriptLPS(1);
10489 11247
11248 //Clone is thread safe
10490 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11249 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10491 11250
10492 UUID assetID = UUID.Zero; 11251 UUID assetID = UUID.Zero;
@@ -10567,15 +11326,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10567 return GetLinkPrimitiveParams(obj, rules); 11326 return GetLinkPrimitiveParams(obj, rules);
10568 } 11327 }
10569 11328
10570 public void print(string str) 11329 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10571 { 11330 {
10572 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11331 List<SceneObjectPart> parts = GetLinkParts(link);
10573 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11332 if (parts.Count < 1)
10574 if (ossl != null) 11333 return 0;
10575 { 11334
10576 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11335 return GetNumberOfSides(parts[0]);
10577 m_log.Info("LSL print():" + str);
10578 }
10579 } 11336 }
10580 11337
10581 private string Name2Username(string name) 11338 private string Name2Username(string name)
@@ -10621,153 +11378,397 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10621 return rq.ToString(); 11378 return rq.ToString();
10622 } 11379 }
10623 11380
11381 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11382 {
11383 m_SayShoutCount = 0;
11384 }
11385
11386 private struct Tri
11387 {
11388 public Vector3 p1;
11389 public Vector3 p2;
11390 public Vector3 p3;
11391 }
11392
11393 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11394 {
11395 float height = avatar.Appearance.AvatarHeight;
11396 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11397 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11398
11399 if (point.X > b1.X && point.X < b2.X &&
11400 point.Y > b1.Y && point.Y < b2.Y &&
11401 point.Z > b1.Z && point.Z < b2.Z)
11402 return true;
11403 return false;
11404 }
11405
11406 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11407 {
11408 List<ContactResult> contacts = new List<ContactResult>();
11409
11410 Vector3 ab = rayEnd - rayStart;
11411
11412 World.ForEachScenePresence(delegate(ScenePresence sp)
11413 {
11414 Vector3 ac = sp.AbsolutePosition - rayStart;
11415 Vector3 bc = sp.AbsolutePosition - rayEnd;
11416
11417 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11418
11419 if (d > 1.5)
11420 return;
11421
11422 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11423
11424 if (d2 > 0)
11425 return;
11426
11427 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11428 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11429
11430 if (!InBoundingBox(sp, p))
11431 return;
11432
11433 ContactResult result = new ContactResult ();
11434 result.ConsumerID = sp.LocalId;
11435 result.Depth = Vector3.Distance(rayStart, p);
11436 result.Normal = Vector3.Zero;
11437 result.Pos = p;
11438
11439 contacts.Add(result);
11440 });
11441
11442 return contacts.ToArray();
11443 }
11444
11445 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11446 {
11447 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11448 List<ContactResult> contacts = new List<ContactResult>();
11449
11450 Vector3 ab = rayEnd - rayStart;
11451
11452 World.ForEachSOG(delegate(SceneObjectGroup group)
11453 {
11454 if (m_host.ParentGroup == group)
11455 return;
11456
11457 if (group.IsAttachment)
11458 return;
11459
11460 if (group.RootPart.PhysActor == null)
11461 {
11462 if (!includePhantom)
11463 return;
11464 }
11465 else
11466 {
11467 if (group.RootPart.PhysActor.IsPhysical)
11468 {
11469 if (!includePhysical)
11470 return;
11471 }
11472 else
11473 {
11474 if (!includeNonPhysical)
11475 return;
11476 }
11477 }
11478
11479 // Find the radius ouside of which we don't even need to hit test
11480 float minX;
11481 float maxX;
11482 float minY;
11483 float maxY;
11484 float minZ;
11485 float maxZ;
11486
11487 float radius = 0.0f;
11488
11489 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11490
11491 if (Math.Abs(minX) > radius)
11492 radius = Math.Abs(minX);
11493 if (Math.Abs(minY) > radius)
11494 radius = Math.Abs(minY);
11495 if (Math.Abs(minZ) > radius)
11496 radius = Math.Abs(minZ);
11497 if (Math.Abs(maxX) > radius)
11498 radius = Math.Abs(maxX);
11499 if (Math.Abs(maxY) > radius)
11500 radius = Math.Abs(maxY);
11501 if (Math.Abs(maxZ) > radius)
11502 radius = Math.Abs(maxZ);
11503
11504 Vector3 ac = group.AbsolutePosition - rayStart;
11505 Vector3 bc = group.AbsolutePosition - rayEnd;
11506
11507 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11508
11509 // Too far off ray, don't bother
11510 if (d > radius)
11511 return;
11512
11513 // Behind ray, drop
11514 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11515 if (d2 > 0)
11516 return;
11517
11518 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11519 // Miss.
11520 if (!intersection.HitTF)
11521 return;
11522
11523 ContactResult result = new ContactResult ();
11524 result.ConsumerID = group.LocalId;
11525 result.Depth = intersection.distance;
11526 result.Normal = intersection.normal;
11527 result.Pos = intersection.ipoint;
11528
11529 contacts.Add(result);
11530 });
11531
11532 return contacts.ToArray();
11533 }
11534
11535 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11536 {
11537 double[,] heightfield = World.Heightmap.GetDoubles();
11538 List<ContactResult> contacts = new List<ContactResult>();
11539
11540 double min = 2048.0;
11541 double max = 0.0;
11542
11543 // Find the min and max of the heightfield
11544 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11545 {
11546 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11547 {
11548 if (heightfield[x, y] > max)
11549 max = heightfield[x, y];
11550 if (heightfield[x, y] < min)
11551 min = heightfield[x, y];
11552 }
11553 }
11554
11555
11556 // A ray extends past rayEnd, but doesn't go back before
11557 // rayStart. If the start is above the highest point of the ground
11558 // and the ray goes up, we can't hit the ground. Ever.
11559 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11560 return null;
11561
11562 // Same for going down
11563 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11564 return null;
11565
11566 List<Tri> trilist = new List<Tri>();
11567
11568 // Create our triangle list
11569 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11570 {
11571 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11572 {
11573 Tri t1 = new Tri();
11574 Tri t2 = new Tri();
11575
11576 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11577 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11578 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11579 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11580
11581 t1.p1 = p1;
11582 t1.p2 = p2;
11583 t1.p3 = p3;
11584
11585 t2.p1 = p3;
11586 t2.p2 = p4;
11587 t2.p3 = p1;
11588
11589 trilist.Add(t1);
11590 trilist.Add(t2);
11591 }
11592 }
11593
11594 // Ray direction
11595 Vector3 rayDirection = rayEnd - rayStart;
11596
11597 foreach (Tri t in trilist)
11598 {
11599 // Compute triangle plane normal and edges
11600 Vector3 u = t.p2 - t.p1;
11601 Vector3 v = t.p3 - t.p1;
11602 Vector3 n = Vector3.Cross(u, v);
11603
11604 if (n == Vector3.Zero)
11605 continue;
11606
11607 Vector3 w0 = rayStart - t.p1;
11608 double a = -Vector3.Dot(n, w0);
11609 double b = Vector3.Dot(n, rayDirection);
11610
11611 // Not intersecting the plane, or in plane (same thing)
11612 // Ignoring this MAY cause the ground to not be detected
11613 // sometimes
11614 if (Math.Abs(b) < 0.000001)
11615 continue;
11616
11617 double r = a / b;
11618
11619 // ray points away from plane
11620 if (r < 0.0)
11621 continue;
11622
11623 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11624
11625 float uu = Vector3.Dot(u, u);
11626 float uv = Vector3.Dot(u, v);
11627 float vv = Vector3.Dot(v, v);
11628 Vector3 w = ip - t.p1;
11629 float wu = Vector3.Dot(w, u);
11630 float wv = Vector3.Dot(w, v);
11631 float d = uv * uv - uu * vv;
11632
11633 float cs = (uv * wv - vv * wu) / d;
11634 if (cs < 0 || cs > 1.0)
11635 continue;
11636 float ct = (uv * wu - uu * wv) / d;
11637 if (ct < 0 || (cs + ct) > 1.0)
11638 continue;
11639
11640 // Add contact point
11641 ContactResult result = new ContactResult ();
11642 result.ConsumerID = 0;
11643 result.Depth = Vector3.Distance(rayStart, ip);
11644 result.Normal = n;
11645 result.Pos = ip;
11646
11647 contacts.Add(result);
11648 }
11649
11650 if (contacts.Count == 0)
11651 return null;
11652
11653 contacts.Sort(delegate(ContactResult a, ContactResult b)
11654 {
11655 return (int)(a.Depth - b.Depth);
11656 });
11657
11658 return contacts[0];
11659 }
11660
10624 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11661 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10625 { 11662 {
11663 LSL_List list = new LSL_List();
11664
10626 m_host.AddScriptLPS(1); 11665 m_host.AddScriptLPS(1);
10627 11666
10628 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11667 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10629 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11668 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10630 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11669 Vector3 dir = rayEnd - rayStart;
10631 11670
10632 int count = 0; 11671 float dist = Vector3.Mag(dir);
10633// int detectPhantom = 0; 11672
11673 int count = 1;
11674 bool detectPhantom = false;
10634 int dataFlags = 0; 11675 int dataFlags = 0;
10635 int rejectTypes = 0; 11676 int rejectTypes = 0;
10636 11677
10637 for (int i = 0; i < options.Length; i += 2) 11678 for (int i = 0; i < options.Length; i += 2)
10638 { 11679 {
10639 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11680 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10640 {
10641 count = options.GetLSLIntegerItem(i + 1); 11681 count = options.GetLSLIntegerItem(i + 1);
10642 } 11682 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10643// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11683 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10644// {
10645// detectPhantom = options.GetLSLIntegerItem(i + 1);
10646// }
10647 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11684 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10648 {
10649 dataFlags = options.GetLSLIntegerItem(i + 1); 11685 dataFlags = options.GetLSLIntegerItem(i + 1);
10650 }
10651 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11686 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10652 {
10653 rejectTypes = options.GetLSLIntegerItem(i + 1); 11687 rejectTypes = options.GetLSLIntegerItem(i + 1);
10654 }
10655 } 11688 }
10656 11689
10657 LSL_List list = new LSL_List(); 11690 if (count > 16)
10658 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11691 count = 16;
10659 11692
10660 double distance = Util.GetDistanceTo(startvector, endvector); 11693 List<ContactResult> results = new List<ContactResult>();
10661
10662 if (distance == 0)
10663 distance = 0.001;
10664
10665 Vector3 posToCheck = startvector;
10666 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10667 11694
10668 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11695 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10669 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11696 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10670 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11697 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10671 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11698 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10672 11699
10673 for (float i = 0; i <= distance; i += 0.1f) 11700 if (checkTerrain)
10674 { 11701 {
10675 posToCheck = startvector + (dir * (i / (float)distance)); 11702 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11703 if (groundContact != null)
11704 results.Add((ContactResult)groundContact);
11705 }
10676 11706
10677 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11707 if (checkAgents)
10678 { 11708 {
10679 ContactResult result = new ContactResult(); 11709 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10680 result.ConsumerID = 0; 11710 foreach (ContactResult r in agentHits)
10681 result.Depth = 0; 11711 results.Add(r);
10682 result.Normal = Vector3.Zero; 11712 }
10683 result.Pos = posToCheck;
10684 results.Add(result);
10685 checkTerrain = false;
10686 }
10687 11713
10688 if (checkAgents) 11714 if (checkPhysical || checkNonPhysical)
10689 { 11715 {
10690 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11716 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10691 { 11717 foreach (ContactResult r in objectHits)
10692 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11718 results.Add(r);
10693 {
10694 ContactResult result = new ContactResult ();
10695 result.ConsumerID = sp.LocalId;
10696 result.Depth = 0;
10697 result.Normal = Vector3.Zero;
10698 result.Pos = posToCheck;
10699 results.Add(result);
10700 }
10701 });
10702 }
10703 } 11719 }
10704 11720
10705 int refcount = 0; 11721 results.Sort(delegate(ContactResult a, ContactResult b)
11722 {
11723 return (int)(a.Depth - b.Depth);
11724 });
11725
11726 int values = 0;
10706 foreach (ContactResult result in results) 11727 foreach (ContactResult result in results)
10707 { 11728 {
10708 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11729 if (result.Depth > dist)
10709 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10710 continue; 11730 continue;
10711 11731
10712 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11732 UUID itemID = UUID.Zero;
10713 11733 int linkNum = 0;
10714 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10715 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10716 11734
10717 if (entity == null) 11735 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11736 // It's a prim!
11737 if (part != null)
10718 { 11738 {
10719 list.Add(UUID.Zero); 11739 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10720 11740 itemID = part.ParentGroup.UUID;
10721 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11741 else
10722 list.Add(0); 11742 itemID = part.UUID;
10723
10724 list.Add(result.Pos);
10725
10726 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10727 list.Add(result.Normal);
10728 11743
10729 continue; //Can't find it, so add UUID.Zero 11744 linkNum = part.LinkNum;
10730 } 11745 }
10731 11746 else
10732 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10733 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10734 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10735
10736 if (entity is SceneObjectPart)
10737 { 11747 {
10738 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11748 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10739 { 11749 /// It it a boy? a girl?
10740 if (!checkPhysical) 11750 if (sp != null)
10741 continue; 11751 itemID = sp.UUID;
10742 }
10743 else
10744 {
10745 if (!checkNonPhysical)
10746 continue;
10747 }
10748 } 11752 }
10749 11753
10750 refcount++; 11754 list.Add(new LSL_String(itemID.ToString()));
10751 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11755 list.Add(new LSL_String(result.Pos.ToString()));
10752 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10753 else
10754 list.Add(entity.UUID);
10755 11756
10756 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11757 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10757 { 11758 list.Add(new LSL_Integer(linkNum));
10758 if (entity is SceneObjectPart)
10759 list.Add(((SceneObjectPart)entity).LinkNum);
10760 else
10761 list.Add(0);
10762 }
10763 11759
10764 list.Add(result.Pos);
10765 11760
10766 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11761 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10767 list.Add(result.Normal); 11762 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11763
11764 values++;
11765 count--;
11766
11767 if (count == 0)
11768 break;
10768 } 11769 }
10769 11770
10770 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11771 list.Add(new LSL_Integer(values));
10771 11772
10772 return list; 11773 return list;
10773 } 11774 }
@@ -10807,7 +11808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10807 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11808 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10808 if (!isAccount) return 0; 11809 if (!isAccount) return 0;
10809 if (estate.HasAccess(id)) return 1; 11810 if (estate.HasAccess(id)) return 1;
10810 if (estate.IsBanned(id)) 11811 if (estate.IsBanned(id, World.GetUserFlags(id)))
10811 estate.RemoveBan(id); 11812 estate.RemoveBan(id);
10812 estate.AddEstateUser(id); 11813 estate.AddEstateUser(id);
10813 break; 11814 break;
@@ -10826,14 +11827,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10826 break; 11827 break;
10827 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11828 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10828 if (!isAccount) return 0; 11829 if (!isAccount) return 0;
10829 if (estate.IsBanned(id)) return 1; 11830 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10830 EstateBan ban = new EstateBan(); 11831 EstateBan ban = new EstateBan();
10831 ban.EstateID = estate.EstateID; 11832 ban.EstateID = estate.EstateID;
10832 ban.BannedUserID = id; 11833 ban.BannedUserID = id;
10833 estate.AddBan(ban); 11834 estate.AddBan(ban);
10834 break; 11835 break;
10835 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11836 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10836 if (!isAccount || !estate.IsBanned(id)) return 0; 11837 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10837 estate.RemoveBan(id); 11838 estate.RemoveBan(id);
10838 break; 11839 break;
10839 default: return 0; 11840 default: return 0;
@@ -10859,22 +11860,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10859 NotImplemented("llGetSPMaxMemory"); 11860 NotImplemented("llGetSPMaxMemory");
10860 } 11861 }
10861 11862
10862 public void llGetUsedMemory() 11863 public virtual LSL_Integer llGetUsedMemory()
10863 { 11864 {
10864 m_host.AddScriptLPS(1); 11865 m_host.AddScriptLPS(1);
10865 NotImplemented("llGetUsedMemory"); 11866 NotImplemented("llGetUsedMemory");
11867 return 0;
10866 } 11868 }
10867 11869
10868 public void llScriptProfiler(LSL_Integer flags) 11870 public void llScriptProfiler(LSL_Integer flags)
10869 { 11871 {
10870 m_host.AddScriptLPS(1); 11872 m_host.AddScriptLPS(1);
10871 NotImplemented("llScriptProfiler"); 11873 //NotImplemented("llScriptProfiler");
10872 } 11874 }
10873 11875
10874 public void llSetSoundQueueing(int queue) 11876 public void llSetSoundQueueing(int queue)
10875 { 11877 {
10876 m_host.AddScriptLPS(1); 11878 m_host.AddScriptLPS(1);
10877 NotImplemented("llSetSoundQueueing");
10878 } 11879 }
10879 11880
10880 public void llCollisionSprite(string impact_sprite) 11881 public void llCollisionSprite(string impact_sprite)
@@ -10886,10 +11887,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10886 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11887 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10887 { 11888 {
10888 m_host.AddScriptLPS(1); 11889 m_host.AddScriptLPS(1);
10889 NotImplemented("llGodLikeRezObject"); 11890
11891 if (!World.Permissions.IsGod(m_host.OwnerID))
11892 NotImplemented("llGodLikeRezObject");
11893
11894 AssetBase rezAsset = World.AssetService.Get(inventory);
11895 if (rezAsset == null)
11896 {
11897 llSay(0, "Asset not found");
11898 return;
11899 }
11900
11901 SceneObjectGroup group = null;
11902
11903 try
11904 {
11905 string xmlData = Utils.BytesToString(rezAsset.Data);
11906 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11907 }
11908 catch
11909 {
11910 llSay(0, "Asset not found");
11911 return;
11912 }
11913
11914 if (group == null)
11915 {
11916 llSay(0, "Asset not found");
11917 return;
11918 }
11919
11920 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11921 group.RootPart.AttachOffset = group.AbsolutePosition;
11922
11923 group.ResetIDs();
11924
11925 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11926 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11927 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11928 group.ScheduleGroupForFullUpdate();
11929
11930 // objects rezzed with this method are die_at_edge by default.
11931 group.RootPart.SetDieAtEdge(true);
11932
11933 group.ResumeScripts();
11934
11935 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11936 "object_rez", new Object[] {
11937 new LSL_String(
11938 group.RootPart.UUID.ToString()) },
11939 new DetectParams[0]));
11940 }
11941
11942 public LSL_String llTransferLindenDollars(string destination, int amount)
11943 {
11944 UUID txn = UUID.Random();
11945
11946 Util.FireAndForget(delegate(object x)
11947 {
11948 int replycode = 0;
11949 string replydata = destination + "," + amount.ToString();
11950
11951 try
11952 {
11953 UUID invItemID=InventorySelf();
11954 if (invItemID == UUID.Zero)
11955 {
11956 replydata = "SERVICE_ERROR";
11957 return;
11958 }
11959
11960 m_host.AddScriptLPS(1);
11961
11962 m_host.TaskInventory.LockItemsForRead(true);
11963 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11964 m_host.TaskInventory.LockItemsForRead(false);
11965
11966 if (item.PermsGranter == UUID.Zero)
11967 {
11968 replydata = "MISSING_PERMISSION_DEBIT";
11969 return;
11970 }
11971
11972 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11973 {
11974 replydata = "MISSING_PERMISSION_DEBIT";
11975 return;
11976 }
11977
11978 UUID toID = new UUID();
11979
11980 if (!UUID.TryParse(destination, out toID))
11981 {
11982 replydata = "INVALID_AGENT";
11983 return;
11984 }
11985
11986 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11987
11988 if (money == null)
11989 {
11990 replydata = "TRANSFERS_DISABLED";
11991 return;
11992 }
11993
11994 bool result = money.ObjectGiveMoney(
11995 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11996
11997 if (result)
11998 {
11999 replycode = 1;
12000 return;
12001 }
12002
12003 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12004 }
12005 finally
12006 {
12007 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12008 "transaction_result", new Object[] {
12009 new LSL_String(txn.ToString()),
12010 new LSL_Integer(replycode),
12011 new LSL_String(replydata) },
12012 new DetectParams[0]));
12013 }
12014 });
12015
12016 return txn.ToString();
10890 } 12017 }
10891 12018
10892 #endregion 12019 #endregion
12020
12021 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12022 {
12023 SceneObjectGroup group = m_host.ParentGroup;
12024
12025 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12026 return;
12027 if (group.IsAttachment)
12028 return;
12029
12030 if (frames.Data.Length > 0) // We are getting a new motion
12031 {
12032 if (group.RootPart.KeyframeMotion != null)
12033 group.RootPart.KeyframeMotion.Stop();
12034 group.RootPart.KeyframeMotion = null;
12035
12036 int idx = 0;
12037
12038 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12039 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12040
12041 while (idx < options.Data.Length)
12042 {
12043 int option = (int)options.GetLSLIntegerItem(idx++);
12044 int remain = options.Data.Length - idx;
12045
12046 switch (option)
12047 {
12048 case ScriptBaseClass.KFM_MODE:
12049 if (remain < 1)
12050 break;
12051 int modeval = (int)options.GetLSLIntegerItem(idx++);
12052 switch(modeval)
12053 {
12054 case ScriptBaseClass.KFM_FORWARD:
12055 mode = KeyframeMotion.PlayMode.Forward;
12056 break;
12057 case ScriptBaseClass.KFM_REVERSE:
12058 mode = KeyframeMotion.PlayMode.Reverse;
12059 break;
12060 case ScriptBaseClass.KFM_LOOP:
12061 mode = KeyframeMotion.PlayMode.Loop;
12062 break;
12063 case ScriptBaseClass.KFM_PING_PONG:
12064 mode = KeyframeMotion.PlayMode.PingPong;
12065 break;
12066 }
12067 break;
12068 case ScriptBaseClass.KFM_DATA:
12069 if (remain < 1)
12070 break;
12071 int dataval = (int)options.GetLSLIntegerItem(idx++);
12072 data = (KeyframeMotion.DataFormat)dataval;
12073 break;
12074 }
12075 }
12076
12077 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12078
12079 idx = 0;
12080
12081 int elemLength = 2;
12082 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12083 elemLength = 3;
12084
12085 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12086 while (idx < frames.Data.Length)
12087 {
12088 int remain = frames.Data.Length - idx;
12089
12090 if (remain < elemLength)
12091 break;
12092
12093 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12094 frame.Position = null;
12095 frame.Rotation = null;
12096
12097 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12098 {
12099 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12100 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12101 }
12102 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12103 {
12104 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12105 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12106 }
12107
12108 float tempf = (float)frames.GetLSLFloatItem(idx++);
12109 frame.TimeMS = (int)(tempf * 1000.0f);
12110
12111 keyframes.Add(frame);
12112 }
12113
12114 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12115 group.RootPart.KeyframeMotion.Start();
12116 }
12117 else
12118 {
12119 if (group.RootPart.KeyframeMotion == null)
12120 return;
12121
12122 if (options.Data.Length == 0)
12123 {
12124 group.RootPart.KeyframeMotion.Stop();
12125 return;
12126 }
12127
12128 int code = (int)options.GetLSLIntegerItem(0);
12129
12130 int idx = 0;
12131
12132 while (idx < options.Data.Length)
12133 {
12134 int option = (int)options.GetLSLIntegerItem(idx++);
12135 int remain = options.Data.Length - idx;
12136
12137 switch (option)
12138 {
12139 case ScriptBaseClass.KFM_COMMAND:
12140 int cmd = (int)options.GetLSLIntegerItem(idx++);
12141 switch (cmd)
12142 {
12143 case ScriptBaseClass.KFM_CMD_PLAY:
12144 group.RootPart.KeyframeMotion.Start();
12145 break;
12146 case ScriptBaseClass.KFM_CMD_STOP:
12147 group.RootPart.KeyframeMotion.Stop();
12148 break;
12149 case ScriptBaseClass.KFM_CMD_PAUSE:
12150 group.RootPart.KeyframeMotion.Pause();
12151 break;
12152 }
12153 break;
12154 }
12155 }
12156 }
12157 }
10893 } 12158 }
10894 12159
10895 public class NotecardCache 12160 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8edd146..ecc5fb5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 private void InitLSL() 221 private void InitLSL()
@@ -917,18 +926,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
917 if (target != null) 926 if (target != null)
918 { 927 {
919 UUID animID=UUID.Zero; 928 UUID animID=UUID.Zero;
920 lock (m_host.TaskInventory) 929 m_host.TaskInventory.LockItemsForRead(true);
930 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
921 { 931 {
922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 932 if (inv.Value.Name == animation)
923 { 933 {
924 if (inv.Value.Name == animation) 934 if (inv.Value.Type == (int)AssetType.Animation)
925 { 935 animID = inv.Value.AssetID;
926 if (inv.Value.Type == (int)AssetType.Animation) 936 continue;
927 animID = inv.Value.AssetID;
928 continue;
929 }
930 } 937 }
931 } 938 }
939 m_host.TaskInventory.LockItemsForRead(false);
932 if (animID == UUID.Zero) 940 if (animID == UUID.Zero)
933 target.Animator.AddAnimation(animation, m_host.UUID); 941 target.Animator.AddAnimation(animation, m_host.UUID);
934 else 942 else
@@ -955,18 +963,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
955 if (target != null) 963 if (target != null)
956 { 964 {
957 UUID animID = UUID.Zero; 965 UUID animID = UUID.Zero;
958 lock (m_host.TaskInventory) 966 m_host.TaskInventory.LockItemsForRead(true);
967 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
959 { 968 {
960 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 969 if (inv.Value.Name == animation)
961 { 970 {
962 if (inv.Value.Name == animation) 971 if (inv.Value.Type == (int)AssetType.Animation)
963 { 972 animID = inv.Value.AssetID;
964 if (inv.Value.Type == (int)AssetType.Animation) 973 continue;
965 animID = inv.Value.AssetID;
966 continue;
967 }
968 } 974 }
969 } 975 }
976 m_host.TaskInventory.LockItemsForRead(false);
970 977
971 if (animID == UUID.Zero) 978 if (animID == UUID.Zero)
972 target.Animator.RemoveAnimation(animation); 979 target.Animator.RemoveAnimation(animation);
@@ -1798,6 +1805,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1798 1805
1799 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1806 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1800 { 1807 {
1808 m_host.TaskInventory.LockItemsForRead(true);
1801 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1809 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1802 { 1810 {
1803 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1811 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1805,6 +1813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1805 assetID = item.AssetID; 1813 assetID = item.AssetID;
1806 } 1814 }
1807 } 1815 }
1816 m_host.TaskInventory.LockItemsForRead(false);
1808 } 1817 }
1809 1818
1810 if (assetID == UUID.Zero) 1819 if (assetID == UUID.Zero)
@@ -2258,7 +2267,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2258 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2267 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2259 m_host.AddScriptLPS(1); 2268 m_host.AddScriptLPS(1);
2260 2269
2261 return NpcCreate(firstname, lastname, position, notecard, false, false); 2270 return NpcCreate(firstname, lastname, position, notecard, true, false);
2262 } 2271 }
2263 2272
2264 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2273 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2269,24 +2278,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2269 return NpcCreate( 2278 return NpcCreate(
2270 firstname, lastname, position, notecard, 2279 firstname, lastname, position, notecard,
2271 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2280 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2272 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2281 false);
2282// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2273 } 2283 }
2274 2284
2275 private LSL_Key NpcCreate( 2285 private LSL_Key NpcCreate(
2276 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2286 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2277 { 2287 {
2288 if (!owned)
2289 OSSLError("Unowned NPCs are unsupported");
2290
2291 string groupTitle = String.Empty;
2292
2293 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2294 return new LSL_Key(UUID.Zero.ToString());
2295
2296 if (firstname != String.Empty || lastname != String.Empty)
2297 {
2298 if (firstname != "Shown outfit:")
2299 groupTitle = "- NPC -";
2300 }
2301
2278 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2302 INPCModule module = World.RequestModuleInterface<INPCModule>();
2279 if (module != null) 2303 if (module != null)
2280 { 2304 {
2281 AvatarAppearance appearance = null; 2305 AvatarAppearance appearance = null;
2282 2306
2283 UUID id; 2307// UUID id;
2284 if (UUID.TryParse(notecard, out id)) 2308// if (UUID.TryParse(notecard, out id))
2285 { 2309// {
2286 ScenePresence clonePresence = World.GetScenePresence(id); 2310// ScenePresence clonePresence = World.GetScenePresence(id);
2287 if (clonePresence != null) 2311// if (clonePresence != null)
2288 appearance = clonePresence.Appearance; 2312// appearance = clonePresence.Appearance;
2289 } 2313// }
2290 2314
2291 if (appearance == null) 2315 if (appearance == null)
2292 { 2316 {
@@ -2314,6 +2338,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2314 World, 2338 World,
2315 appearance); 2339 appearance);
2316 2340
2341 ScenePresence sp;
2342 if (World.TryGetScenePresence(x, out sp))
2343 {
2344 sp.Grouptitle = groupTitle;
2345 sp.SendAvatarDataToAllAgents();
2346 }
2317 return new LSL_Key(x.ToString()); 2347 return new LSL_Key(x.ToString());
2318 } 2348 }
2319 2349
@@ -2582,16 +2612,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2582 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2612 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2583 m_host.AddScriptLPS(1); 2613 m_host.AddScriptLPS(1);
2584 2614
2585 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2615 ManualResetEvent ev = new ManualResetEvent(false);
2586 if (module != null)
2587 {
2588 UUID npcId = new UUID(npc.m_string);
2589 2616
2590 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2617 Util.FireAndForget(delegate(object x) {
2591 return; 2618 try
2619 {
2620 INPCModule module = World.RequestModuleInterface<INPCModule>();
2621 if (module != null)
2622 {
2623 UUID npcId = new UUID(npc.m_string);
2592 2624
2593 module.DeleteNPC(npcId, World); 2625 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2594 } 2626 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2627 {
2628 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2629 return;
2630 }
2631
2632 module.DeleteNPC(npcId, World);
2633 }
2634 }
2635 finally
2636 {
2637 ev.Set();
2638 }
2639 });
2640 ev.WaitOne();
2595 } 2641 }
2596 2642
2597 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2643 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -2944,4 +2990,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2990 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2945 } 2991 }
2946 } 2992 }
2947} \ No newline at end of file 2993}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 1c272f8..1373971 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
222 // Is the sensor type is AGENT and not SCRIPTED then include agents 222 // Is the sensor type is AGENT and not SCRIPTED then include agents
223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
224 { 224 {
225 sensedEntities.AddRange(doAgentSensor(ts)); 225 sensedEntities.AddRange(doAgentSensor(ts));
226 } 226 }
227 227
228 // If SCRIPTED or PASSIVE or ACTIVE check objects 228 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -319,13 +319,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.RotationOffset; 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, the sensor cone always orients with the 326 // In attachments, the sensor cone always orients with the
326 // avatar rotation. This may include a nonzero elevation if 327 // avatar rotation. This may include a nonzero elevation if
327 // in mouselook. 328 // in mouselook.
328 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 329 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
330 fromRegionPos = avatar.AbsolutePosition;
329 q = avatar.Rotation; 331 q = avatar.Rotation;
330 } 332 }
331 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 333 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -448,6 +450,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
448 // avatar rotation. This may include a nonzero elevation if 450 // avatar rotation. This may include a nonzero elevation if
449 // in mouselook. 451 // in mouselook.
450 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 452 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
453 if (avatar == null)
454 return sensedEntities;
455 fromRegionPos = avatar.AbsolutePosition;
451 q = avatar.Rotation; 456 q = avatar.Rotation;
452 } 457 }
453 458
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 0f53bc3..8d97a7c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -124,6 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
124 LSL_Float llGetEnergy(); 124 LSL_Float llGetEnergy();
125 LSL_Vector llGetForce(); 125 LSL_Vector llGetForce();
126 LSL_Integer llGetFreeMemory(); 126 LSL_Integer llGetFreeMemory();
127 LSL_Integer llGetUsedMemory();
127 LSL_Integer llGetFreeURLs(); 128 LSL_Integer llGetFreeURLs();
128 LSL_Vector llGetGeometricCenter(); 129 LSL_Vector llGetGeometricCenter();
129 LSL_Float llGetGMTclock(); 130 LSL_Float llGetGMTclock();
@@ -203,6 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
203 void llGiveInventory(string destination, string inventory); 204 void llGiveInventory(string destination, string inventory);
204 void llGiveInventoryList(string destination, string category, LSL_List inventory); 205 void llGiveInventoryList(string destination, string category, LSL_List inventory);
205 LSL_Integer llGiveMoney(string destination, int amount); 206 LSL_Integer llGiveMoney(string destination, int amount);
207 LSL_String llTransferLindenDollars(string destination, int amount);
206 void llGodLikeRezObject(string inventory, LSL_Vector pos); 208 void llGodLikeRezObject(string inventory, LSL_Vector pos);
207 LSL_Float llGround(LSL_Vector offset); 209 LSL_Float llGround(LSL_Vector offset);
208 LSL_Vector llGroundContour(LSL_Vector offset); 210 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -348,6 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
348 void llSetParcelMusicURL(string url); 350 void llSetParcelMusicURL(string url);
349 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 351 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
350 void llSetPos(LSL_Vector pos); 352 void llSetPos(LSL_Vector pos);
353 LSL_Integer llSetRegionPos(LSL_Vector pos);
351 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 354 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
352 void llSetPrimitiveParams(LSL_List rules); 355 void llSetPrimitiveParams(LSL_List rules);
353 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 356 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -396,6 +399,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
396 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 399 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
397 void llTargetRemove(int number); 400 void llTargetRemove(int number);
398 void llTeleportAgentHome(string agent); 401 void llTeleportAgentHome(string agent);
402 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
399 void llTextBox(string avatar, string message, int chat_channel); 403 void llTextBox(string avatar, string message, int chat_channel);
400 LSL_String llToLower(string source); 404 LSL_String llToLower(string source);
401 LSL_String llToUpper(string source); 405 LSL_String llToUpper(string source);
@@ -412,9 +416,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
412 LSL_Vector llWind(LSL_Vector offset); 416 LSL_Vector llWind(LSL_Vector offset);
413 LSL_String llXorBase64Strings(string str1, string str2); 417 LSL_String llXorBase64Strings(string str1, string str2);
414 LSL_String llXorBase64StringsCorrect(string str1, string str2); 418 LSL_String llXorBase64StringsCorrect(string str1, string str2);
415 void print(string str); 419 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
416 420
417 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 421 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
418 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 422 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
423 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
419 } 424 }
420} 425}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 82a6caf..fb52600 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 5a53e15..a5e160d 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;
@@ -640,5 +641,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
640 public static readonly LSLInteger RCERR_UNKNOWN = -1; 641 public static readonly LSLInteger RCERR_UNKNOWN = -1;
641 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 642 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
642 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 643 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
644
645 public const int KFM_MODE = 1;
646 public const int KFM_LOOP = 1;
647 public const int KFM_REVERSE = 3;
648 public const int KFM_FORWARD = 0;
649 public const int KFM_PING_PONG = 2;
650 public const int KFM_DATA = 2;
651 public const int KFM_TRANSLATION = 2;
652 public const int KFM_ROTATION = 1;
653 public const int KFM_COMMAND = 0;
654 public const int KFM_CMD_PLAY = 0;
655 public const int KFM_CMD_STOP = 1;
656 public const int KFM_CMD_PAUSE = 2;
643 } 657 }
644} 658}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index f8e3c36..a8d1ddb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -464,6 +471,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 471 return m_LSL_Functions.llGetFreeMemory();
465 } 472 }
466 473
474 public LSL_Integer llGetUsedMemory()
475 {
476 return m_LSL_Functions.llGetUsedMemory();
477 }
478
467 public LSL_Integer llGetFreeURLs() 479 public LSL_Integer llGetFreeURLs()
468 { 480 {
469 return m_LSL_Functions.llGetFreeURLs(); 481 return m_LSL_Functions.llGetFreeURLs();
@@ -849,6 +861,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
849 return m_LSL_Functions.llGiveMoney(destination, amount); 861 return m_LSL_Functions.llGiveMoney(destination, amount);
850 } 862 }
851 863
864 public LSL_String llTransferLindenDollars(string destination, int amount)
865 {
866 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
867 }
868
852 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 869 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
853 { 870 {
854 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 871 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1563,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1563 m_LSL_Functions.llSetPos(pos); 1580 m_LSL_Functions.llSetPos(pos);
1564 } 1581 }
1565 1582
1583 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1584 {
1585 return m_LSL_Functions.llSetRegionPos(pos);
1586 }
1587
1566 public void llSetPrimitiveParams(LSL_List rules) 1588 public void llSetPrimitiveParams(LSL_List rules)
1567 { 1589 {
1568 m_LSL_Functions.llSetPrimitiveParams(rules); 1590 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1798,6 +1820,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1798 m_LSL_Functions.llTargetRemove(number); 1820 m_LSL_Functions.llTargetRemove(number);
1799 } 1821 }
1800 1822
1823 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1824 {
1825 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1826 }
1827
1801 public void llTeleportAgentHome(string agent) 1828 public void llTeleportAgentHome(string agent)
1802 { 1829 {
1803 m_LSL_Functions.llTeleportAgentHome(agent); 1830 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1913,9 +1940,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1913 return m_LSL_Functions.llClearLinkMedia(link, face); 1940 return m_LSL_Functions.llClearLinkMedia(link, face);
1914 } 1941 }
1915 1942
1916 public void print(string str) 1943 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1944 {
1945 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1946 }
1947
1948 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1917 { 1949 {
1918 m_LSL_Functions.print(str); 1950 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1919 } 1951 }
1920 } 1952 }
1921} 1953}
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 bc1902b..da2ef7b 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;
@@ -264,13 +265,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
264 265
265 if (part != null) 266 if (part != null)
266 { 267 {
267 lock (part.TaskInventory) 268 part.TaskInventory.LockItemsForRead(true);
269 if (part.TaskInventory.ContainsKey(m_ItemID))
268 { 270 {
269 if (part.TaskInventory.ContainsKey(m_ItemID)) 271 m_thisScriptTask = part.TaskInventory[m_ItemID];
270 {
271 m_thisScriptTask = part.TaskInventory[m_ItemID];
272 }
273 } 272 }
273 part.TaskInventory.LockItemsForRead(false);
274 } 274 }
275 275
276 ApiManager am = new ApiManager(); 276 ApiManager am = new ApiManager();
@@ -469,14 +469,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
469 { 469 {
470 int permsMask; 470 int permsMask;
471 UUID permsGranter; 471 UUID permsGranter;
472 lock (part.TaskInventory) 472 part.TaskInventory.LockItemsForRead(true);
473 if (!part.TaskInventory.ContainsKey(m_ItemID))
473 { 474 {
474 if (!part.TaskInventory.ContainsKey(m_ItemID)) 475 part.TaskInventory.LockItemsForRead(false);
475 return; 476 return;
476
477 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
478 permsMask = part.TaskInventory[m_ItemID].PermsMask;
479 } 477 }
478 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
479 permsMask = part.TaskInventory[m_ItemID].PermsMask;
480 part.TaskInventory.LockItemsForRead(false);
480 481
481 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 482 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
482 { 483 {
@@ -588,6 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
588 return true; 589 return true;
589 } 590 }
590 591
592 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
591 public void SetState(string state) 593 public void SetState(string state)
592 { 594 {
593 if (state == State) 595 if (state == State)
@@ -599,7 +601,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
599 new DetectParams[0])); 601 new DetectParams[0]));
600 PostEvent(new EventParams("state_entry", new Object[0], 602 PostEvent(new EventParams("state_entry", new Object[0],
601 new DetectParams[0])); 603 new DetectParams[0]));
602 604
603 throw new EventAbortException(); 605 throw new EventAbortException();
604 } 606 }
605 607
@@ -682,41 +684,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
682 /// <returns></returns> 684 /// <returns></returns>
683 public object EventProcessor() 685 public object EventProcessor()
684 { 686 {
685 lock (m_Script) 687 EventParams data = null;
686 {
687// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
688 688
689 if (Suspended) 689// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
690 return 0;
691 690
692 EventParams data = null; 691 if (Suspended)
692 return 0;
693 693
694 lock (m_EventQueue) 694 lock (m_EventQueue)
695 {
696 data = (EventParams) m_EventQueue.Dequeue();
697 if (data == null) // Shouldn't happen
695 { 698 {
696 data = (EventParams) m_EventQueue.Dequeue(); 699 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
697 if (data == null) // Shouldn't happen
698 { 700 {
699 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 701 m_CurrentResult = m_Engine.QueueEventHandler(this);
700 {
701 m_CurrentResult = m_Engine.QueueEventHandler(this);
702 }
703 else
704 {
705 m_CurrentResult = null;
706 }
707 return 0;
708 } 702 }
709 703 else
710 if (data.EventName == "timer")
711 m_TimerQueued = false;
712 if (data.EventName == "control")
713 { 704 {
714 if (m_ControlEventsInQueue > 0) 705 m_CurrentResult = null;
715 m_ControlEventsInQueue--;
716 } 706 }
717 if (data.EventName == "collision") 707 return 0;
718 m_CollisionInQueue = false; 708 }
709
710 if (data.EventName == "timer")
711 m_TimerQueued = false;
712 if (data.EventName == "control")
713 {
714 if (m_ControlEventsInQueue > 0)
715 m_ControlEventsInQueue--;
719 } 716 }
717 if (data.EventName == "collision")
718 m_CollisionInQueue = false;
719 }
720
721 lock(m_Script)
722 {
720 723
721// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 724// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
722 725
@@ -876,6 +879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
876 new Object[0], new DetectParams[0])); 879 new Object[0], new DetectParams[0]));
877 } 880 }
878 881
882 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
879 public void ApiResetScript() 883 public void ApiResetScript()
880 { 884 {
881 // bool running = Running; 885 // bool running = Running;
@@ -907,10 +911,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
907 911
908 public Dictionary<string, object> GetVars() 912 public Dictionary<string, object> GetVars()
909 { 913 {
910 if (m_Script != null) 914 return m_Script.GetVars();
911 return m_Script.GetVars();
912 else
913 return new Dictionary<string, object>();
914 } 915 }
915 916
916 public void SetVars(Dictionary<string, object> vars) 917 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index b433430..db6a407 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -112,6 +113,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
112 private Dictionary<UUID, IScriptInstance> m_Scripts = 113 private Dictionary<UUID, IScriptInstance> m_Scripts =
113 new Dictionary<UUID, IScriptInstance>(); 114 new Dictionary<UUID, IScriptInstance>();
114 115
116 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
117
115 // Maps the asset ID to the assembly 118 // Maps the asset ID to the assembly
116 119
117 private Dictionary<UUID, string> m_Assemblies = 120 private Dictionary<UUID, string> m_Assemblies =
@@ -134,6 +137,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
134 IWorkItemResult m_CurrentCompile = null; 137 IWorkItemResult m_CurrentCompile = null;
135 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 138 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
136 139
140 private void lockScriptsForRead(bool locked)
141 {
142 if (locked)
143 {
144 if (m_scriptsLock.RecursiveReadCount > 0)
145 {
146 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
147 m_scriptsLock.ExitReadLock();
148 }
149 if (m_scriptsLock.RecursiveWriteCount > 0)
150 {
151 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
152 m_scriptsLock.ExitWriteLock();
153 }
154
155 while (!m_scriptsLock.TryEnterReadLock(60000))
156 {
157 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
158 if (m_scriptsLock.IsWriteLockHeld)
159 {
160 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
161 }
162 }
163 }
164 else
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_scriptsLock.ExitReadLock();
169 }
170 }
171 }
172 private void lockScriptsForWrite(bool locked)
173 {
174 if (locked)
175 {
176 if (m_scriptsLock.RecursiveReadCount > 0)
177 {
178 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
179 m_scriptsLock.ExitReadLock();
180 }
181 if (m_scriptsLock.RecursiveWriteCount > 0)
182 {
183 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
184 m_scriptsLock.ExitWriteLock();
185 }
186
187 while (!m_scriptsLock.TryEnterWriteLock(60000))
188 {
189 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
190 if (m_scriptsLock.IsWriteLockHeld)
191 {
192 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
193 }
194 }
195 }
196 else
197 {
198 if (m_scriptsLock.RecursiveWriteCount > 0)
199 {
200 m_scriptsLock.ExitWriteLock();
201 }
202 }
203 }
204
137 public string ScriptEngineName 205 public string ScriptEngineName
138 { 206 {
139 get { return "XEngine"; } 207 get { return "XEngine"; }
@@ -516,44 +584,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
516 { 584 {
517 if (!m_Enabled) 585 if (!m_Enabled)
518 return; 586 return;
519 587 lockScriptsForRead(true);
520 lock (m_Scripts) 588 foreach (IScriptInstance instance in m_Scripts.Values)
521 { 589 {
522 m_log.InfoFormat( 590 // Force a final state save
523 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 591 //
524 592 if (m_Assemblies.ContainsKey(instance.AssetID))
525 foreach (IScriptInstance instance in m_Scripts.Values)
526 { 593 {
527 // Force a final state save 594 string assembly = m_Assemblies[instance.AssetID];
528 // 595 instance.SaveState(assembly);
529 if (m_Assemblies.ContainsKey(instance.AssetID)) 596 }
530 {
531 string assembly = m_Assemblies[instance.AssetID];
532 instance.SaveState(assembly);
533 }
534 597
535 // Clear the event queue and abort the instance thread 598 // Clear the event queue and abort the instance thread
536 // 599 //
537 instance.ClearQueue(); 600 instance.ClearQueue();
538 instance.Stop(0); 601 instance.Stop(0);
539 602
540 // Release events, timer, etc 603 // Release events, timer, etc
541 // 604 //
542 instance.DestroyScriptInstance(); 605 instance.DestroyScriptInstance();
543 606
544 // Unload scripts and app domains. 607 // Unload scripts and app domains
545 // Must be done explicitly because they have infinite 608 // Must be done explicitly because they have infinite
546 // lifetime. 609 // lifetime
547 // However, don't bother to do this if the simulator is shutting 610 //
548 // down since it takes a long time with many scripts. 611 if (!m_SimulatorShuttingDown)
549 if (!m_SimulatorShuttingDown) 612 {
613 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
614 if (m_DomainScripts[instance.AppDomain].Count == 0)
550 { 615 {
551 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 616 m_DomainScripts.Remove(instance.AppDomain);
552 if (m_DomainScripts[instance.AppDomain].Count == 0) 617 UnloadAppDomain(instance.AppDomain);
553 {
554 m_DomainScripts.Remove(instance.AppDomain);
555 UnloadAppDomain(instance.AppDomain);
556 }
557 } 618 }
558 } 619 }
559 620
@@ -562,6 +623,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
562 m_Assemblies.Clear(); 623 m_Assemblies.Clear();
563 m_DomainScripts.Clear(); 624 m_DomainScripts.Clear();
564 } 625 }
626 lockScriptsForRead(false);
627 lockScriptsForWrite(true);
628 m_Scripts.Clear();
629 lockScriptsForWrite(false);
630 m_PrimObjects.Clear();
631 m_Assemblies.Clear();
632 m_DomainScripts.Clear();
633
565 lock (m_ScriptEngines) 634 lock (m_ScriptEngines)
566 { 635 {
567 m_ScriptEngines.Remove(this); 636 m_ScriptEngines.Remove(this);
@@ -626,22 +695,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
626 695
627 List<IScriptInstance> instances = new List<IScriptInstance>(); 696 List<IScriptInstance> instances = new List<IScriptInstance>();
628 697
629 lock (m_Scripts) 698 lockScriptsForRead(true);
630 { 699 foreach (IScriptInstance instance in m_Scripts.Values)
631 foreach (IScriptInstance instance in m_Scripts.Values)
632 instances.Add(instance); 700 instances.Add(instance);
633 } 701 lockScriptsForRead(false);
634 702
635 foreach (IScriptInstance i in instances) 703 foreach (IScriptInstance i in instances)
636 { 704 {
637 string assembly = String.Empty; 705 string assembly = String.Empty;
638 706
639 lock (m_Scripts) 707
640 {
641 if (!m_Assemblies.ContainsKey(i.AssetID)) 708 if (!m_Assemblies.ContainsKey(i.AssetID))
642 continue; 709 continue;
643 assembly = m_Assemblies[i.AssetID]; 710 assembly = m_Assemblies[i.AssetID];
644 } 711
645 712
646 i.SaveState(assembly); 713 i.SaveState(assembly);
647 } 714 }
@@ -985,92 +1052,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
985 } 1052 }
986 1053
987 ScriptInstance instance = null; 1054 ScriptInstance instance = null;
988 lock (m_Scripts) 1055 // Create the object record
1056 lockScriptsForRead(true);
1057 if ((!m_Scripts.ContainsKey(itemID)) ||
1058 (m_Scripts[itemID].AssetID != assetID))
989 { 1059 {
990 // Create the object record 1060 lockScriptsForRead(false);
991 1061
992 if ((!m_Scripts.ContainsKey(itemID)) || 1062 UUID appDomain = assetID;
993 (m_Scripts[itemID].AssetID != assetID))
994 {
995 UUID appDomain = assetID;
996 1063
997 if (part.ParentGroup.IsAttachment) 1064 if (part.ParentGroup.IsAttachment)
998 appDomain = part.ParentGroup.RootPart.UUID; 1065 appDomain = part.ParentGroup.RootPart.UUID;
999 1066
1000 if (!m_AppDomains.ContainsKey(appDomain)) 1067 if (!m_AppDomains.ContainsKey(appDomain))
1068 {
1069 try
1001 { 1070 {
1002 try 1071 AppDomainSetup appSetup = new AppDomainSetup();
1003 { 1072 appSetup.PrivateBinPath = Path.Combine(
1004 AppDomainSetup appSetup = new AppDomainSetup(); 1073 m_ScriptEnginesPath,
1005 appSetup.PrivateBinPath = Path.Combine( 1074 m_Scene.RegionInfo.RegionID.ToString());
1006 m_ScriptEnginesPath, 1075
1007 m_Scene.RegionInfo.RegionID.ToString()); 1076 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1008 1077 Evidence evidence = new Evidence(baseEvidence);
1009 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1078
1010 Evidence evidence = new Evidence(baseEvidence); 1079 AppDomain sandbox;
1011 1080 if (m_AppDomainLoading)
1012 AppDomain sandbox; 1081 sandbox = AppDomain.CreateDomain(
1013 if (m_AppDomainLoading) 1082 m_Scene.RegionInfo.RegionID.ToString(),
1014 sandbox = AppDomain.CreateDomain( 1083 evidence, appSetup);
1015 m_Scene.RegionInfo.RegionID.ToString(), 1084 else
1016 evidence, appSetup); 1085 sandbox = AppDomain.CurrentDomain;
1017 else 1086
1018 sandbox = AppDomain.CurrentDomain; 1087 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1019 1088 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1020 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1089 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1021 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1090 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1022 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 1091 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1023 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 1092 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1024 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 1093 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1025 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 1094
1026 //sandbox.SetAppDomainPolicy(sandboxPolicy); 1095 m_AppDomains[appDomain] = sandbox;
1027 1096
1028 m_AppDomains[appDomain] = sandbox; 1097 m_AppDomains[appDomain].AssemblyResolve +=
1029 1098 new ResolveEventHandler(
1030 m_AppDomains[appDomain].AssemblyResolve += 1099 AssemblyResolver.OnAssemblyResolve);
1031 new ResolveEventHandler( 1100 m_DomainScripts[appDomain] = new List<UUID>();
1032 AssemblyResolver.OnAssemblyResolve); 1101 }
1033 m_DomainScripts[appDomain] = new List<UUID>(); 1102 catch (Exception e)
1034 } 1103 {
1035 catch (Exception e) 1104 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1105 m_ScriptErrorMessage += "Exception creating app domain:\n";
1106 m_ScriptFailCount++;
1107 lock (m_AddingAssemblies)
1036 { 1108 {
1037 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1109 m_AddingAssemblies[assembly]--;
1038 m_ScriptErrorMessage += "Exception creating app domain:\n";
1039 m_ScriptFailCount++;
1040 lock (m_AddingAssemblies)
1041 {
1042 m_AddingAssemblies[assembly]--;
1043 }
1044 return false;
1045 } 1110 }
1111 return false;
1046 } 1112 }
1047 m_DomainScripts[appDomain].Add(itemID); 1113 }
1048 1114 m_DomainScripts[appDomain].Add(itemID);
1049 instance = new ScriptInstance(this, part, 1115
1050 itemID, assetID, assembly, 1116 instance = new ScriptInstance(this, part,
1051 m_AppDomains[appDomain], 1117 itemID, assetID, assembly,
1052 part.ParentGroup.RootPart.Name, 1118 m_AppDomains[appDomain],
1053 item.Name, startParam, postOnRez, 1119 part.ParentGroup.RootPart.Name,
1054 stateSource, m_MaxScriptQueue); 1120 item.Name, startParam, postOnRez,
1055 1121 stateSource, m_MaxScriptQueue);
1056 m_log.DebugFormat( 1122
1057 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1123 m_log.DebugFormat(
1058 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1124 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1125 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1059 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1126 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1060 1127
1061 if (presence != null) 1128 if (presence != null)
1062 { 1129 {
1063 ShowScriptSaveResponse(item.OwnerID, 1130 ShowScriptSaveResponse(item.OwnerID,
1064 assetID, "Compile successful", true); 1131 assetID, "Compile successful", true);
1065 }
1066
1067 instance.AppDomain = appDomain;
1068 instance.LineMap = linemap;
1069
1070 m_Scripts[itemID] = instance;
1071 } 1132 }
1072 }
1073 1133
1134 instance.AppDomain = appDomain;
1135 instance.LineMap = linemap;
1136 lockScriptsForWrite(true);
1137 m_Scripts[itemID] = instance;
1138 lockScriptsForWrite(false);
1139 }
1140 else
1141 {
1142 lockScriptsForRead(false);
1143 }
1074 lock (m_PrimObjects) 1144 lock (m_PrimObjects)
1075 { 1145 {
1076 if (!m_PrimObjects.ContainsKey(localID)) 1146 if (!m_PrimObjects.ContainsKey(localID))
@@ -1089,9 +1159,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1089 m_AddingAssemblies[assembly]--; 1159 m_AddingAssemblies[assembly]--;
1090 } 1160 }
1091 1161
1092 if (instance != null) 1162 if (instance!=null)
1093 instance.Init(); 1163 instance.Init();
1094 1164
1095 return true; 1165 return true;
1096 } 1166 }
1097 1167
@@ -1104,20 +1174,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1104 m_CompileDict.Remove(itemID); 1174 m_CompileDict.Remove(itemID);
1105 } 1175 }
1106 1176
1107 IScriptInstance instance = null; 1177 lockScriptsForRead(true);
1108 1178 // Do we even have it?
1109 lock (m_Scripts) 1179 if (!m_Scripts.ContainsKey(itemID))
1110 { 1180 {
1111 // Do we even have it? 1181 // Do we even have it?
1112 if (!m_Scripts.ContainsKey(itemID)) 1182 if (!m_Scripts.ContainsKey(itemID))
1113 return; 1183 return;
1114 1184
1115 instance = m_Scripts[itemID]; 1185 lockScriptsForRead(false);
1186 lockScriptsForWrite(true);
1116 m_Scripts.Remove(itemID); 1187 m_Scripts.Remove(itemID);
1188 lockScriptsForWrite(false);
1189
1190 return;
1117 } 1191 }
1192
1118 1193
1194 IScriptInstance instance=m_Scripts[itemID];
1195 lockScriptsForRead(false);
1196 lockScriptsForWrite(true);
1197 m_Scripts.Remove(itemID);
1198 lockScriptsForWrite(false);
1119 instance.ClearQueue(); 1199 instance.ClearQueue();
1120 instance.Stop(0); 1200 instance.Stop(0);
1201
1121// bool objectRemoved = false; 1202// bool objectRemoved = false;
1122 1203
1123 lock (m_PrimObjects) 1204 lock (m_PrimObjects)
@@ -1153,10 +1234,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1153 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1234 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1154 if (handlerObjectRemoved != null) 1235 if (handlerObjectRemoved != null)
1155 { 1236 {
1156 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1237 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1157 handlerObjectRemoved(part.UUID); 1238 handlerObjectRemoved(part.UUID);
1158 } 1239 }
1159 1240
1241 CleanAssemblies();
1242
1160 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1243 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1161 if (handlerScriptRemoved != null) 1244 if (handlerScriptRemoved != null)
1162 handlerScriptRemoved(itemID); 1245 handlerScriptRemoved(itemID);
@@ -1298,7 +1381,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1298 return false; 1381 return false;
1299 1382
1300 uuids = m_PrimObjects[localID]; 1383 uuids = m_PrimObjects[localID];
1301 } 1384
1302 1385
1303 foreach (UUID itemID in uuids) 1386 foreach (UUID itemID in uuids)
1304 { 1387 {
@@ -1316,6 +1399,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1316 result = true; 1399 result = true;
1317 } 1400 }
1318 } 1401 }
1402 }
1319 1403
1320 return result; 1404 return result;
1321 } 1405 }
@@ -1417,12 +1501,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1417 private IScriptInstance GetInstance(UUID itemID) 1501 private IScriptInstance GetInstance(UUID itemID)
1418 { 1502 {
1419 IScriptInstance instance; 1503 IScriptInstance instance;
1420 lock (m_Scripts) 1504 lockScriptsForRead(true);
1505 if (!m_Scripts.ContainsKey(itemID))
1421 { 1506 {
1422 if (!m_Scripts.ContainsKey(itemID)) 1507 lockScriptsForRead(false);
1423 return null; 1508 return null;
1424 instance = m_Scripts[itemID];
1425 } 1509 }
1510 instance = m_Scripts[itemID];
1511 lockScriptsForRead(false);
1426 return instance; 1512 return instance;
1427 } 1513 }
1428 1514
@@ -1446,6 +1532,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1446 return false; 1532 return false;
1447 } 1533 }
1448 1534
1535 [DebuggerNonUserCode]
1449 public void ApiResetScript(UUID itemID) 1536 public void ApiResetScript(UUID itemID)
1450 { 1537 {
1451 IScriptInstance instance = GetInstance(itemID); 1538 IScriptInstance instance = GetInstance(itemID);
@@ -1497,6 +1584,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1497 return UUID.Zero; 1584 return UUID.Zero;
1498 } 1585 }
1499 1586
1587 [DebuggerNonUserCode]
1500 public void SetState(UUID itemID, string newState) 1588 public void SetState(UUID itemID, string newState)
1501 { 1589 {
1502 IScriptInstance instance = GetInstance(itemID); 1590 IScriptInstance instance = GetInstance(itemID);
@@ -1519,11 +1607,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1519 1607
1520 List<IScriptInstance> instances = new List<IScriptInstance>(); 1608 List<IScriptInstance> instances = new List<IScriptInstance>();
1521 1609
1522 lock (m_Scripts) 1610 lockScriptsForRead(true);
1523 { 1611 foreach (IScriptInstance instance in m_Scripts.Values)
1524 foreach (IScriptInstance instance in m_Scripts.Values)
1525 instances.Add(instance); 1612 instances.Add(instance);
1526 } 1613 lockScriptsForRead(false);
1527 1614
1528 foreach (IScriptInstance i in instances) 1615 foreach (IScriptInstance i in instances)
1529 { 1616 {
@@ -1908,5 +1995,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1908// else 1995// else
1909// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 1996// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
1910 } 1997 }
1998
1999 public bool HasScript(UUID itemID, out bool running)
2000 {
2001 running = true;
2002
2003 IScriptInstance instance = GetInstance(itemID);
2004 if (instance == null)
2005 return false;
2006
2007 running = instance.Running;
2008 return true;
2009 }
1911 } 2010 }
1912} \ No newline at end of file 2011}