aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.cs2256
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs8
-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.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs11
-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.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
19 files changed, 2120 insertions, 973 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ce7d97c..3f48080 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{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -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);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -288,40 +357,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 357 protected UUID InventorySelf()
289 { 358 {
290 UUID invItemID = new UUID(); 359 UUID invItemID = new UUID();
291 360 bool unlock = false;
292 lock (m_host.TaskInventory) 361 if (!m_host.TaskInventory.IsReadLockedByMe())
293 { 362 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 363 m_host.TaskInventory.LockItemsForRead(true);
364 unlock = true;
365 }
366 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
367 {
368 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 369 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 370 invItemID = inv.Key;
297 { 371 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 372 }
302 } 373 }
303 374 if (unlock)
375 {
376 m_host.TaskInventory.LockItemsForRead(false);
377 }
304 return invItemID; 378 return invItemID;
305 } 379 }
306 380
307 protected UUID InventoryKey(string name, int type) 381 protected UUID InventoryKey(string name, int type)
308 { 382 {
309 m_host.AddScriptLPS(1); 383 m_host.AddScriptLPS(1);
310 384 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 385
386 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 387 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 388 if (inv.Value.Name == name)
314 { 389 {
315 if (inv.Value.Name == name) 390 m_host.TaskInventory.LockItemsForRead(false);
391
392 if (inv.Value.Type != type)
316 { 393 {
317 if (inv.Value.Type != type) 394 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 395 }
396
397 return inv.Value.AssetID;
322 } 398 }
323 } 399 }
324 400
401 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 402 return UUID.Zero;
326 } 403 }
327 404
@@ -329,17 +406,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 406 {
330 m_host.AddScriptLPS(1); 407 m_host.AddScriptLPS(1);
331 408
332 lock (m_host.TaskInventory) 409
410 m_host.TaskInventory.LockItemsForRead(true);
411
412 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 413 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 414 if (inv.Value.Name == name)
335 { 415 {
336 if (inv.Value.Name == name) 416 m_host.TaskInventory.LockItemsForRead(false);
337 { 417 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 418 }
341 } 419 }
342 420
421 m_host.TaskInventory.LockItemsForRead(false);
422
423
343 return UUID.Zero; 424 return UUID.Zero;
344 } 425 }
345 426
@@ -481,26 +562,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 562
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 563 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 564
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 565 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 566
567 // normalize an angle between -PI and PI (-180 to +180 degrees)
568 protected double NormalizeAngle(double angle)
569 {
570 if (angle > -Math.PI && angle < Math.PI)
571 return angle;
572
573 int numPis = (int)(Math.PI / angle);
574 double remainder = angle - Math.PI * numPis;
575 if (numPis % 2 == 1)
576 return Math.PI - angle;
577 return remainder;
578 }
486 579
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 580 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 581 {
489 m_host.AddScriptLPS(1); 582 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 583 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 584
492 double m = (t.x + t.y + t.z + t.s); 585 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 586 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 587 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 588 double sqz = q1.y*q1.y;
496 if (p > 0) 589 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 590 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 591 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 592 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 593 eul.y = Math.PI/2;
501 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 594 eul.x = 0;
502 else 595 return eul;
503 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 596 }
597 if (test < -0.4999*unit) { // singularity at south pole
598 eul.z = -2 * Math.Atan2(q1.x,q1.s);
599 eul.y = -Math.PI/2;
600 eul.x = 0;
601 return eul;
602 }
603 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
604 eul.y = Math.Asin(2*test/unit);
605 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
606 return eul;
504 } 607 }
505 608
506 /* From wiki: 609 /* From wiki:
@@ -702,77 +805,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 805 {
703 //A and B should both be normalized 806 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 807 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 808 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 809 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 810
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 811 double dotProduct = LSL_Vector.Dot(a, b);
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
813 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
814 double angle = Math.Acos(dotProduct / magProduct);
815 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
816 double s = Math.Sin(angle / 2);
817
818 double x = axis.x * s;
819 double y = axis.y * s;
820 double z = axis.z * s;
821 double w = Math.Cos(angle / 2);
822
823 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
824 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
825
826 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
827 */
828
829 // This method mimics the 180 errors found in SL
830 // See www.euclideanspace.com... angleBetween
831 LSL_Vector vec_a = a;
832 LSL_Vector vec_b = b;
833
834 // Eliminate zero length
835 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
836 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
837 if (vec_a_mag < 0.00001 ||
838 vec_b_mag < 0.00001)
709 { 839 {
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 840 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 } 841 }
712 else 842
843 // Normalize
844 vec_a = llVecNorm(vec_a);
845 vec_b = llVecNorm(vec_b);
846
847 // Calculate axis and rotation angle
848 LSL_Vector axis = vec_a % vec_b;
849 LSL_Float cos_theta = vec_a * vec_b;
850
851 // Check if parallel
852 if (cos_theta > 0.99999)
713 { 853 {
714 a = LSL_Vector.Norm(a); 854 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 b = LSL_Vector.Norm(b); 855 }
716 double dotProduct = LSL_Vector.Dot(a, b); 856
717 // There are two degenerate cases possible. These are for vectors 180 or 857 // Check if anti-parallel
718 // 0 degrees apart. These have to be detected and handled individually. 858 else if (cos_theta < -0.99999)
719 // 859 {
720 // Check for vectors 180 degrees apart. 860 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 861 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
722 if (dotProduct < -0.9999999f) 862 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
723 { 863 }
724 // First assume X axis is orthogonal to the vectors. 864 else // other rotation
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 865 {
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 866 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
727 // Check for near zero vector. A very small non-zero number here will create 867 axis = llVecNorm(axis);
728 // a rotation in an undesired direction. 868 double x, y, z, s, t;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 869 s = Math.Cos(theta);
730 { 870 t = Math.Sin(theta);
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 871 x = axis.x * t;
732 } 872 y = axis.y * t;
733 // If the magnitude of the vector was near zero, then assume the X axis is not 873 z = axis.z * t;
734 // orthogonal and use the Z axis instead. 874 return new LSL_Rotation(x,y,z,s);
735 else
736 {
737 // Set 180 z rotation.
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
739 }
740 }
741 // Check for parallel vectors.
742 // A dot product of 1 would mean the angle between vectors is 0 degrees.
743 else if (dotProduct > 0.9999999f)
744 {
745 // Set zero rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
747 }
748 else
749 {
750 // All special checks have been performed so get the axis of rotation.
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
752 // Quarternion s value is the length of the unit vector + dot product.
753 double qs = 1.0 + dotProduct;
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
755 // Normalize the rotation.
756 double mag = LSL_Rotation.Mag(rotBetween);
757 // We shouldn't have to worry about a divide by zero here. The qs value will be
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the
760 // crossProduct vector should also not be zero.
761 rotBetween.x = rotBetween.x / mag;
762 rotBetween.y = rotBetween.y / mag;
763 rotBetween.z = rotBetween.z / mag;
764 rotBetween.s = rotBetween.s / mag;
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required
766 // any longer since zero vectors are checked for at the top.
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
768 {
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
770 }
771 }
772 } 875 }
773 return rotBetween;
774 } 876 }
775 877
776 public void llWhisper(int channelID, string text) 878 public void llWhisper(int channelID, string text)
777 { 879 {
778 m_host.AddScriptLPS(1); 880 m_host.AddScriptLPS(1);
@@ -792,6 +894,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
792 { 894 {
793 m_host.AddScriptLPS(1); 895 m_host.AddScriptLPS(1);
794 896
897 if (channelID == 0)
898 m_SayShoutCount++;
899
900 if (m_SayShoutCount >= 11)
901 ScriptSleep(2000);
902
795 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 903 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
796 { 904 {
797 Console.WriteLine(text); 905 Console.WriteLine(text);
@@ -814,6 +922,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
814 { 922 {
815 m_host.AddScriptLPS(1); 923 m_host.AddScriptLPS(1);
816 924
925 if (channelID == 0)
926 m_SayShoutCount++;
927
928 if (m_SayShoutCount >= 11)
929 ScriptSleep(2000);
930
817 if (text.Length > 1023) 931 if (text.Length > 1023)
818 text = text.Substring(0, 1023); 932 text = text.Substring(0, 1023);
819 933
@@ -1096,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1097 } 1211 }
1098 1212
1213 [DebuggerNonUserCode]
1099 public virtual void llDie() 1214 public virtual void llDie()
1100 { 1215 {
1101 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1217 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1218 }
1104 1219
1105 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1287
1173 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1174 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1175 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1176 1293
1177 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -1402,6 +1519,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1519 {
1403 m_host.AddScriptLPS(1); 1520 m_host.AddScriptLPS(1);
1404 1521
1522 SetColor(m_host, color, face);
1523 }
1524
1525 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1526 {
1527 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1528 return;
1529
1530 Primitive.TextureEntry tex = part.Shape.Textures;
1531 Color4 texcolor;
1532 if (face >= 0 && face < GetNumberOfSides(part))
1533 {
1534 texcolor = tex.CreateFace((uint)face).RGBA;
1535 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1536 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1537 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1538 tex.FaceTextures[face].RGBA = texcolor;
1539 part.UpdateTexture(tex);
1540 return;
1541 }
1542 else if (face == ScriptBaseClass.ALL_SIDES)
1543 {
1544 for (uint i = 0; i < GetNumberOfSides(part); i++)
1545 {
1546 if (tex.FaceTextures[i] != null)
1547 {
1548 texcolor = tex.FaceTextures[i].RGBA;
1549 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1550 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1551 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1552 tex.FaceTextures[i].RGBA = texcolor;
1553 }
1554 texcolor = tex.DefaultTexture.RGBA;
1555 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1556 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1557 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1558 tex.DefaultTexture.RGBA = texcolor;
1559 }
1560 part.UpdateTexture(tex);
1561 return;
1562 }
1563
1405 if (face == ScriptBaseClass.ALL_SIDES) 1564 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1565 face = SceneObjectPart.ALL_SIDES;
1407 1566
@@ -1410,6 +1569,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1569
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1570 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1571 {
1572 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1573 return;
1574
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1575 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1576 MappingType textype;
1415 textype = MappingType.Default; 1577 textype = MappingType.Default;
@@ -1440,6 +1602,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1602
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1603 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1604 {
1605 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1606 return;
1607
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1608 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1609 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1610 {
@@ -1465,6 +1630,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1630
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1631 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1632 {
1633 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1634 return;
1468 1635
1469 Shininess sval = new Shininess(); 1636 Shininess sval = new Shininess();
1470 1637
@@ -1515,6 +1682,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1682
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1683 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1684 {
1685 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1686 return;
1687
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1688 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1689 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1690 {
@@ -1575,13 +1745,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1745 m_host.AddScriptLPS(1);
1576 1746
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1747 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1748 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1749 {
1580 SetAlpha(part, alpha, face); 1750 try
1751 {
1752 parts[0].ParentGroup.areUpdatesSuspended = true;
1753 foreach (SceneObjectPart part in parts)
1754 SetAlpha(part, alpha, face);
1755 }
1756 finally
1757 {
1758 parts[0].ParentGroup.areUpdatesSuspended = false;
1759 }
1760 }
1581 } 1761 }
1582 1762
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1763 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1764 {
1765 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1766 return;
1767
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1768 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1769 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1770 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1810 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1811 float wind, float tension, LSL_Vector Force)
1629 { 1812 {
1630 if (part == null) 1813 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1814 return;
1632 1815
1633 if (flexi) 1816 if (flexi)
@@ -1662,7 +1845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1845 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1846 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1847 {
1665 if (part == null) 1848 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1849 return;
1667 1850
1668 if (light) 1851 if (light)
@@ -1739,15 +1922,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1922 m_host.AddScriptLPS(1);
1740 1923
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1924 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1925 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1926 {
1744 SetTexture(part, texture, face); 1927 try
1745 1928 {
1929 parts[0].ParentGroup.areUpdatesSuspended = true;
1930 foreach (SceneObjectPart part in parts)
1931 SetTexture(part, texture, face);
1932 }
1933 finally
1934 {
1935 parts[0].ParentGroup.areUpdatesSuspended = false;
1936 }
1937 }
1746 ScriptSleep(200); 1938 ScriptSleep(200);
1747 } 1939 }
1748 1940
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1941 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1942 {
1943 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1944 return;
1945
1751 UUID textureID = new UUID(); 1946 UUID textureID = new UUID();
1752 1947
1753 textureID = InventoryKey(texture, (int)AssetType.Texture); 1948 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1792,6 +1987,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1987
1793 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1988 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1794 { 1989 {
1990 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1991 return;
1992
1795 Primitive.TextureEntry tex = part.Shape.Textures; 1993 Primitive.TextureEntry tex = part.Shape.Textures;
1796 if (face >= 0 && face < GetNumberOfSides(part)) 1994 if (face >= 0 && face < GetNumberOfSides(part))
1797 { 1995 {
@@ -1828,6 +2026,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 2026
1829 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2027 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1830 { 2028 {
2029 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2030 return;
2031
1831 Primitive.TextureEntry tex = part.Shape.Textures; 2032 Primitive.TextureEntry tex = part.Shape.Textures;
1832 if (face >= 0 && face < GetNumberOfSides(part)) 2033 if (face >= 0 && face < GetNumberOfSides(part))
1833 { 2034 {
@@ -1864,6 +2065,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1864 2065
1865 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2066 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1866 { 2067 {
2068 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2069 return;
2070
1867 Primitive.TextureEntry tex = part.Shape.Textures; 2071 Primitive.TextureEntry tex = part.Shape.Textures;
1868 if (face >= 0 && face < GetNumberOfSides(part)) 2072 if (face >= 0 && face < GetNumberOfSides(part))
1869 { 2073 {
@@ -1932,10 +2136,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 return end; 2136 return end;
1933 } 2137 }
1934 2138
1935 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2139 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1936 { 2140 {
2141 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2142 return fromPos;
2143
1937 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2144 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1938 LSL_Vector currentPos = GetPartLocalPos(part); 2145
1939 2146
1940 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2147 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1941 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2148 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1944,14 +2151,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 { 2151 {
1945 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2152 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
1946 targetPos.z = ground; 2153 targetPos.z = ground;
2154 }
2155 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2156
2157 return real_vec;
2158 }
2159
2160 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2161 {
2162 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2163 return;
2164
2165 LSL_Vector currentPos = GetPartLocalPos(part);
2166 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2167
2168 if (part.ParentGroup.RootPart == part)
2169 {
1947 SceneObjectGroup parent = part.ParentGroup; 2170 SceneObjectGroup parent = part.ParentGroup;
1948 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2171 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1949 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1950 } 2172 }
1951 else 2173 else
1952 { 2174 {
1953 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2175 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1954 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1955 SceneObjectGroup parent = part.ParentGroup; 2176 SceneObjectGroup parent = part.ParentGroup;
1956 parent.HasGroupChanged = true; 2177 parent.HasGroupChanged = true;
1957 parent.ScheduleGroupForTerseUpdate(); 2178 parent.ScheduleGroupForTerseUpdate();
@@ -2002,9 +2223,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 m_host.AddScriptLPS(1); 2223 m_host.AddScriptLPS(1);
2003 2224
2004 // try to let this work as in SL... 2225 // try to let this work as in SL...
2005 if (m_host.ParentID == 0) 2226 if (m_host.LinkNum < 2)
2006 { 2227 {
2007 // special case: If we are root, rotate complete SOG to new rotation 2228 // Special case: If we are root, rotate complete SOG to new
2229 // rotation.
2230 // We are root if the link number is 0 (single prim) or 1
2231 // (root prim). ParentID may be nonzero in attachments and
2232 // using it would cause attachments and HUDs to rotate
2233 // to the wrong positions.
2008 SetRot(m_host, Rot2Quaternion(rot)); 2234 SetRot(m_host, Rot2Quaternion(rot));
2009 } 2235 }
2010 else 2236 else
@@ -2033,6 +2259,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2033 2259
2034 protected void SetRot(SceneObjectPart part, Quaternion rot) 2260 protected void SetRot(SceneObjectPart part, Quaternion rot)
2035 { 2261 {
2262 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2263 return;
2264
2036 part.UpdateRotation(rot); 2265 part.UpdateRotation(rot);
2037 // Update rotation does not move the object in the physics scene if it's a linkset. 2266 // Update rotation does not move the object in the physics scene if it's a linkset.
2038 2267
@@ -2652,12 +2881,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 2881
2653 m_host.AddScriptLPS(1); 2882 m_host.AddScriptLPS(1);
2654 2883
2884 m_host.TaskInventory.LockItemsForRead(true);
2655 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2885 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2656 2886 m_host.TaskInventory.LockItemsForRead(false);
2657 lock (m_host.TaskInventory)
2658 {
2659 item = m_host.TaskInventory[invItemID];
2660 }
2661 2887
2662 if (item.PermsGranter == UUID.Zero) 2888 if (item.PermsGranter == UUID.Zero)
2663 return 0; 2889 return 0;
@@ -2732,6 +2958,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 if (dist > m_ScriptDistanceFactor * 10.0f) 2958 if (dist > m_ScriptDistanceFactor * 10.0f)
2733 return; 2959 return;
2734 2960
2961 //Clone is thread-safe
2735 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2962 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2736 2963
2737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2964 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2794,6 +3021,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 3021
2795 public void llLookAt(LSL_Vector target, double strength, double damping) 3022 public void llLookAt(LSL_Vector target, double strength, double damping)
2796 { 3023 {
3024 /*
2797 m_host.AddScriptLPS(1); 3025 m_host.AddScriptLPS(1);
2798 // Determine where we are looking from 3026 // Determine where we are looking from
2799 LSL_Vector from = llGetPos(); 3027 LSL_Vector from = llGetPos();
@@ -2813,10 +3041,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 // the angles of rotation in radians into rotation value 3041 // the angles of rotation in radians into rotation value
2814 3042
2815 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3043 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2816 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3044
2817 m_host.startLookAt(rotation, (float)damping, (float)strength); 3045 // This would only work if your physics system contains an APID controller:
3046 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3047 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3048
2818 // Orient the object to the angle calculated 3049 // Orient the object to the angle calculated
2819 //llSetRot(rot); 3050 llSetRot(rot);
3051 */
3052
3053 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3054 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3055 // http://bugs.meta7.com/view.php?id=28
3056 // - Tom
3057
3058 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3059 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3060 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3061 */
3062 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3063 {
3064 // Part is non-phys, convert this to a llSetRot()
3065 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3066 Vector3 dir = tgt - m_host.GroupPosition;
3067 dir.Normalize();
3068 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3069 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3070 float terot = (float)Math.Atan2(-dir.Z, txy);
3071 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3072 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3073 LSL_Types.Quaternion spin = llEuler2Rot(az);
3074 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3075 llSetRot(rot);
3076 }
3077 else
3078 {
3079 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3080 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3081 m_host.RotLookAt(q, (float)strength, (float)damping);
3082 }
3083
3084 }
3085
3086 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3087 {
3088 m_host.AddScriptLPS(1);
3089// NotImplemented("llRotLookAt");
3090 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3091
2820 } 3092 }
2821 3093
2822 public void llStopLookAt() 3094 public void llStopLookAt()
@@ -2865,13 +3137,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 { 3137 {
2866 TaskInventoryItem item; 3138 TaskInventoryItem item;
2867 3139
2868 lock (m_host.TaskInventory) 3140 m_host.TaskInventory.LockItemsForRead(true);
3141 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2869 { 3142 {
2870 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3143 m_host.TaskInventory.LockItemsForRead(false);
2871 return; 3144 return;
2872 else
2873 item = m_host.TaskInventory[InventorySelf()];
2874 } 3145 }
3146 else
3147 {
3148 item = m_host.TaskInventory[InventorySelf()];
3149 }
3150 m_host.TaskInventory.LockItemsForRead(false);
2875 3151
2876 if (item.PermsGranter != UUID.Zero) 3152 if (item.PermsGranter != UUID.Zero)
2877 { 3153 {
@@ -2893,13 +3169,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2893 { 3169 {
2894 TaskInventoryItem item; 3170 TaskInventoryItem item;
2895 3171
3172 m_host.TaskInventory.LockItemsForRead(true);
2896 lock (m_host.TaskInventory) 3173 lock (m_host.TaskInventory)
2897 { 3174 {
3175
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3176 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3177 {
3178 m_host.TaskInventory.LockItemsForRead(false);
2899 return; 3179 return;
3180 }
2900 else 3181 else
3182 {
2901 item = m_host.TaskInventory[InventorySelf()]; 3183 item = m_host.TaskInventory[InventorySelf()];
3184 }
2902 } 3185 }
3186 m_host.TaskInventory.LockItemsForRead(false);
2903 3187
2904 m_host.AddScriptLPS(1); 3188 m_host.AddScriptLPS(1);
2905 3189
@@ -2931,18 +3215,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2931 { 3215 {
2932 m_host.AddScriptLPS(1); 3216 m_host.AddScriptLPS(1);
2933 3217
2934 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2935 return;
2936
2937 TaskInventoryItem item; 3218 TaskInventoryItem item;
2938 3219
2939 lock (m_host.TaskInventory) 3220 m_host.TaskInventory.LockItemsForRead(true);
3221
3222 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2940 { 3223 {
2941 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3224 m_host.TaskInventory.LockItemsForRead(false);
2942 return; 3225 return;
2943 else
2944 item = m_host.TaskInventory[InventorySelf()];
2945 } 3226 }
3227 else
3228 {
3229 item = m_host.TaskInventory[InventorySelf()];
3230 }
3231
3232 m_host.TaskInventory.LockItemsForRead(false);
2946 3233
2947 if (item.PermsGranter != m_host.OwnerID) 3234 if (item.PermsGranter != m_host.OwnerID)
2948 return; 3235 return;
@@ -2953,10 +3240,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 3240
2954 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3241 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2955 3242
2956 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3243 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2957 if (attachmentsModule != null)
2958 attachmentsModule.AttachObject(presence.ControllingClient,
2959 grp, (uint)attachment, false);
2960 } 3244 }
2961 } 3245 }
2962 3246
@@ -2969,13 +3253,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2969 3253
2970 TaskInventoryItem item; 3254 TaskInventoryItem item;
2971 3255
2972 lock (m_host.TaskInventory) 3256 m_host.TaskInventory.LockItemsForRead(true);
3257
3258 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2973 { 3259 {
2974 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3260 m_host.TaskInventory.LockItemsForRead(false);
2975 return; 3261 return;
2976 else
2977 item = m_host.TaskInventory[InventorySelf()];
2978 } 3262 }
3263 else
3264 {
3265 item = m_host.TaskInventory[InventorySelf()];
3266 }
3267 m_host.TaskInventory.LockItemsForRead(false);
3268
2979 3269
2980 if (item.PermsGranter != m_host.OwnerID) 3270 if (item.PermsGranter != m_host.OwnerID)
2981 return; 3271 return;
@@ -3022,6 +3312,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3312
3023 public void llInstantMessage(string user, string message) 3313 public void llInstantMessage(string user, string message)
3024 { 3314 {
3315 UUID result;
3316 if (!UUID.TryParse(user, out result))
3317 {
3318 ShoutError("An invalid key was passed to llInstantMessage");
3319 ScriptSleep(2000);
3320 return;
3321 }
3322
3323
3025 m_host.AddScriptLPS(1); 3324 m_host.AddScriptLPS(1);
3026 3325
3027 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3326 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3036,14 +3335,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 UUID friendTransactionID = UUID.Random(); 3335 UUID friendTransactionID = UUID.Random();
3037 3336
3038 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3337 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3039 3338
3040 GridInstantMessage msg = new GridInstantMessage(); 3339 GridInstantMessage msg = new GridInstantMessage();
3041 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3340 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3042 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3341 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3043 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3342 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3044// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3343// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3045// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3344// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3046 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3345// DateTime dt = DateTime.UtcNow;
3346//
3347// // Ticks from UtcNow, but make it look like local. Evil, huh?
3348// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3349//
3350// try
3351// {
3352// // Convert that to the PST timezone
3353// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3354// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3355// }
3356// catch
3357// {
3358// // No logging here, as it could be VERY spammy
3359// }
3360//
3361// // And make it look local again to fool the unix time util
3362// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3363
3364 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3365
3047 //if (client != null) 3366 //if (client != null)
3048 //{ 3367 //{
3049 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3368 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3057,12 +3376,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 msg.message = message.Substring(0, 1024); 3376 msg.message = message.Substring(0, 1024);
3058 else 3377 else
3059 msg.message = message; 3378 msg.message = message;
3060 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3379 msg.dialog = (byte)19; // MessageFromObject
3061 msg.fromGroup = false;// fromGroup; 3380 msg.fromGroup = false;// fromGroup;
3062 msg.offline = (byte)0; //offline; 3381 msg.offline = (byte)0; //offline;
3063 msg.ParentEstateID = 0; //ParentEstateID; 3382 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3064 msg.Position = new Vector3(m_host.AbsolutePosition); 3383 msg.Position = new Vector3(m_host.AbsolutePosition);
3065 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3384 msg.RegionID = World.RegionInfo.RegionID.Guid;
3066 msg.binaryBucket 3385 msg.binaryBucket
3067 = Util.StringToBytes256( 3386 = Util.StringToBytes256(
3068 "{0}/{1}/{2}/{3}", 3387 "{0}/{1}/{2}/{3}",
@@ -3090,7 +3409,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3409 }
3091 3410
3092 emailModule.SendEmail(m_host.UUID, address, subject, message); 3411 emailModule.SendEmail(m_host.UUID, address, subject, message);
3093 ScriptSleep(20000); 3412 ScriptSleep(15000);
3094 } 3413 }
3095 3414
3096 public void llGetNextEmail(string address, string subject) 3415 public void llGetNextEmail(string address, string subject)
@@ -3134,7 +3453,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 { 3453 {
3135 if (!m_host.ParentGroup.IsDeleted) 3454 if (!m_host.ParentGroup.IsDeleted)
3136 { 3455 {
3137 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); 3456 m_host.ParentGroup.RootPart.Buoyancy = (float)buoyancy;
3138 } 3457 }
3139 } 3458 }
3140 } 3459 }
@@ -3192,13 +3511,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 m_host.AddScriptLPS(1); 3511 m_host.AddScriptLPS(1);
3193 } 3512 }
3194 3513
3195 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3196 {
3197 m_host.AddScriptLPS(1);
3198 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3199 m_host.RotLookAt(rot, (float)strength, (float)damping);
3200 }
3201
3202 public LSL_Integer llStringLength(string str) 3514 public LSL_Integer llStringLength(string str)
3203 { 3515 {
3204 m_host.AddScriptLPS(1); 3516 m_host.AddScriptLPS(1);
@@ -3222,14 +3534,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3222 3534
3223 TaskInventoryItem item; 3535 TaskInventoryItem item;
3224 3536
3225 lock (m_host.TaskInventory) 3537 m_host.TaskInventory.LockItemsForRead(true);
3538 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 { 3539 {
3227 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3540 m_host.TaskInventory.LockItemsForRead(false);
3228 return; 3541 return;
3229 else
3230 item = m_host.TaskInventory[InventorySelf()];
3231 } 3542 }
3232 3543 else
3544 {
3545 item = m_host.TaskInventory[InventorySelf()];
3546 }
3547 m_host.TaskInventory.LockItemsForRead(false);
3233 if (item.PermsGranter == UUID.Zero) 3548 if (item.PermsGranter == UUID.Zero)
3234 return; 3549 return;
3235 3550
@@ -3259,13 +3574,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3259 3574
3260 TaskInventoryItem item; 3575 TaskInventoryItem item;
3261 3576
3262 lock (m_host.TaskInventory) 3577 m_host.TaskInventory.LockItemsForRead(true);
3578 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3263 { 3579 {
3264 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3580 m_host.TaskInventory.LockItemsForRead(false);
3265 return; 3581 return;
3266 else
3267 item = m_host.TaskInventory[InventorySelf()];
3268 } 3582 }
3583 else
3584 {
3585 item = m_host.TaskInventory[InventorySelf()];
3586 }
3587 m_host.TaskInventory.LockItemsForRead(false);
3588
3269 3589
3270 if (item.PermsGranter == UUID.Zero) 3590 if (item.PermsGranter == UUID.Zero)
3271 return; 3591 return;
@@ -3330,10 +3650,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3330 3650
3331 TaskInventoryItem item; 3651 TaskInventoryItem item;
3332 3652
3333 lock (m_host.TaskInventory) 3653
3654 m_host.TaskInventory.LockItemsForRead(true);
3655 if (!m_host.TaskInventory.ContainsKey(invItemID))
3656 {
3657 m_host.TaskInventory.LockItemsForRead(false);
3658 return;
3659 }
3660 else
3334 { 3661 {
3335 item = m_host.TaskInventory[invItemID]; 3662 item = m_host.TaskInventory[invItemID];
3336 } 3663 }
3664 m_host.TaskInventory.LockItemsForRead(false);
3337 3665
3338 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3666 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3339 { 3667 {
@@ -3361,15 +3689,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3361 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3689 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3362 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3690 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3363 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3691 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3692 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3364 ScriptBaseClass.PERMISSION_ATTACH; 3693 ScriptBaseClass.PERMISSION_ATTACH;
3365 3694
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3695 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3696 {
3368 lock (m_host.TaskInventory) 3697 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3698 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3699 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3700 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3701
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3702 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3703 "run_time_permissions", new Object[] {
@@ -3379,28 +3707,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3379 return; 3707 return;
3380 } 3708 }
3381 } 3709 }
3382 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3710 else
3383 { 3711 {
3384 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3712 bool sitting = false;
3385 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3713 if (m_host.SitTargetAvatar == agentID)
3386 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3714 {
3387 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3715 sitting = true;
3388 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3716 }
3717 else
3718 {
3719 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3720 {
3721 if (p.SitTargetAvatar == agentID)
3722 sitting = true;
3723 }
3724 }
3389 3725
3390 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3726 if (sitting)
3391 { 3727 {
3392 lock (m_host.TaskInventory) 3728 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3729 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3730 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3731 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3732 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3733
3734 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3393 { 3735 {
3736 m_host.TaskInventory.LockItemsForWrite(true);
3394 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3737 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3395 m_host.TaskInventory[invItemID].PermsMask = perm; 3738 m_host.TaskInventory[invItemID].PermsMask = perm;
3396 } 3739 m_host.TaskInventory.LockItemsForWrite(false);
3397 3740
3398 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3741 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3399 "run_time_permissions", new Object[] { 3742 "run_time_permissions", new Object[] {
3400 new LSL_Integer(perm) }, 3743 new LSL_Integer(perm) },
3401 new DetectParams[0])); 3744 new DetectParams[0]));
3402 3745
3403 return; 3746 return;
3747 }
3404 } 3748 }
3405 } 3749 }
3406 3750
@@ -3414,11 +3758,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 3758
3415 if (!m_waitingForScriptAnswer) 3759 if (!m_waitingForScriptAnswer)
3416 { 3760 {
3417 lock (m_host.TaskInventory) 3761 m_host.TaskInventory.LockItemsForWrite(true);
3418 { 3762 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3419 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3763 m_host.TaskInventory[invItemID].PermsMask = 0;
3420 m_host.TaskInventory[invItemID].PermsMask = 0; 3764 m_host.TaskInventory.LockItemsForWrite(false);
3421 }
3422 3765
3423 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3766 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3424 m_waitingForScriptAnswer=true; 3767 m_waitingForScriptAnswer=true;
@@ -3453,10 +3796,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3453 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3796 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3454 llReleaseControls(); 3797 llReleaseControls();
3455 3798
3456 lock (m_host.TaskInventory) 3799
3457 { 3800 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsMask = answer; 3801 m_host.TaskInventory[invItemID].PermsMask = answer;
3459 } 3802 m_host.TaskInventory.LockItemsForWrite(false);
3803
3460 3804
3461 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3805 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3806 "run_time_permissions", new Object[] {
@@ -3468,16 +3812,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3468 { 3812 {
3469 m_host.AddScriptLPS(1); 3813 m_host.AddScriptLPS(1);
3470 3814
3471 lock (m_host.TaskInventory) 3815 m_host.TaskInventory.LockItemsForRead(true);
3816
3817 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3472 { 3818 {
3473 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3819 if (item.Type == 10 && item.ItemID == m_itemID)
3474 { 3820 {
3475 if (item.Type == 10 && item.ItemID == m_itemID) 3821 m_host.TaskInventory.LockItemsForRead(false);
3476 { 3822 return item.PermsGranter.ToString();
3477 return item.PermsGranter.ToString();
3478 }
3479 } 3823 }
3480 } 3824 }
3825 m_host.TaskInventory.LockItemsForRead(false);
3481 3826
3482 return UUID.Zero.ToString(); 3827 return UUID.Zero.ToString();
3483 } 3828 }
@@ -3486,19 +3831,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3486 { 3831 {
3487 m_host.AddScriptLPS(1); 3832 m_host.AddScriptLPS(1);
3488 3833
3489 lock (m_host.TaskInventory) 3834 m_host.TaskInventory.LockItemsForRead(true);
3835
3836 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3490 { 3837 {
3491 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3838 if (item.Type == 10 && item.ItemID == m_itemID)
3492 { 3839 {
3493 if (item.Type == 10 && item.ItemID == m_itemID) 3840 int perms = item.PermsMask;
3494 { 3841 if (m_automaticLinkPermission)
3495 int perms = item.PermsMask; 3842 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3496 if (m_automaticLinkPermission) 3843 m_host.TaskInventory.LockItemsForRead(false);
3497 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3844 return perms;
3498 return perms;
3499 }
3500 } 3845 }
3501 } 3846 }
3847 m_host.TaskInventory.LockItemsForRead(false);
3502 3848
3503 return 0; 3849 return 0;
3504 } 3850 }
@@ -3520,9 +3866,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3520 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3866 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3521 { 3867 {
3522 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3868 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3523 3869 if (parts.Count > 0)
3524 foreach (SceneObjectPart part in parts) 3870 {
3525 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3871 try
3872 {
3873 parts[0].ParentGroup.areUpdatesSuspended = true;
3874 foreach (SceneObjectPart part in parts)
3875 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3876 }
3877 finally
3878 {
3879 parts[0].ParentGroup.areUpdatesSuspended = false;
3880 }
3881 }
3526 } 3882 }
3527 3883
3528 public void llCreateLink(string target, int parent) 3884 public void llCreateLink(string target, int parent)
@@ -3535,11 +3891,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3535 return; 3891 return;
3536 3892
3537 TaskInventoryItem item; 3893 TaskInventoryItem item;
3538 lock (m_host.TaskInventory) 3894 m_host.TaskInventory.LockItemsForRead(true);
3539 { 3895 item = m_host.TaskInventory[invItemID];
3540 item = m_host.TaskInventory[invItemID]; 3896 m_host.TaskInventory.LockItemsForRead(false);
3541 } 3897
3542
3543 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3898 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3544 && !m_automaticLinkPermission) 3899 && !m_automaticLinkPermission)
3545 { 3900 {
@@ -3556,11 +3911,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 3911
3557 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3912 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0)
3558 return; // Fail silently if attached 3913 return; // Fail silently if attached
3914
3915 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3916 return;
3917
3559 SceneObjectGroup parentPrim = null, childPrim = null; 3918 SceneObjectGroup parentPrim = null, childPrim = null;
3560 3919
3561 if (targetPart != null) 3920 if (targetPart != null)
3562 { 3921 {
3563 if (parent != 0) { 3922 if (parent != 0)
3923 {
3564 parentPrim = m_host.ParentGroup; 3924 parentPrim = m_host.ParentGroup;
3565 childPrim = targetPart.ParentGroup; 3925 childPrim = targetPart.ParentGroup;
3566 } 3926 }
@@ -3592,16 +3952,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3592 m_host.AddScriptLPS(1); 3952 m_host.AddScriptLPS(1);
3593 UUID invItemID = InventorySelf(); 3953 UUID invItemID = InventorySelf();
3594 3954
3595 lock (m_host.TaskInventory) 3955 m_host.TaskInventory.LockItemsForRead(true);
3596 {
3597 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3956 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3598 && !m_automaticLinkPermission) 3957 && !m_automaticLinkPermission)
3599 { 3958 {
3600 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3959 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3960 m_host.TaskInventory.LockItemsForRead(false);
3601 return; 3961 return;
3602 } 3962 }
3603 } 3963 m_host.TaskInventory.LockItemsForRead(false);
3604 3964
3605 if (linknum < ScriptBaseClass.LINK_THIS) 3965 if (linknum < ScriptBaseClass.LINK_THIS)
3606 return; 3966 return;
3607 3967
@@ -3640,10 +4000,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 // Restructuring Multiple Prims. 4000 // Restructuring Multiple Prims.
3641 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4001 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3642 parts.Remove(parentPrim.RootPart); 4002 parts.Remove(parentPrim.RootPart);
3643 foreach (SceneObjectPart part in parts) 4003 if (parts.Count > 0)
3644 { 4004 {
3645 parentPrim.DelinkFromGroup(part.LocalId, true); 4005 try
4006 {
4007 parts[0].ParentGroup.areUpdatesSuspended = true;
4008 foreach (SceneObjectPart part in parts)
4009 {
4010 parentPrim.DelinkFromGroup(part.LocalId, true);
4011 }
4012 }
4013 finally
4014 {
4015 parts[0].ParentGroup.areUpdatesSuspended = false;
4016 }
3646 } 4017 }
4018
3647 parentPrim.HasGroupChanged = true; 4019 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 4020 parentPrim.ScheduleGroupForFullUpdate();
3649 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4021 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3652,11 +4024,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3652 { 4024 {
3653 SceneObjectPart newRoot = parts[0]; 4025 SceneObjectPart newRoot = parts[0];
3654 parts.Remove(newRoot); 4026 parts.Remove(newRoot);
3655 foreach (SceneObjectPart part in parts) 4027
4028 try
3656 { 4029 {
3657 part.UpdateFlag = 0; 4030 parts[0].ParentGroup.areUpdatesSuspended = true;
3658 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4031 foreach (SceneObjectPart part in parts)
4032 {
4033 part.UpdateFlag = 0;
4034 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4035 }
3659 } 4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
4041
4042
3660 newRoot.ParentGroup.HasGroupChanged = true; 4043 newRoot.ParentGroup.HasGroupChanged = true;
3661 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4044 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3662 } 4045 }
@@ -3676,6 +4059,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3676 public void llBreakAllLinks() 4059 public void llBreakAllLinks()
3677 { 4060 {
3678 m_host.AddScriptLPS(1); 4061 m_host.AddScriptLPS(1);
4062
4063 UUID invItemID = InventorySelf();
4064
4065 TaskInventoryItem item;
4066 m_host.TaskInventory.LockItemsForRead(true);
4067 item = m_host.TaskInventory[invItemID];
4068 m_host.TaskInventory.LockItemsForRead(false);
4069
4070 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4071 && !m_automaticLinkPermission)
4072 {
4073 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4074 return;
4075 }
4076
3679 SceneObjectGroup parentPrim = m_host.ParentGroup; 4077 SceneObjectGroup parentPrim = m_host.ParentGroup;
3680 if (parentPrim.RootPart.AttachmentPoint != 0) 4078 if (parentPrim.RootPart.AttachmentPoint != 0)
3681 return; // Fail silently if attached 4079 return; // Fail silently if attached
@@ -3702,6 +4100,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3702 } 4100 }
3703 else 4101 else
3704 { 4102 {
4103 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4104 {
4105 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4106
4107 if (linknum < 0)
4108 return UUID.Zero.ToString();
4109
4110 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4111 if (avatars.Count > linknum)
4112 {
4113 return avatars[linknum].UUID.ToString();
4114 }
4115 }
3705 return UUID.Zero.ToString(); 4116 return UUID.Zero.ToString();
3706 } 4117 }
3707 } 4118 }
@@ -3778,17 +4189,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3778 m_host.AddScriptLPS(1); 4189 m_host.AddScriptLPS(1);
3779 int count = 0; 4190 int count = 0;
3780 4191
3781 lock (m_host.TaskInventory) 4192 m_host.TaskInventory.LockItemsForRead(true);
4193 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3782 { 4194 {
3783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4195 if (inv.Value.Type == type || type == -1)
3784 { 4196 {
3785 if (inv.Value.Type == type || type == -1) 4197 count = count + 1;
3786 {
3787 count = count + 1;
3788 }
3789 } 4198 }
3790 } 4199 }
3791 4200
4201 m_host.TaskInventory.LockItemsForRead(false);
3792 return count; 4202 return count;
3793 } 4203 }
3794 4204
@@ -3797,16 +4207,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3797 m_host.AddScriptLPS(1); 4207 m_host.AddScriptLPS(1);
3798 ArrayList keys = new ArrayList(); 4208 ArrayList keys = new ArrayList();
3799 4209
3800 lock (m_host.TaskInventory) 4210 m_host.TaskInventory.LockItemsForRead(true);
4211 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3801 { 4212 {
3802 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4213 if (inv.Value.Type == type || type == -1)
3803 { 4214 {
3804 if (inv.Value.Type == type || type == -1) 4215 keys.Add(inv.Value.Name);
3805 {
3806 keys.Add(inv.Value.Name);
3807 }
3808 } 4216 }
3809 } 4217 }
4218 m_host.TaskInventory.LockItemsForRead(false);
3810 4219
3811 if (keys.Count == 0) 4220 if (keys.Count == 0)
3812 { 4221 {
@@ -3843,25 +4252,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 } 4252 }
3844 4253
3845 // move the first object found with this inventory name 4254 // move the first object found with this inventory name
3846 lock (m_host.TaskInventory) 4255 m_host.TaskInventory.LockItemsForRead(true);
4256 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3847 { 4257 {
3848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4258 if (inv.Value.Name == inventory)
3849 { 4259 {
3850 if (inv.Value.Name == inventory) 4260 found = true;
3851 { 4261 objId = inv.Key;
3852 found = true; 4262 assetType = inv.Value.Type;
3853 objId = inv.Key; 4263 objName = inv.Value.Name;
3854 assetType = inv.Value.Type; 4264 break;
3855 objName = inv.Value.Name;
3856 break;
3857 }
3858 } 4265 }
3859 } 4266 }
4267 m_host.TaskInventory.LockItemsForRead(false);
3860 4268
3861 if (!found) 4269 if (!found)
3862 { 4270 {
3863 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4271 llSay(0, String.Format("Could not find object '{0}'", inventory));
3864 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4272 return;
4273// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3865 } 4274 }
3866 4275
3867 // check if destination is an object 4276 // check if destination is an object
@@ -3887,6 +4296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3887 return; 4296 return;
3888 } 4297 }
3889 } 4298 }
4299
3890 // destination is an avatar 4300 // destination is an avatar
3891 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4301 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3892 4302
@@ -3909,26 +4319,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3909 bucket); 4319 bucket);
3910 if (m_TransferModule != null) 4320 if (m_TransferModule != null)
3911 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4321 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4322
4323 //This delay should only occur when giving inventory to avatars.
3912 ScriptSleep(3000); 4324 ScriptSleep(3000);
3913 } 4325 }
3914 } 4326 }
3915 4327
4328 [DebuggerNonUserCode]
3916 public void llRemoveInventory(string name) 4329 public void llRemoveInventory(string name)
3917 { 4330 {
3918 m_host.AddScriptLPS(1); 4331 m_host.AddScriptLPS(1);
3919 4332
3920 lock (m_host.TaskInventory) 4333 List<TaskInventoryItem> inv;
4334 try
3921 { 4335 {
3922 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4336 m_host.TaskInventory.LockItemsForRead(true);
4337 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4338 }
4339 finally
4340 {
4341 m_host.TaskInventory.LockItemsForRead(false);
4342 }
4343 foreach (TaskInventoryItem item in inv)
4344 {
4345 if (item.Name == name)
3923 { 4346 {
3924 if (item.Name == name) 4347 if (item.ItemID == m_itemID)
3925 { 4348 throw new ScriptDeleteException();
3926 if (item.ItemID == m_itemID) 4349 else
3927 throw new ScriptDeleteException(); 4350 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3928 else 4351 return;
3929 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3930 return;
3931 }
3932 } 4352 }
3933 } 4353 }
3934 } 4354 }
@@ -3963,112 +4383,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3963 { 4383 {
3964 m_host.AddScriptLPS(1); 4384 m_host.AddScriptLPS(1);
3965 4385
3966 UUID uuid = (UUID)id; 4386 UUID uuid;
3967 PresenceInfo pinfo = null; 4387 if (UUID.TryParse(id, out uuid))
3968 UserAccount account;
3969
3970 UserInfoCacheEntry ce;
3971 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3972 { 4388 {
3973 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4389 PresenceInfo pinfo = null;
3974 if (account == null) 4390 UserAccount account;
4391
4392 UserInfoCacheEntry ce;
4393 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3975 { 4394 {
3976 m_userInfoCache[uuid] = null; // Cache negative 4395 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3977 return UUID.Zero.ToString(); 4396 if (account == null)
3978 } 4397 {
4398 m_userInfoCache[uuid] = null; // Cache negative
4399 return UUID.Zero.ToString();
4400 }
3979 4401
3980 4402
3981 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4403 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3982 if (pinfos != null && pinfos.Length > 0) 4404 if (pinfos != null && pinfos.Length > 0)
3983 {
3984 foreach (PresenceInfo p in pinfos)
3985 { 4405 {
3986 if (p.RegionID != UUID.Zero) 4406 foreach (PresenceInfo p in pinfos)
3987 { 4407 {
3988 pinfo = p; 4408 if (p.RegionID != UUID.Zero)
4409 {
4410 pinfo = p;
4411 }
3989 } 4412 }
3990 } 4413 }
3991 }
3992 4414
3993 ce = new UserInfoCacheEntry(); 4415 ce = new UserInfoCacheEntry();
3994 ce.time = Util.EnvironmentTickCount(); 4416 ce.time = Util.EnvironmentTickCount();
3995 ce.account = account; 4417 ce.account = account;
3996 ce.pinfo = pinfo; 4418 ce.pinfo = pinfo;
3997 } 4419 m_userInfoCache[uuid] = ce;
3998 else 4420 }
3999 { 4421 else
4000 if (ce == null) 4422 {
4001 return UUID.Zero.ToString(); 4423 if (ce == null)
4424 return UUID.Zero.ToString();
4002 4425
4003 account = ce.account; 4426 account = ce.account;
4004 pinfo = ce.pinfo; 4427 pinfo = ce.pinfo;
4005 } 4428 }
4006 4429
4007 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4430 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4008 {
4009 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4010 if (pinfos != null && pinfos.Length > 0)
4011 { 4431 {
4012 foreach (PresenceInfo p in pinfos) 4432 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4433 if (pinfos != null && pinfos.Length > 0)
4013 { 4434 {
4014 if (p.RegionID != UUID.Zero) 4435 foreach (PresenceInfo p in pinfos)
4015 { 4436 {
4016 pinfo = p; 4437 if (p.RegionID != UUID.Zero)
4438 {
4439 pinfo = p;
4440 }
4017 } 4441 }
4018 } 4442 }
4019 } 4443 else
4020 else 4444 pinfo = null;
4021 pinfo = null;
4022 4445
4023 ce.time = Util.EnvironmentTickCount(); 4446 ce.time = Util.EnvironmentTickCount();
4024 ce.pinfo = pinfo; 4447 ce.pinfo = pinfo;
4025 } 4448 }
4026 4449
4027 string reply = String.Empty; 4450 string reply = String.Empty;
4028 4451
4029 switch (data) 4452 switch (data)
4030 { 4453 {
4031 case 1: // DATA_ONLINE (0|1) 4454 case 1: // DATA_ONLINE (0|1)
4032 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4455 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4033 reply = "1"; 4456 reply = "1";
4034 else 4457 else
4035 reply = "0"; 4458 reply = "0";
4036 break; 4459 break;
4037 case 2: // DATA_NAME (First Last) 4460 case 2: // DATA_NAME (First Last)
4038 reply = account.FirstName + " " + account.LastName; 4461 reply = account.FirstName + " " + account.LastName;
4039 break; 4462 break;
4040 case 3: // DATA_BORN (YYYY-MM-DD) 4463 case 3: // DATA_BORN (YYYY-MM-DD)
4041 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4464 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4042 born = born.AddSeconds(account.Created); 4465 born = born.AddSeconds(account.Created);
4043 reply = born.ToString("yyyy-MM-dd"); 4466 reply = born.ToString("yyyy-MM-dd");
4044 break; 4467 break;
4045 case 4: // DATA_RATING (0,0,0,0,0,0) 4468 case 4: // DATA_RATING (0,0,0,0,0,0)
4046 reply = "0,0,0,0,0,0"; 4469 reply = "0,0,0,0,0,0";
4047 break; 4470 break;
4048 case 8: // DATA_PAYINFO (0|1|2|3) 4471 case 8: // DATA_PAYINFO (0|1|2|3)
4049 reply = "0"; 4472 reply = "0";
4050 break; 4473 break;
4051 default: 4474 default:
4052 return UUID.Zero.ToString(); // Raise no event 4475 return UUID.Zero.ToString(); // Raise no event
4053 } 4476 }
4054 4477
4055 UUID rq = UUID.Random(); 4478 UUID rq = UUID.Random();
4056 4479
4057 UUID tid = AsyncCommands. 4480 UUID tid = AsyncCommands.
4058 DataserverPlugin.RegisterRequest(m_localID, 4481 DataserverPlugin.RegisterRequest(m_localID,
4059 m_itemID, rq.ToString()); 4482 m_itemID, rq.ToString());
4060 4483
4061 AsyncCommands. 4484 AsyncCommands.
4062 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4485 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4063 4486
4064 ScriptSleep(100); 4487 ScriptSleep(100);
4065 return tid.ToString(); 4488 return tid.ToString();
4489 }
4490 else
4491 {
4492 ShoutError("Invalid UUID passed to llRequestAgentData.");
4493 }
4494 return "";
4066 } 4495 }
4067 4496
4068 public LSL_String llRequestInventoryData(string name) 4497 public LSL_String llRequestInventoryData(string name)
4069 { 4498 {
4070 m_host.AddScriptLPS(1); 4499 m_host.AddScriptLPS(1);
4071 4500
4501 //Clone is thread safe
4072 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4502 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4073 4503
4074 foreach (TaskInventoryItem item in itemDictionary.Values) 4504 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4122,6 +4552,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4122 ScenePresence presence = World.GetScenePresence(agentId); 4552 ScenePresence presence = World.GetScenePresence(agentId);
4123 if (presence != null) 4553 if (presence != null)
4124 { 4554 {
4555 // agent must not be a god
4556 if (presence.UserLevel >= 200) return;
4557
4125 // agent must be over the owners land 4558 // agent must be over the owners land
4126 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4559 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4127 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4560 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4144,7 +4577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4144 UUID av = new UUID(); 4577 UUID av = new UUID();
4145 if (!UUID.TryParse(agent,out av)) 4578 if (!UUID.TryParse(agent,out av))
4146 { 4579 {
4147 LSLError("First parameter to llDialog needs to be a key"); 4580 //LSLError("First parameter to llDialog needs to be a key");
4148 return; 4581 return;
4149 } 4582 }
4150 4583
@@ -4181,17 +4614,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4181 UUID soundId = UUID.Zero; 4614 UUID soundId = UUID.Zero;
4182 if (!UUID.TryParse(impact_sound, out soundId)) 4615 if (!UUID.TryParse(impact_sound, out soundId))
4183 { 4616 {
4184 lock (m_host.TaskInventory) 4617 m_host.TaskInventory.LockItemsForRead(true);
4618 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4185 { 4619 {
4186 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4620 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4187 { 4621 {
4188 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4622 soundId = item.AssetID;
4189 { 4623 break;
4190 soundId = item.AssetID;
4191 break;
4192 }
4193 } 4624 }
4194 } 4625 }
4626 m_host.TaskInventory.LockItemsForRead(false);
4195 } 4627 }
4196 m_host.CollisionSound = soundId; 4628 m_host.CollisionSound = soundId;
4197 m_host.CollisionSoundVolume = (float)impact_volume; 4629 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4231,6 +4663,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4231 UUID partItemID; 4663 UUID partItemID;
4232 foreach (SceneObjectPart part in parts) 4664 foreach (SceneObjectPart part in parts)
4233 { 4665 {
4666 //Clone is thread safe
4234 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4667 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4235 4668
4236 foreach (TaskInventoryItem item in itemsDictionary.Values) 4669 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4445,17 +4878,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4445 4878
4446 m_host.AddScriptLPS(1); 4879 m_host.AddScriptLPS(1);
4447 4880
4448 lock (m_host.TaskInventory) 4881 m_host.TaskInventory.LockItemsForRead(true);
4882 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4449 { 4883 {
4450 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4884 if (item.Type == 10 && item.ItemID == m_itemID)
4451 { 4885 {
4452 if (item.Type == 10 && item.ItemID == m_itemID) 4886 result = item.Name!=null?item.Name:String.Empty;
4453 { 4887 break;
4454 result = item.Name != null ? item.Name : String.Empty;
4455 break;
4456 }
4457 } 4888 }
4458 } 4889 }
4890 m_host.TaskInventory.LockItemsForRead(false);
4459 4891
4460 return result; 4892 return result;
4461 } 4893 }
@@ -4624,23 +5056,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4624 { 5056 {
4625 m_host.AddScriptLPS(1); 5057 m_host.AddScriptLPS(1);
4626 5058
4627 lock (m_host.TaskInventory) 5059 m_host.TaskInventory.LockItemsForRead(true);
5060 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4628 { 5061 {
4629 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5062 if (inv.Value.Name == name)
4630 { 5063 {
4631 if (inv.Value.Name == name) 5064 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4632 { 5065 {
4633 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5066 m_host.TaskInventory.LockItemsForRead(false);
4634 { 5067 return inv.Value.AssetID.ToString();
4635 return inv.Value.AssetID.ToString(); 5068 }
4636 } 5069 else
4637 else 5070 {
4638 { 5071 m_host.TaskInventory.LockItemsForRead(false);
4639 return UUID.Zero.ToString(); 5072 return UUID.Zero.ToString();
4640 }
4641 } 5073 }
4642 } 5074 }
4643 } 5075 }
5076 m_host.TaskInventory.LockItemsForRead(false);
4644 5077
4645 return UUID.Zero.ToString(); 5078 return UUID.Zero.ToString();
4646 } 5079 }
@@ -4793,14 +5226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4793 { 5226 {
4794 m_host.AddScriptLPS(1); 5227 m_host.AddScriptLPS(1);
4795 5228
4796 if (src == null) 5229 return src.Length;
4797 {
4798 return 0;
4799 }
4800 else
4801 {
4802 return src.Length;
4803 }
4804 } 5230 }
4805 5231
4806 public LSL_Integer llList2Integer(LSL_List src, int index) 5232 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4846,7 +5272,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4846 else if (src.Data[index] is LSL_Float) 5272 else if (src.Data[index] is LSL_Float)
4847 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5273 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4848 else if (src.Data[index] is LSL_String) 5274 else if (src.Data[index] is LSL_String)
4849 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5275 {
5276 string str = ((LSL_String) src.Data[index]).m_string;
5277 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5278 if (m != Match.Empty)
5279 {
5280 str = m.Value;
5281 double d = 0.0;
5282 if (!Double.TryParse(str, out d))
5283 return 0.0;
5284
5285 return d;
5286 }
5287 return 0.0;
5288 }
4850 return Convert.ToDouble(src.Data[index]); 5289 return Convert.ToDouble(src.Data[index]);
4851 } 5290 }
4852 catch (FormatException) 5291 catch (FormatException)
@@ -5050,7 +5489,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5050 } 5489 }
5051 } 5490 }
5052 5491
5053 result.Add(src.Substring(start,length).Trim()); 5492 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5054 5493
5055 return result; 5494 return result;
5056 } 5495 }
@@ -5119,7 +5558,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5119 } 5558 }
5120 } 5559 }
5121 } 5560 }
5122 else { 5561 else
5562 {
5123 object[] array = new object[src.Length]; 5563 object[] array = new object[src.Length];
5124 Array.Copy(src.Data, 0, array, 0, src.Length); 5564 Array.Copy(src.Data, 0, array, 0, src.Length);
5125 result = new LSL_List(array); 5565 result = new LSL_List(array);
@@ -5570,10 +6010,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5570 m_host.AddScriptLPS(1); 6010 m_host.AddScriptLPS(1);
5571 6011
5572 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6012 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5573 6013 if (parts.Count > 0)
5574 foreach (var part in parts)
5575 { 6014 {
5576 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6015 try
6016 {
6017 parts[0].ParentGroup.areUpdatesSuspended = true;
6018 foreach (var part in parts)
6019 {
6020 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6021 }
6022 }
6023 finally
6024 {
6025 parts[0].ParentGroup.areUpdatesSuspended = false;
6026 }
5577 } 6027 }
5578 } 6028 }
5579 6029
@@ -5627,6 +6077,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5627 ScriptSleep(5000); 6077 ScriptSleep(5000);
5628 } 6078 }
5629 6079
6080 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6081 {
6082 return ParseString2List(str, separators, in_spacers, false);
6083 }
6084
5630 public LSL_Integer llOverMyLand(string id) 6085 public LSL_Integer llOverMyLand(string id)
5631 { 6086 {
5632 m_host.AddScriptLPS(1); 6087 m_host.AddScriptLPS(1);
@@ -5827,7 +6282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5827 return m_host.ParentGroup.RootPart.AttachmentPoint; 6282 return m_host.ParentGroup.RootPart.AttachmentPoint;
5828 } 6283 }
5829 6284
5830 public LSL_Integer llGetFreeMemory() 6285 public virtual LSL_Integer llGetFreeMemory()
5831 { 6286 {
5832 m_host.AddScriptLPS(1); 6287 m_host.AddScriptLPS(1);
5833 // Make scripts designed for LSO happy 6288 // Make scripts designed for LSO happy
@@ -5944,7 +6399,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5944 SetParticleSystem(m_host, rules); 6399 SetParticleSystem(m_host, rules);
5945 } 6400 }
5946 6401
5947 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6402 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6403 {
5948 6404
5949 6405
5950 if (rules.Length == 0) 6406 if (rules.Length == 0)
@@ -6138,14 +6594,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6138 6594
6139 protected UUID GetTaskInventoryItem(string name) 6595 protected UUID GetTaskInventoryItem(string name)
6140 { 6596 {
6141 lock (m_host.TaskInventory) 6597 m_host.TaskInventory.LockItemsForRead(true);
6598 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6142 { 6599 {
6143 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6600 if (inv.Value.Name == name)
6144 { 6601 {
6145 if (inv.Value.Name == name) 6602 m_host.TaskInventory.LockItemsForRead(false);
6146 return inv.Key; 6603 return inv.Key;
6147 } 6604 }
6148 } 6605 }
6606 m_host.TaskInventory.LockItemsForRead(false);
6149 6607
6150 return UUID.Zero; 6608 return UUID.Zero;
6151 } 6609 }
@@ -6395,13 +6853,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6395 UUID av = new UUID(); 6853 UUID av = new UUID();
6396 if (!UUID.TryParse(avatar,out av)) 6854 if (!UUID.TryParse(avatar,out av))
6397 { 6855 {
6398 LSLError("First parameter to llDialog needs to be a key"); 6856 //LSLError("First parameter to llDialog needs to be a key");
6399 return; 6857 return;
6400 } 6858 }
6401 if (buttons.Length < 1) 6859 if (buttons.Length < 1)
6402 { 6860 {
6403 LSLError("No less than 1 button can be shown"); 6861 buttons.Add("OK");
6404 return;
6405 } 6862 }
6406 if (buttons.Length > 12) 6863 if (buttons.Length > 12)
6407 { 6864 {
@@ -6418,7 +6875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6418 } 6875 }
6419 if (buttons.Data[i].ToString().Length > 24) 6876 if (buttons.Data[i].ToString().Length > 24)
6420 { 6877 {
6421 LSLError("button label cannot be longer than 24 characters"); 6878 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6422 return; 6879 return;
6423 } 6880 }
6424 buts[i] = buttons.Data[i].ToString(); 6881 buts[i] = buttons.Data[i].ToString();
@@ -6482,22 +6939,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6482 } 6939 }
6483 6940
6484 // copy the first script found with this inventory name 6941 // copy the first script found with this inventory name
6485 lock (m_host.TaskInventory) 6942 TaskInventoryItem scriptItem = null;
6943 m_host.TaskInventory.LockItemsForRead(true);
6944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6486 { 6945 {
6487 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6946 if (inv.Value.Name == name)
6488 { 6947 {
6489 if (inv.Value.Name == name) 6948 // make sure the object is a script
6949 if (10 == inv.Value.Type)
6490 { 6950 {
6491 // make sure the object is a script 6951 found = true;
6492 if (10 == inv.Value.Type) 6952 srcId = inv.Key;
6493 { 6953 scriptItem = inv.Value;
6494 found = true; 6954 break;
6495 srcId = inv.Key;
6496 break;
6497 }
6498 } 6955 }
6499 } 6956 }
6500 } 6957 }
6958 m_host.TaskInventory.LockItemsForRead(false);
6501 6959
6502 if (!found) 6960 if (!found)
6503 { 6961 {
@@ -6505,8 +6963,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6505 return; 6963 return;
6506 } 6964 }
6507 6965
6508 // the rest of the permission checks are done in RezScript, so check the pin there as well 6966 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6509 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6967 if (dest != null)
6968 {
6969 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6970 {
6971 // the rest of the permission checks are done in RezScript, so check the pin there as well
6972 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6973
6974 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6975 m_host.Inventory.RemoveInventoryItem(srcId);
6976 }
6977 }
6510 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6978 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6511 ScriptSleep(3000); 6979 ScriptSleep(3000);
6512 } 6980 }
@@ -6569,18 +7037,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6569 public LSL_String llMD5String(string src, int nonce) 7037 public LSL_String llMD5String(string src, int nonce)
6570 { 7038 {
6571 m_host.AddScriptLPS(1); 7039 m_host.AddScriptLPS(1);
6572 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7040 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6573 } 7041 }
6574 7042
6575 public LSL_String llSHA1String(string src) 7043 public LSL_String llSHA1String(string src)
6576 { 7044 {
6577 m_host.AddScriptLPS(1); 7045 m_host.AddScriptLPS(1);
6578 return Util.SHA1Hash(src).ToLower(); 7046 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6579 } 7047 }
6580 7048
6581 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7049 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6582 { 7050 {
6583 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7051 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7053 return shapeBlock;
6584 7054
6585 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7055 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6586 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7056 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6656,6 +7126,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6656 7126
6657 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7127 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6658 { 7128 {
7129 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7130 return;
7131
6659 ObjectShapePacket.ObjectDataBlock shapeBlock; 7132 ObjectShapePacket.ObjectDataBlock shapeBlock;
6660 7133
6661 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7134 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6705,6 +7178,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6705 7178
6706 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7179 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6707 { 7180 {
7181 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7182 return;
7183
6708 ObjectShapePacket.ObjectDataBlock shapeBlock; 7184 ObjectShapePacket.ObjectDataBlock shapeBlock;
6709 7185
6710 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7186 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6747,6 +7223,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6747 7223
6748 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 fudge) 7224 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 fudge)
6749 { 7225 {
7226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7227 return;
7228
6750 ObjectShapePacket.ObjectDataBlock shapeBlock; 7229 ObjectShapePacket.ObjectDataBlock shapeBlock;
6751 7230
6752 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7231 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6873,6 +7352,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6873 7352
6874 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7353 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6875 { 7354 {
7355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7356 return;
7357
6876 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7358 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6877 UUID sculptId; 7359 UUID sculptId;
6878 7360
@@ -6888,13 +7370,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6888 shapeBlock.PathScaleX = 100; 7370 shapeBlock.PathScaleX = 100;
6889 shapeBlock.PathScaleY = 150; 7371 shapeBlock.PathScaleY = 150;
6890 7372
6891 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7373 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6892 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7374 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6893 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7375 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6894 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7376 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6895 { 7377 {
6896 // default 7378 // default
6897 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7379 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6898 } 7380 }
6899 7381
6900 // retain pathcurve 7382 // retain pathcurve
@@ -6913,32 +7395,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6913 ScriptSleep(200); 7395 ScriptSleep(200);
6914 } 7396 }
6915 7397
6916 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7398 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6917 { 7399 {
6918 m_host.AddScriptLPS(1); 7400 m_host.AddScriptLPS(1);
6919 7401
6920 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7402 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7403 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7404 if (parts.Count>0)
7405 {
7406 try
7407 {
7408 parts[0].ParentGroup.areUpdatesSuspended = true;
7409 foreach (SceneObjectPart part in parts)
7410 SetPrimParams(part, rules);
7411 }
7412 finally
7413 {
7414 parts[0].ParentGroup.areUpdatesSuspended = false;
7415 }
7416 }
7417 if (avatars.Count > 0)
7418 {
7419 foreach (ScenePresence avatar in avatars)
7420 SetPrimParams(avatar, rules);
7421 }
7422 }
6921 7423
6922 foreach (SceneObjectPart part in parts) 7424 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6923 SetPrimParams(part, rules); 7425 {
6924 7426 llSetLinkPrimitiveParamsFast(linknumber, rules);
6925 ScriptSleep(200); 7427 ScriptSleep(200);
6926 } 7428 }
6927 7429
6928 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7430 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6929 { 7431 {
6930 m_host.AddScriptLPS(1); 7432 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7433 //We only support PRIM_POSITION and PRIM_ROTATION
6931 7434
6932 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7435 int idx = 0;
6933 7436
6934 foreach (SceneObjectPart part in parts) 7437 while (idx < rules.Length)
6935 SetPrimParams(part, rules); 7438 {
7439 int code = rules.GetLSLIntegerItem(idx++);
7440
7441 int remain = rules.Length - idx;
7442
7443
7444
7445 switch (code)
7446 {
7447 case (int)ScriptBaseClass.PRIM_POSITION:
7448 if (remain < 1)
7449 return;
7450 LSL_Vector v;
7451 v = rules.GetVector3Item(idx++);
7452 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7453 av.SendAvatarDataToAllAgents();
7454
7455 break;
7456
7457 case (int)ScriptBaseClass.PRIM_ROTATION:
7458 if (remain < 1)
7459 return;
7460 LSL_Rotation r;
7461 r = rules.GetQuaternionItem(idx++);
7462 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7463 av.SendAvatarDataToAllAgents();
7464 break;
7465 }
7466 }
6936 } 7467 }
6937 7468
6938 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7469 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6939 { 7470 {
7471 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7472 return;
7473
6940 int idx = 0; 7474 int idx = 0;
6941 7475
7476 bool positionChanged = false;
7477 LSL_Vector currentPosition = GetPartLocalPos(part);
7478
6942 while (idx < rules.Length) 7479 while (idx < rules.Length)
6943 { 7480 {
6944 int code = rules.GetLSLIntegerItem(idx++); 7481 int code = rules.GetLSLIntegerItem(idx++);
@@ -6947,7 +7484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6947 7484
6948 int face; 7485 int face;
6949 LSL_Vector v; 7486 LSL_Vector v;
6950 7487
6951 switch (code) 7488 switch (code)
6952 { 7489 {
6953 case (int)ScriptBaseClass.PRIM_POSITION: 7490 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6955,7 +7492,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6955 return; 7492 return;
6956 7493
6957 v=rules.GetVector3Item(idx++); 7494 v=rules.GetVector3Item(idx++);
6958 SetPos(part, v); 7495 positionChanged = true;
7496 currentPosition = GetSetPosTarget(part, v, currentPosition);
6959 7497
6960 break; 7498 break;
6961 case (int)ScriptBaseClass.PRIM_SIZE: 7499 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7323,6 +7861,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7323 break; 7861 break;
7324 } 7862 }
7325 } 7863 }
7864
7865 if (positionChanged)
7866 {
7867 if (part.ParentGroup.RootPart == part)
7868 {
7869 SceneObjectGroup parent = part.ParentGroup;
7870 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7871 }
7872 else
7873 {
7874 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7875 SceneObjectGroup parent = part.ParentGroup;
7876 parent.HasGroupChanged = true;
7877 parent.ScheduleGroupForTerseUpdate();
7878 }
7879 }
7326 } 7880 }
7327 7881
7328 public LSL_String llStringToBase64(string str) 7882 public LSL_String llStringToBase64(string str)
@@ -7471,13 +8025,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7471 public LSL_Integer llGetNumberOfPrims() 8025 public LSL_Integer llGetNumberOfPrims()
7472 { 8026 {
7473 m_host.AddScriptLPS(1); 8027 m_host.AddScriptLPS(1);
7474 int avatarCount = 0; 8028 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7475 World.ForEachScenePresence(delegate(ScenePresence presence) 8029
7476 {
7477 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7478 avatarCount++;
7479 });
7480
7481 return m_host.ParentGroup.PrimCount + avatarCount; 8030 return m_host.ParentGroup.PrimCount + avatarCount;
7482 } 8031 }
7483 8032
@@ -7493,55 +8042,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7493 m_host.AddScriptLPS(1); 8042 m_host.AddScriptLPS(1);
7494 UUID objID = UUID.Zero; 8043 UUID objID = UUID.Zero;
7495 LSL_List result = new LSL_List(); 8044 LSL_List result = new LSL_List();
8045
8046 // If the ID is not valid, return null result
7496 if (!UUID.TryParse(obj, out objID)) 8047 if (!UUID.TryParse(obj, out objID))
7497 { 8048 {
7498 result.Add(new LSL_Vector()); 8049 result.Add(new LSL_Vector());
7499 result.Add(new LSL_Vector()); 8050 result.Add(new LSL_Vector());
7500 return result; 8051 return result;
7501 } 8052 }
8053
8054 // Check if this is an attached prim. If so, replace
8055 // the UUID with the avatar UUID and report it's bounding box
8056 SceneObjectPart part = World.GetSceneObjectPart(objID);
8057 if (part != null && part.ParentGroup.IsAttachment)
8058 objID = part.ParentGroup.RootPart.AttachedAvatar;
8059
8060 // Find out if this is an avatar ID. If so, return it's box
7502 ScenePresence presence = World.GetScenePresence(objID); 8061 ScenePresence presence = World.GetScenePresence(objID);
7503 if (presence != null) 8062 if (presence != null)
7504 { 8063 {
7505 if (presence.ParentID == 0) // not sat on an object 8064 // As per LSL Wiki, there is no difference between sitting
8065 // and standing avatar since server 1.36
8066 LSL_Vector lower;
8067 LSL_Vector upper;
8068 if (presence.Animator.Animations.DefaultAnimation.AnimID
8069 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7506 { 8070 {
7507 LSL_Vector lower; 8071 // This is for ground sitting avatars
7508 LSL_Vector upper; 8072 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7509 if (presence.Animator.Animations.DefaultAnimation.AnimID 8073 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7510 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8074 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7511 {
7512 // This is for ground sitting avatars
7513 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7514 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7515 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7516 }
7517 else
7518 {
7519 // This is for standing/flying avatars
7520 float height = presence.Appearance.AvatarHeight / 2.0f;
7521 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7522 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7523 }
7524 result.Add(lower);
7525 result.Add(upper);
7526 return result;
7527 } 8075 }
7528 else 8076 else
7529 { 8077 {
7530 // sitting on an object so we need the bounding box of that 8078 // This is for standing/flying avatars
7531 // which should include the avatar so set the UUID to the 8079 float height = presence.Appearance.AvatarHeight / 2.0f;
7532 // UUID of the object the avatar is sat on and allow it to fall through 8080 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7533 // to processing an object 8081 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7534 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7535 objID = p.UUID;
7536 } 8082 }
8083
8084 // Adjust to the documented error offsets (see LSL Wiki)
8085 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8086 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8087
8088 if (lower.x > upper.x)
8089 lower.x = upper.x;
8090 if (lower.y > upper.y)
8091 lower.y = upper.y;
8092 if (lower.z > upper.z)
8093 lower.z = upper.z;
8094
8095 result.Add(lower);
8096 result.Add(upper);
8097 return result;
7537 } 8098 }
7538 SceneObjectPart part = World.GetSceneObjectPart(objID); 8099
8100 part = World.GetSceneObjectPart(objID);
7539 // Currently only works for single prims without a sitting avatar 8101 // Currently only works for single prims without a sitting avatar
7540 if (part != null) 8102 if (part != null)
7541 { 8103 {
7542 Vector3 halfSize = part.Scale / 2.0f; 8104 float minX;
7543 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8105 float maxX;
7544 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8106 float minY;
8107 float maxY;
8108 float minZ;
8109 float maxZ;
8110
8111 // This BBox is in sim coordinates, with the offset being
8112 // a contained point.
8113 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8114 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8115
8116 minX -= offsets[0].X;
8117 maxX -= offsets[0].X;
8118 minY -= offsets[0].Y;
8119 maxY -= offsets[0].Y;
8120 minZ -= offsets[0].Z;
8121 maxZ -= offsets[0].Z;
8122
8123 LSL_Vector lower;
8124 LSL_Vector upper;
8125
8126 // Adjust to the documented error offsets (see LSL Wiki)
8127 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8128 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8129
8130 if (lower.x > upper.x)
8131 lower.x = upper.x;
8132 if (lower.y > upper.y)
8133 lower.y = upper.y;
8134 if (lower.z > upper.z)
8135 lower.z = upper.z;
8136
7545 result.Add(lower); 8137 result.Add(lower);
7546 result.Add(upper); 8138 result.Add(upper);
7547 return result; 8139 return result;
@@ -7621,13 +8213,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7621 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8213 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7622 part.AbsolutePosition.Y, 8214 part.AbsolutePosition.Y,
7623 part.AbsolutePosition.Z); 8215 part.AbsolutePosition.Z);
7624 // For some reason, the part.AbsolutePosition.* values do not change if the
7625 // linkset is rotated; they always reflect the child prim's world position
7626 // as though the linkset is unrotated. This is incompatible behavior with SL's
7627 // implementation, so will break scripts imported from there (not to mention it
7628 // makes it more difficult to determine a child prim's actual inworld position).
7629 if (part.ParentID != 0)
7630 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7631 res.Add(v); 8216 res.Add(v);
7632 break; 8217 break;
7633 8218
@@ -7788,56 +8373,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7788 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8373 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7789 if (remain < 1) 8374 if (remain < 1)
7790 return res; 8375 return res;
7791 8376 face = (int)rules.GetLSLIntegerItem(idx++);
7792 face=(int)rules.GetLSLIntegerItem(idx++);
7793 8377
7794 tex = part.Shape.Textures; 8378 tex = part.Shape.Textures;
8379 int shiny;
7795 if (face == ScriptBaseClass.ALL_SIDES) 8380 if (face == ScriptBaseClass.ALL_SIDES)
7796 { 8381 {
7797 for (face = 0; face < GetNumberOfSides(part); face++) 8382 for (face = 0; face < GetNumberOfSides(part); face++)
7798 { 8383 {
7799 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8384 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7800 // Convert Shininess to PRIM_SHINY_* 8385 if (shinyness == Shininess.High)
7801 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8386 {
7802 // PRIM_BUMP_* 8387 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7803 res.Add(new LSL_Integer((int)texface.Bump)); 8388 }
8389 else if (shinyness == Shininess.Medium)
8390 {
8391 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8392 }
8393 else if (shinyness == Shininess.Low)
8394 {
8395 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8396 }
8397 else
8398 {
8399 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8400 }
8401 res.Add(new LSL_Integer(shiny));
8402 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7804 } 8403 }
7805 } 8404 }
7806 else 8405 else
7807 { 8406 {
7808 if (face >= 0 && face < GetNumberOfSides(part)) 8407 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8408 if (shinyness == Shininess.High)
7809 { 8409 {
7810 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8410 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7811 // Convert Shininess to PRIM_SHINY_* 8411 }
7812 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8412 else if (shinyness == Shininess.Medium)
7813 // PRIM_BUMP_* 8413 {
7814 res.Add(new LSL_Integer((int)texface.Bump)); 8414 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8415 }
8416 else if (shinyness == Shininess.Low)
8417 {
8418 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8419 }
8420 else
8421 {
8422 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7815 } 8423 }
8424 res.Add(new LSL_Integer(shiny));
8425 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7816 } 8426 }
7817 break; 8427 break;
7818 8428
7819 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8429 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7820 if (remain < 1) 8430 if (remain < 1)
7821 return res; 8431 return res;
7822 8432 face = (int)rules.GetLSLIntegerItem(idx++);
7823 face=(int)rules.GetLSLIntegerItem(idx++);
7824 8433
7825 tex = part.Shape.Textures; 8434 tex = part.Shape.Textures;
8435 int fullbright;
7826 if (face == ScriptBaseClass.ALL_SIDES) 8436 if (face == ScriptBaseClass.ALL_SIDES)
7827 { 8437 {
7828 for (face = 0; face < GetNumberOfSides(part); face++) 8438 for (face = 0; face < GetNumberOfSides(part); face++)
7829 { 8439 {
7830 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8440 if (tex.GetFace((uint)face).Fullbright == true)
7831 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8441 {
8442 fullbright = ScriptBaseClass.TRUE;
8443 }
8444 else
8445 {
8446 fullbright = ScriptBaseClass.FALSE;
8447 }
8448 res.Add(new LSL_Integer(fullbright));
7832 } 8449 }
7833 } 8450 }
7834 else 8451 else
7835 { 8452 {
7836 if (face >= 0 && face < GetNumberOfSides(part)) 8453 if (tex.GetFace((uint)face).Fullbright == true)
7837 { 8454 {
7838 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8455 fullbright = ScriptBaseClass.TRUE;
7839 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8456 }
8457 else
8458 {
8459 fullbright = ScriptBaseClass.FALSE;
7840 } 8460 }
8461 res.Add(new LSL_Integer(fullbright));
7841 } 8462 }
7842 break; 8463 break;
7843 8464
@@ -7859,27 +8480,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7859 break; 8480 break;
7860 8481
7861 case (int)ScriptBaseClass.PRIM_TEXGEN: 8482 case (int)ScriptBaseClass.PRIM_TEXGEN:
8483 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7862 if (remain < 1) 8484 if (remain < 1)
7863 return res; 8485 return res;
7864 8486 face = (int)rules.GetLSLIntegerItem(idx++);
7865 face=(int)rules.GetLSLIntegerItem(idx++);
7866 8487
7867 tex = part.Shape.Textures; 8488 tex = part.Shape.Textures;
7868 if (face == ScriptBaseClass.ALL_SIDES) 8489 if (face == ScriptBaseClass.ALL_SIDES)
7869 { 8490 {
7870 for (face = 0; face < GetNumberOfSides(part); face++) 8491 for (face = 0; face < GetNumberOfSides(part); face++)
7871 { 8492 {
7872 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8493 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7873 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8494 {
7874 res.Add(new LSL_Integer((uint)texgen >> 1)); 8495 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8496 }
8497 else
8498 {
8499 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8500 }
7875 } 8501 }
7876 } 8502 }
7877 else 8503 else
7878 { 8504 {
7879 if (face >= 0 && face < GetNumberOfSides(part)) 8505 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8506 {
8507 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8508 }
8509 else
7880 { 8510 {
7881 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8511 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7882 res.Add(new LSL_Integer((uint)texgen >> 1));
7883 } 8512 }
7884 } 8513 }
7885 break; 8514 break;
@@ -7902,28 +8531,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7902 case (int)ScriptBaseClass.PRIM_GLOW: 8531 case (int)ScriptBaseClass.PRIM_GLOW:
7903 if (remain < 1) 8532 if (remain < 1)
7904 return res; 8533 return res;
7905 8534 face = (int)rules.GetLSLIntegerItem(idx++);
7906 face=(int)rules.GetLSLIntegerItem(idx++);
7907 8535
7908 tex = part.Shape.Textures; 8536 tex = part.Shape.Textures;
8537 float primglow;
7909 if (face == ScriptBaseClass.ALL_SIDES) 8538 if (face == ScriptBaseClass.ALL_SIDES)
7910 { 8539 {
7911 for (face = 0; face < GetNumberOfSides(part); face++) 8540 for (face = 0; face < GetNumberOfSides(part); face++)
7912 { 8541 {
7913 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8542 primglow = tex.GetFace((uint)face).Glow;
7914 res.Add(new LSL_Float(texface.Glow)); 8543 res.Add(new LSL_Float(primglow));
7915 } 8544 }
7916 } 8545 }
7917 else 8546 else
7918 { 8547 {
7919 if (face >= 0 && face < GetNumberOfSides(part)) 8548 primglow = tex.GetFace((uint)face).Glow;
7920 { 8549 res.Add(new LSL_Float(primglow));
7921 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7922 res.Add(new LSL_Float(texface.Glow));
7923 }
7924 } 8550 }
7925 break; 8551 break;
7926
7927 case (int)ScriptBaseClass.PRIM_TEXT: 8552 case (int)ScriptBaseClass.PRIM_TEXT:
7928 Color4 textColor = part.GetTextColor(); 8553 Color4 textColor = part.GetTextColor();
7929 res.Add(part.Text); 8554 res.Add(part.Text);
@@ -8472,8 +9097,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8472 // The function returns an ordered list 9097 // The function returns an ordered list
8473 // representing the tokens found in the supplied 9098 // representing the tokens found in the supplied
8474 // sources string. If two successive tokenizers 9099 // sources string. If two successive tokenizers
8475 // are encountered, then a NULL entry is added 9100 // are encountered, then a null-string entry is
8476 // to the list. 9101 // added to the list.
8477 // 9102 //
8478 // It is a precondition that the source and 9103 // It is a precondition that the source and
8479 // toekizer lisst are non-null. If they are null, 9104 // toekizer lisst are non-null. If they are null,
@@ -8481,7 +9106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8481 // while their lengths are being determined. 9106 // while their lengths are being determined.
8482 // 9107 //
8483 // A small amount of working memoryis required 9108 // A small amount of working memoryis required
8484 // of approximately 8*#tokenizers. 9109 // of approximately 8*#tokenizers + 8*srcstrlen.
8485 // 9110 //
8486 // There are many ways in which this function 9111 // There are many ways in which this function
8487 // can be implemented, this implementation is 9112 // can be implemented, this implementation is
@@ -8497,155 +9122,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8497 // and eliminates redundant tokenizers as soon 9122 // and eliminates redundant tokenizers as soon
8498 // as is possible. 9123 // as is possible.
8499 // 9124 //
8500 // The implementation tries to avoid any copying 9125 // The implementation tries to minimize temporary
8501 // of arrays or other objects. 9126 // garbage generation.
8502 // </remarks> 9127 // </remarks>
8503 9128
8504 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9129 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8505 { 9130 {
8506 int beginning = 0; 9131 return ParseString2List(src, separators, spacers, true);
8507 int srclen = src.Length; 9132 }
8508 int seplen = separators.Length;
8509 object[] separray = separators.Data;
8510 int spclen = spacers.Length;
8511 object[] spcarray = spacers.Data;
8512 int mlen = seplen+spclen;
8513
8514 int[] offset = new int[mlen+1];
8515 bool[] active = new bool[mlen];
8516
8517 int best;
8518 int j;
8519
8520 // Initial capacity reduces resize cost
8521 9133
8522 LSL_List tokens = new LSL_List(); 9134 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9135 {
9136 int srclen = src.Length;
9137 int seplen = separators.Length;
9138 object[] separray = separators.Data;
9139 int spclen = spacers.Length;
9140 object[] spcarray = spacers.Data;
9141 int dellen = 0;
9142 string[] delarray = new string[seplen+spclen];
8523 9143
8524 // All entries are initially valid 9144 int outlen = 0;
9145 string[] outarray = new string[srclen*2+1];
8525 9146
8526 for (int i = 0; i < mlen; i++) 9147 int i, j;
8527 active[i] = true; 9148 string d;
8528 9149
8529 offset[mlen] = srclen; 9150 m_host.AddScriptLPS(1);
8530 9151
8531 while (beginning < srclen) 9152 /*
9153 * Convert separator and spacer lists to C# strings.
9154 * Also filter out null strings so we don't hang.
9155 */
9156 for (i = 0; i < seplen; i ++)
8532 { 9157 {
9158 d = separray[i].ToString();
9159 if (d.Length > 0)
9160 {
9161 delarray[dellen++] = d;
9162 }
9163 }
9164 seplen = dellen;
8533 9165
8534 best = mlen; // as bad as it gets 9166 for (i = 0; i < spclen; i ++)
9167 {
9168 d = spcarray[i].ToString();
9169 if (d.Length > 0)
9170 {
9171 delarray[dellen++] = d;
9172 }
9173 }
8535 9174
8536 // Scan for separators 9175 /*
9176 * Scan through source string from beginning to end.
9177 */
9178 for (i = 0;;)
9179 {
8537 9180
8538 for (j = 0; j < seplen; j++) 9181 /*
9182 * Find earliest delimeter in src starting at i (if any).
9183 */
9184 int earliestDel = -1;
9185 int earliestSrc = srclen;
9186 string earliestStr = null;
9187 for (j = 0; j < dellen; j ++)
8539 { 9188 {
8540 if (separray[j].ToString() == String.Empty) 9189 d = delarray[j];
8541 active[j] = false; 9190 if (d != null)
8542
8543 if (active[j])
8544 { 9191 {
8545 // scan all of the markers 9192 int index = src.IndexOf(d, i);
8546 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9193 if (index < 0)
8547 { 9194 {
8548 // not present at all 9195 delarray[j] = null; // delim nowhere in src, don't check it anymore
8549 active[j] = false;
8550 } 9196 }
8551 else 9197 else if (index < earliestSrc)
8552 { 9198 {
8553 // present and correct 9199 earliestSrc = index; // where delimeter starts in source string
8554 if (offset[j] < offset[best]) 9200 earliestDel = j; // where delimeter is in delarray[]
8555 { 9201 earliestStr = d; // the delimeter string from delarray[]
8556 // closest so far 9202 if (index == i) break; // can't do any better than found at beg of string
8557 best = j;
8558 if (offset[best] == beginning)
8559 break;
8560 }
8561 } 9203 }
8562 } 9204 }
8563 } 9205 }
8564 9206
8565 // Scan for spacers 9207 /*
8566 9208 * Output source string starting at i through start of earliest delimeter.
8567 if (offset[best] != beginning) 9209 */
9210 if (keepNulls || (earliestSrc > i))
8568 { 9211 {
8569 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9212 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8570 {
8571 if (spcarray[j-seplen].ToString() == String.Empty)
8572 active[j] = false;
8573
8574 if (active[j])
8575 {
8576 // scan all of the markers
8577 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8578 {
8579 // not present at all
8580 active[j] = false;
8581 }
8582 else
8583 {
8584 // present and correct
8585 if (offset[j] < offset[best])
8586 {
8587 // closest so far
8588 best = j;
8589 }
8590 }
8591 }
8592 }
8593 } 9213 }
8594 9214
8595 // This is the normal exit from the scanning loop 9215 /*
9216 * If no delimeter found at or after i, we're done scanning.
9217 */
9218 if (earliestDel < 0) break;
8596 9219
8597 if (best == mlen) 9220 /*
9221 * If delimeter was a spacer, output the spacer.
9222 */
9223 if (earliestDel >= seplen)
8598 { 9224 {
8599 // no markers were found on this pass 9225 outarray[outlen++] = earliestStr;
8600 // so we're pretty much done
8601 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8602 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8603 break;
8604 } 9226 }
8605 9227
8606 // Otherwise we just add the newly delimited token 9228 /*
8607 // and recalculate where the search should continue. 9229 * Look at rest of src string following delimeter.
8608 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9230 */
8609 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9231 i = earliestSrc + earliestStr.Length;
8610
8611 if (best < seplen)
8612 {
8613 beginning = offset[best] + (separray[best].ToString()).Length;
8614 }
8615 else
8616 {
8617 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8618 string str = spcarray[best - seplen].ToString();
8619 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8620 tokens.Add(new LSL_String(str));
8621 }
8622 } 9232 }
8623 9233
8624 // This an awkward an not very intuitive boundary case. If the 9234 /*
8625 // last substring is a tokenizer, then there is an implied trailing 9235 * Make up an exact-sized output array suitable for an LSL_List object.
8626 // null list entry. Hopefully the single comparison will not be too 9236 */
8627 // arduous. Alternatively the 'break' could be replced with a return 9237 object[] outlist = new object[outlen];
8628 // but that's shabby programming. 9238 for (i = 0; i < outlen; i ++)
8629
8630 if ((beginning == srclen) && (keepNulls))
8631 { 9239 {
8632 if (srclen != 0) 9240 outlist[i] = new LSL_String(outarray[i]);
8633 tokens.Add(new LSL_String(""));
8634 } 9241 }
8635 9242 return new LSL_List(outlist);
8636 return tokens;
8637 }
8638
8639 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8640 {
8641 m_host.AddScriptLPS(1);
8642 return this.ParseString(src, separators, spacers, false);
8643 }
8644
8645 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8646 {
8647 m_host.AddScriptLPS(1);
8648 return this.ParseString(src, separators, spacers, true);
8649 } 9243 }
8650 9244
8651 public LSL_Integer llGetObjectPermMask(int mask) 9245 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8722,28 +9316,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8722 { 9316 {
8723 m_host.AddScriptLPS(1); 9317 m_host.AddScriptLPS(1);
8724 9318
8725 lock (m_host.TaskInventory) 9319 m_host.TaskInventory.LockItemsForRead(true);
9320 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8726 { 9321 {
8727 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9322 if (inv.Value.Name == item)
8728 { 9323 {
8729 if (inv.Value.Name == item) 9324 m_host.TaskInventory.LockItemsForRead(false);
9325 switch (mask)
8730 { 9326 {
8731 switch (mask) 9327 case 0:
8732 { 9328 return (int)inv.Value.BasePermissions;
8733 case 0: 9329 case 1:
8734 return (int)inv.Value.BasePermissions; 9330 return (int)inv.Value.CurrentPermissions;
8735 case 1: 9331 case 2:
8736 return (int)inv.Value.CurrentPermissions; 9332 return (int)inv.Value.GroupPermissions;
8737 case 2: 9333 case 3:
8738 return (int)inv.Value.GroupPermissions; 9334 return (int)inv.Value.EveryonePermissions;
8739 case 3: 9335 case 4:
8740 return (int)inv.Value.EveryonePermissions; 9336 return (int)inv.Value.NextPermissions;
8741 case 4:
8742 return (int)inv.Value.NextPermissions;
8743 }
8744 } 9337 }
8745 } 9338 }
8746 } 9339 }
9340 m_host.TaskInventory.LockItemsForRead(false);
8747 9341
8748 return -1; 9342 return -1;
8749 } 9343 }
@@ -8790,16 +9384,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8790 { 9384 {
8791 m_host.AddScriptLPS(1); 9385 m_host.AddScriptLPS(1);
8792 9386
8793 lock (m_host.TaskInventory) 9387 m_host.TaskInventory.LockItemsForRead(true);
9388 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8794 { 9389 {
8795 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9390 if (inv.Value.Name == item)
8796 { 9391 {
8797 if (inv.Value.Name == item) 9392 m_host.TaskInventory.LockItemsForRead(false);
8798 { 9393 return inv.Value.CreatorID.ToString();
8799 return inv.Value.CreatorID.ToString();
8800 }
8801 } 9394 }
8802 } 9395 }
9396 m_host.TaskInventory.LockItemsForRead(false);
8803 9397
8804 llSay(0, "No item name '" + item + "'"); 9398 llSay(0, "No item name '" + item + "'");
8805 9399
@@ -8947,7 +9541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8947 } 9541 }
8948 9542
8949 /// <summary> 9543 /// <summary>
8950 /// illListReplaceList removes the sub-list defined by the inclusive indices 9544 /// llListReplaceList removes the sub-list defined by the inclusive indices
8951 /// start and end and inserts the src list in its place. The inclusive 9545 /// start and end and inserts the src list in its place. The inclusive
8952 /// nature of the indices means that at least one element must be deleted 9546 /// nature of the indices means that at least one element must be deleted
8953 /// if the indices are within the bounds of the existing list. I.e. 2,2 9547 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9004,16 +9598,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9004 // based upon end. Note that if end exceeds the upper 9598 // based upon end. Note that if end exceeds the upper
9005 // bound in this case, the entire destination list 9599 // bound in this case, the entire destination list
9006 // is removed. 9600 // is removed.
9007 else 9601 else if (start == 0)
9008 { 9602 {
9009 if (end + 1 < dest.Length) 9603 if (end + 1 < dest.Length)
9010 {
9011 return src + dest.GetSublist(end + 1, -1); 9604 return src + dest.GetSublist(end + 1, -1);
9012 }
9013 else 9605 else
9014 {
9015 return src; 9606 return src;
9016 } 9607 }
9608 else // Start < 0
9609 {
9610 if (end + 1 < dest.Length)
9611 return dest.GetSublist(end + 1, -1);
9612 else
9613 return new LSL_List();
9017 } 9614 }
9018 } 9615 }
9019 // Finally, if start > end, we strip away a prefix and 9616 // Finally, if start > end, we strip away a prefix and
@@ -9064,17 +9661,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9064 int width = 0; 9661 int width = 0;
9065 int height = 0; 9662 int height = 0;
9066 9663
9067 ParcelMediaCommandEnum? commandToSend = null; 9664 uint commandToSend = 0;
9068 float time = 0.0f; // default is from start 9665 float time = 0.0f; // default is from start
9069 9666
9070 ScenePresence presence = null; 9667 ScenePresence presence = null;
9071 9668
9072 for (int i = 0; i < commandList.Data.Length; i++) 9669 for (int i = 0; i < commandList.Data.Length; i++)
9073 { 9670 {
9074 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9671 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9075 switch (command) 9672 switch (command)
9076 { 9673 {
9077 case ParcelMediaCommandEnum.Agent: 9674 case (uint)ParcelMediaCommandEnum.Agent:
9078 // we send only to one agent 9675 // we send only to one agent
9079 if ((i + 1) < commandList.Length) 9676 if ((i + 1) < commandList.Length)
9080 { 9677 {
@@ -9091,25 +9688,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9091 } 9688 }
9092 break; 9689 break;
9093 9690
9094 case ParcelMediaCommandEnum.Loop: 9691 case (uint)ParcelMediaCommandEnum.Loop:
9095 loop = 1; 9692 loop = 1;
9096 commandToSend = command; 9693 commandToSend = command;
9097 update = true; //need to send the media update packet to set looping 9694 update = true; //need to send the media update packet to set looping
9098 break; 9695 break;
9099 9696
9100 case ParcelMediaCommandEnum.Play: 9697 case (uint)ParcelMediaCommandEnum.Play:
9101 loop = 0; 9698 loop = 0;
9102 commandToSend = command; 9699 commandToSend = command;
9103 update = true; //need to send the media update packet to make sure it doesn't loop 9700 update = true; //need to send the media update packet to make sure it doesn't loop
9104 break; 9701 break;
9105 9702
9106 case ParcelMediaCommandEnum.Pause: 9703 case (uint)ParcelMediaCommandEnum.Pause:
9107 case ParcelMediaCommandEnum.Stop: 9704 case (uint)ParcelMediaCommandEnum.Stop:
9108 case ParcelMediaCommandEnum.Unload: 9705 case (uint)ParcelMediaCommandEnum.Unload:
9109 commandToSend = command; 9706 commandToSend = command;
9110 break; 9707 break;
9111 9708
9112 case ParcelMediaCommandEnum.Url: 9709 case (uint)ParcelMediaCommandEnum.Url:
9113 if ((i + 1) < commandList.Length) 9710 if ((i + 1) < commandList.Length)
9114 { 9711 {
9115 if (commandList.Data[i + 1] is LSL_String) 9712 if (commandList.Data[i + 1] is LSL_String)
@@ -9122,7 +9719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9122 } 9719 }
9123 break; 9720 break;
9124 9721
9125 case ParcelMediaCommandEnum.Texture: 9722 case (uint)ParcelMediaCommandEnum.Texture:
9126 if ((i + 1) < commandList.Length) 9723 if ((i + 1) < commandList.Length)
9127 { 9724 {
9128 if (commandList.Data[i + 1] is LSL_String) 9725 if (commandList.Data[i + 1] is LSL_String)
@@ -9135,7 +9732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9135 } 9732 }
9136 break; 9733 break;
9137 9734
9138 case ParcelMediaCommandEnum.Time: 9735 case (uint)ParcelMediaCommandEnum.Time:
9139 if ((i + 1) < commandList.Length) 9736 if ((i + 1) < commandList.Length)
9140 { 9737 {
9141 if (commandList.Data[i + 1] is LSL_Float) 9738 if (commandList.Data[i + 1] is LSL_Float)
@@ -9147,7 +9744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9147 } 9744 }
9148 break; 9745 break;
9149 9746
9150 case ParcelMediaCommandEnum.AutoAlign: 9747 case (uint)ParcelMediaCommandEnum.AutoAlign:
9151 if ((i + 1) < commandList.Length) 9748 if ((i + 1) < commandList.Length)
9152 { 9749 {
9153 if (commandList.Data[i + 1] is LSL_Integer) 9750 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9161,7 +9758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9161 } 9758 }
9162 break; 9759 break;
9163 9760
9164 case ParcelMediaCommandEnum.Type: 9761 case (uint)ParcelMediaCommandEnum.Type:
9165 if ((i + 1) < commandList.Length) 9762 if ((i + 1) < commandList.Length)
9166 { 9763 {
9167 if (commandList.Data[i + 1] is LSL_String) 9764 if (commandList.Data[i + 1] is LSL_String)
@@ -9174,7 +9771,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9174 } 9771 }
9175 break; 9772 break;
9176 9773
9177 case ParcelMediaCommandEnum.Desc: 9774 case (uint)ParcelMediaCommandEnum.Desc:
9178 if ((i + 1) < commandList.Length) 9775 if ((i + 1) < commandList.Length)
9179 { 9776 {
9180 if (commandList.Data[i + 1] is LSL_String) 9777 if (commandList.Data[i + 1] is LSL_String)
@@ -9187,7 +9784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9187 } 9784 }
9188 break; 9785 break;
9189 9786
9190 case ParcelMediaCommandEnum.Size: 9787 case (uint)ParcelMediaCommandEnum.Size:
9191 if ((i + 2) < commandList.Length) 9788 if ((i + 2) < commandList.Length)
9192 { 9789 {
9193 if (commandList.Data[i + 1] is LSL_Integer) 9790 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9257,7 +9854,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9257 } 9854 }
9258 } 9855 }
9259 9856
9260 if (commandToSend != null) 9857 if (commandToSend != 0)
9261 { 9858 {
9262 // the commandList contained a start/stop/... command, too 9859 // the commandList contained a start/stop/... command, too
9263 if (presence == null) 9860 if (presence == null)
@@ -9294,7 +9891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9294 9891
9295 if (aList.Data[i] != null) 9892 if (aList.Data[i] != null)
9296 { 9893 {
9297 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9894 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9298 { 9895 {
9299 case ParcelMediaCommandEnum.Url: 9896 case ParcelMediaCommandEnum.Url:
9300 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9897 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9337,16 +9934,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9337 { 9934 {
9338 m_host.AddScriptLPS(1); 9935 m_host.AddScriptLPS(1);
9339 9936
9340 lock (m_host.TaskInventory) 9937 m_host.TaskInventory.LockItemsForRead(true);
9938 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9341 { 9939 {
9342 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9940 if (inv.Value.Name == name)
9343 { 9941 {
9344 if (inv.Value.Name == name) 9942 m_host.TaskInventory.LockItemsForRead(false);
9345 { 9943 return inv.Value.Type;
9346 return inv.Value.Type;
9347 }
9348 } 9944 }
9349 } 9945 }
9946 m_host.TaskInventory.LockItemsForRead(false);
9350 9947
9351 return -1; 9948 return -1;
9352 } 9949 }
@@ -9357,15 +9954,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 9954
9358 if (quick_pay_buttons.Data.Length < 4) 9955 if (quick_pay_buttons.Data.Length < 4)
9359 { 9956 {
9360 LSLError("List must have at least 4 elements"); 9957 int x;
9361 return; 9958 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9959 {
9960 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9961 }
9362 } 9962 }
9363 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9963 int[] nPrice = new int[5];
9364 9964 nPrice[0] = price;
9365 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9965 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9366 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9966 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9367 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9967 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9368 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9968 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9969 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9369 m_host.ParentGroup.HasGroupChanged = true; 9970 m_host.ParentGroup.HasGroupChanged = true;
9370 } 9971 }
9371 9972
@@ -9377,17 +9978,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9377 if (invItemID == UUID.Zero) 9978 if (invItemID == UUID.Zero)
9378 return new LSL_Vector(); 9979 return new LSL_Vector();
9379 9980
9380 lock (m_host.TaskInventory) 9981 m_host.TaskInventory.LockItemsForRead(true);
9982 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9381 { 9983 {
9382 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9984 m_host.TaskInventory.LockItemsForRead(false);
9383 return new LSL_Vector(); 9985 return new LSL_Vector();
9986 }
9384 9987
9385 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9988 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9386 { 9989 {
9387 ShoutError("No permissions to track the camera"); 9990 ShoutError("No permissions to track the camera");
9388 return new LSL_Vector(); 9991 m_host.TaskInventory.LockItemsForRead(false);
9389 } 9992 return new LSL_Vector();
9390 } 9993 }
9994 m_host.TaskInventory.LockItemsForRead(false);
9391 9995
9392 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9996 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9393 if (presence != null) 9997 if (presence != null)
@@ -9405,17 +10009,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9405 if (invItemID == UUID.Zero) 10009 if (invItemID == UUID.Zero)
9406 return new LSL_Rotation(); 10010 return new LSL_Rotation();
9407 10011
9408 lock (m_host.TaskInventory) 10012 m_host.TaskInventory.LockItemsForRead(true);
10013 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9409 { 10014 {
9410 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10015 m_host.TaskInventory.LockItemsForRead(false);
9411 return new LSL_Rotation(); 10016 return new LSL_Rotation();
9412
9413 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9414 {
9415 ShoutError("No permissions to track the camera");
9416 return new LSL_Rotation();
9417 }
9418 } 10017 }
10018 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10019 {
10020 ShoutError("No permissions to track the camera");
10021 m_host.TaskInventory.LockItemsForRead(false);
10022 return new LSL_Rotation();
10023 }
10024 m_host.TaskInventory.LockItemsForRead(false);
9419 10025
9420 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10026 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9421 if (presence != null) 10027 if (presence != null)
@@ -9477,8 +10083,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 { 10083 {
9478 m_host.AddScriptLPS(1); 10084 m_host.AddScriptLPS(1);
9479 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10085 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9480 if (detectedParams == null) return; // only works on the first detected avatar 10086 if (detectedParams == null)
9481 10087 {
10088 if (m_host.IsAttachment == true)
10089 {
10090 detectedParams = new DetectParams();
10091 detectedParams.Key = m_host.OwnerID;
10092 }
10093 else
10094 {
10095 return;
10096 }
10097 }
10098
9482 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10099 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9483 if (avatar != null) 10100 if (avatar != null)
9484 { 10101 {
@@ -9486,6 +10103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9486 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10103 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9487 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10104 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9488 } 10105 }
10106
9489 ScriptSleep(1000); 10107 ScriptSleep(1000);
9490 } 10108 }
9491 10109
@@ -9578,14 +10196,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9578 if (objectID == UUID.Zero) return; 10196 if (objectID == UUID.Zero) return;
9579 10197
9580 UUID agentID; 10198 UUID agentID;
9581 lock (m_host.TaskInventory) 10199 m_host.TaskInventory.LockItemsForRead(true);
9582 { 10200 // we need the permission first, to know which avatar we want to set the camera for
9583 // we need the permission first, to know which avatar we want to set the camera for 10201 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9584 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9585 10202
9586 if (agentID == UUID.Zero) return; 10203 if (agentID == UUID.Zero)
9587 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10204 {
10205 m_host.TaskInventory.LockItemsForRead(false);
10206 return;
9588 } 10207 }
10208 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10209 {
10210 m_host.TaskInventory.LockItemsForRead(false);
10211 return;
10212 }
10213 m_host.TaskInventory.LockItemsForRead(false);
9589 10214
9590 ScenePresence presence = World.GetScenePresence(agentID); 10215 ScenePresence presence = World.GetScenePresence(agentID);
9591 10216
@@ -9594,12 +10219,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9594 10219
9595 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10220 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9596 object[] data = rules.Data; 10221 object[] data = rules.Data;
9597 for (int i = 0; i < data.Length; ++i) { 10222 for (int i = 0; i < data.Length; ++i)
10223 {
9598 int type = Convert.ToInt32(data[i++].ToString()); 10224 int type = Convert.ToInt32(data[i++].ToString());
9599 if (i >= data.Length) break; // odd number of entries => ignore the last 10225 if (i >= data.Length) break; // odd number of entries => ignore the last
9600 10226
9601 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10227 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9602 switch (type) { 10228 switch (type)
10229 {
9603 case ScriptBaseClass.CAMERA_FOCUS: 10230 case ScriptBaseClass.CAMERA_FOCUS:
9604 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10231 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9605 case ScriptBaseClass.CAMERA_POSITION: 10232 case ScriptBaseClass.CAMERA_POSITION:
@@ -9635,12 +10262,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9635 10262
9636 // we need the permission first, to know which avatar we want to clear the camera for 10263 // we need the permission first, to know which avatar we want to clear the camera for
9637 UUID agentID; 10264 UUID agentID;
9638 lock (m_host.TaskInventory) 10265 m_host.TaskInventory.LockItemsForRead(true);
10266 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10267 if (agentID == UUID.Zero)
9639 { 10268 {
9640 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10269 m_host.TaskInventory.LockItemsForRead(false);
9641 if (agentID == UUID.Zero) return; 10270 return;
9642 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9643 } 10271 }
10272 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10273 {
10274 m_host.TaskInventory.LockItemsForRead(false);
10275 return;
10276 }
10277 m_host.TaskInventory.LockItemsForRead(false);
9644 10278
9645 ScenePresence presence = World.GetScenePresence(agentID); 10279 ScenePresence presence = World.GetScenePresence(agentID);
9646 10280
@@ -9707,19 +10341,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9707 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10341 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9708 { 10342 {
9709 m_host.AddScriptLPS(1); 10343 m_host.AddScriptLPS(1);
9710 string ret = String.Empty; 10344
9711 string src1 = llBase64ToString(str1); 10345 if (str1 == String.Empty)
9712 string src2 = llBase64ToString(str2); 10346 return String.Empty;
9713 int c = 0; 10347 if (str2 == String.Empty)
9714 for (int i = 0; i < src1.Length; i++) 10348 return str1;
10349
10350 int len = str2.Length;
10351 if ((len % 4) != 0) // LL is EVIL!!!!
10352 {
10353 while (str2.EndsWith("="))
10354 str2 = str2.Substring(0, str2.Length - 1);
10355
10356 len = str2.Length;
10357 int mod = len % 4;
10358
10359 if (mod == 1)
10360 str2 = str2.Substring(0, str2.Length - 1);
10361 else if (mod == 2)
10362 str2 += "==";
10363 else if (mod == 3)
10364 str2 += "=";
10365 }
10366
10367 byte[] data1;
10368 byte[] data2;
10369 try
9715 { 10370 {
9716 ret += (char) (src1[i] ^ src2[c]); 10371 data1 = Convert.FromBase64String(str1);
10372 data2 = Convert.FromBase64String(str2);
10373 }
10374 catch (Exception)
10375 {
10376 return new LSL_String(String.Empty);
10377 }
10378
10379 byte[] d2 = new Byte[data1.Length];
10380 int pos = 0;
10381
10382 if (data1.Length <= data2.Length)
10383 {
10384 Array.Copy(data2, 0, d2, 0, data1.Length);
10385 }
10386 else
10387 {
10388 while (pos < data1.Length)
10389 {
10390 len = data1.Length - pos;
10391 if (len > data2.Length)
10392 len = data2.Length;
9717 10393
9718 c++; 10394 Array.Copy(data2, 0, d2, pos, len);
9719 if (c >= src2.Length) 10395 pos += len;
9720 c = 0; 10396 }
9721 } 10397 }
9722 return llStringToBase64(ret); 10398
10399 for (pos = 0 ; pos < data1.Length ; pos++ )
10400 data1[pos] ^= d2[pos];
10401
10402 return Convert.ToBase64String(data1);
9723 } 10403 }
9724 10404
9725 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10405 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9778,12 +10458,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9778 Regex r = new Regex(authregex); 10458 Regex r = new Regex(authregex);
9779 int[] gnums = r.GetGroupNumbers(); 10459 int[] gnums = r.GetGroupNumbers();
9780 Match m = r.Match(url); 10460 Match m = r.Match(url);
9781 if (m.Success) { 10461 if (m.Success)
9782 for (int i = 1; i < gnums.Length; i++) { 10462 {
10463 for (int i = 1; i < gnums.Length; i++)
10464 {
9783 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10465 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9784 //CaptureCollection cc = g.Captures; 10466 //CaptureCollection cc = g.Captures;
9785 } 10467 }
9786 if (m.Groups.Count == 5) { 10468 if (m.Groups.Count == 5)
10469 {
9787 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10470 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9788 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10471 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9789 } 10472 }
@@ -9895,7 +10578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9895 { 10578 {
9896 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10579 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9897 { 10580 {
9898 ret.Add(detectedParams.Key.ToString()); 10581 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9899 ret.Add(detectedParams.Value); 10582 ret.Add(detectedParams.Value);
9900 } 10583 }
9901 } 10584 }
@@ -10064,15 +10747,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10064 10747
10065 internal UUID ScriptByName(string name) 10748 internal UUID ScriptByName(string name)
10066 { 10749 {
10067 lock (m_host.TaskInventory) 10750 m_host.TaskInventory.LockItemsForRead(true);
10751
10752 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10068 { 10753 {
10069 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10754 if (item.Type == 10 && item.Name == name)
10070 { 10755 {
10071 if (item.Type == 10 && item.Name == name) 10756 m_host.TaskInventory.LockItemsForRead(false);
10072 return item.ItemID; 10757 return item.ItemID;
10073 } 10758 }
10074 } 10759 }
10075 10760
10761 m_host.TaskInventory.LockItemsForRead(false);
10762
10076 return UUID.Zero; 10763 return UUID.Zero;
10077 } 10764 }
10078 10765
@@ -10113,6 +10800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10113 { 10800 {
10114 m_host.AddScriptLPS(1); 10801 m_host.AddScriptLPS(1);
10115 10802
10803 //Clone is thread safe
10116 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10804 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10117 10805
10118 UUID assetID = UUID.Zero; 10806 UUID assetID = UUID.Zero;
@@ -10175,6 +10863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10175 { 10863 {
10176 m_host.AddScriptLPS(1); 10864 m_host.AddScriptLPS(1);
10177 10865
10866 //Clone is thread safe
10178 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10867 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10179 10868
10180 UUID assetID = UUID.Zero; 10869 UUID assetID = UUID.Zero;
@@ -10255,15 +10944,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10255 return GetLinkPrimitiveParams(obj, rules); 10944 return GetLinkPrimitiveParams(obj, rules);
10256 } 10945 }
10257 10946
10258 public void print(string str) 10947 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10259 { 10948 {
10260 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10949 List<SceneObjectPart> parts = GetLinkParts(link);
10261 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10950 if (parts.Count < 1)
10262 if (ossl != null) 10951 return 0;
10263 { 10952
10264 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10953 return GetNumberOfSides(parts[0]);
10265 m_log.Info("LSL print():" + str);
10266 }
10267 } 10954 }
10268 10955
10269 private string Name2Username(string name) 10956 private string Name2Username(string name)
@@ -10309,6 +10996,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10309 return rq.ToString(); 10996 return rq.ToString();
10310 } 10997 }
10311 10998
10999 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11000 {
11001 m_SayShoutCount = 0;
11002 }
11003
10312 #region Not Implemented 11004 #region Not Implemented
10313 // 11005 //
10314 // Listing the unimplemented lsl functions here, please move 11006 // Listing the unimplemented lsl functions here, please move
@@ -10335,11 +11027,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10335 11027
10336 } 11028 }
10337 11029
10338 public void llGetUsedMemory() 11030 public virtual LSL_Integer llGetUsedMemory()
10339 { 11031 {
10340 m_host.AddScriptLPS(1); 11032 m_host.AddScriptLPS(1);
10341 NotImplemented("llGetUsedMemory"); 11033 NotImplemented("llGetUsedMemory");
10342 11034 return 0;
10343 } 11035 }
10344 11036
10345 public void llRegionSayTo( LSL_Key target, LSL_Integer channel, LSL_String msg ) 11037 public void llRegionSayTo( LSL_Key target, LSL_Integer channel, LSL_String msg )
@@ -10352,14 +11044,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10352 public void llScriptProfiler( LSL_Integer flags ) 11044 public void llScriptProfiler( LSL_Integer flags )
10353 { 11045 {
10354 m_host.AddScriptLPS(1); 11046 m_host.AddScriptLPS(1);
10355 NotImplemented("llScriptProfiler"); 11047 //NotImplemented("llScriptProfiler");
10356 11048
10357 } 11049 }
10358 11050
10359 public void llSetSoundQueueing(int queue) 11051 public void llSetSoundQueueing(int queue)
10360 { 11052 {
10361 m_host.AddScriptLPS(1); 11053 m_host.AddScriptLPS(1);
10362 NotImplemented("llSetSoundQueueing");
10363 } 11054 }
10364 11055
10365 public void llCollisionSprite(string impact_sprite) 11056 public void llCollisionSprite(string impact_sprite)
@@ -10371,7 +11062,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10371 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11062 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10372 { 11063 {
10373 m_host.AddScriptLPS(1); 11064 m_host.AddScriptLPS(1);
10374 NotImplemented("llGodLikeRezObject"); 11065
11066 if (!World.Permissions.IsGod(m_host.OwnerID))
11067 NotImplemented("llGodLikeRezObject");
11068
11069 AssetBase rezAsset = World.AssetService.Get(inventory);
11070 if (rezAsset == null)
11071 {
11072 llSay(0, "Asset not found");
11073 return;
11074 }
11075
11076 SceneObjectGroup group = null;
11077
11078 try
11079 {
11080 string xmlData = Utils.BytesToString(rezAsset.Data);
11081 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11082 }
11083 catch
11084 {
11085 llSay(0, "Asset not found");
11086 return;
11087 }
11088
11089 if (group == null)
11090 {
11091 llSay(0, "Asset not found");
11092 return;
11093 }
11094
11095 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11096 group.RootPart.AttachOffset = group.AbsolutePosition;
11097
11098 group.ResetIDs();
11099
11100 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11101 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11102 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11103 group.ScheduleGroupForFullUpdate();
11104
11105 // objects rezzed with this method are die_at_edge by default.
11106 group.RootPart.SetDieAtEdge(true);
11107
11108 group.ResumeScripts();
11109
11110 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11111 "object_rez", new Object[] {
11112 new LSL_String(
11113 group.RootPart.UUID.ToString()) },
11114 new DetectParams[0]));
10375 } 11115 }
10376 11116
10377 #endregion 11117 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 963727d..2b8155f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -831,18 +840,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
831 if (target != null) 840 if (target != null)
832 { 841 {
833 UUID animID=UUID.Zero; 842 UUID animID=UUID.Zero;
834 lock (m_host.TaskInventory) 843 m_host.TaskInventory.LockItemsForRead(true);
844 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
835 { 845 {
836 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 846 if (inv.Value.Name == animation)
837 { 847 {
838 if (inv.Value.Name == animation) 848 if (inv.Value.Type == (int)AssetType.Animation)
839 { 849 animID = inv.Value.AssetID;
840 if (inv.Value.Type == (int)AssetType.Animation) 850 continue;
841 animID = inv.Value.AssetID;
842 continue;
843 }
844 } 851 }
845 } 852 }
853 m_host.TaskInventory.LockItemsForRead(false);
846 if (animID == UUID.Zero) 854 if (animID == UUID.Zero)
847 target.Animator.AddAnimation(animation, m_host.UUID); 855 target.Animator.AddAnimation(animation, m_host.UUID);
848 else 856 else
@@ -864,18 +872,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
864 if (target != null) 872 if (target != null)
865 { 873 {
866 UUID animID=UUID.Zero; 874 UUID animID=UUID.Zero;
867 lock (m_host.TaskInventory) 875 m_host.TaskInventory.LockItemsForRead(true);
876 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
868 { 877 {
869 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 878 if (inv.Value.Name == animation)
870 { 879 {
871 if (inv.Value.Name == animation) 880 if (inv.Value.Type == (int)AssetType.Animation)
872 { 881 animID = inv.Value.AssetID;
873 if (inv.Value.Type == (int)AssetType.Animation) 882 continue;
874 animID = inv.Value.AssetID;
875 continue;
876 }
877 } 883 }
878 } 884 }
885 m_host.TaskInventory.LockItemsForRead(false);
879 886
880 if (animID == UUID.Zero) 887 if (animID == UUID.Zero)
881 target.Animator.RemoveAnimation(animation); 888 target.Animator.RemoveAnimation(animation);
@@ -1768,6 +1775,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1768 1775
1769 if (!UUID.TryParse(name, out assetID)) 1776 if (!UUID.TryParse(name, out assetID))
1770 { 1777 {
1778 m_host.TaskInventory.LockItemsForRead(true);
1771 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1779 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1772 { 1780 {
1773 if (item.Type == 7 && item.Name == name) 1781 if (item.Type == 7 && item.Name == name)
@@ -1775,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1775 assetID = item.AssetID; 1783 assetID = item.AssetID;
1776 } 1784 }
1777 } 1785 }
1786 m_host.TaskInventory.LockItemsForRead(false);
1778 } 1787 }
1779 1788
1780 if (assetID == UUID.Zero) 1789 if (assetID == UUID.Zero)
@@ -1821,6 +1830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 1830
1822 if (!UUID.TryParse(name, out assetID)) 1831 if (!UUID.TryParse(name, out assetID))
1823 { 1832 {
1833 m_host.TaskInventory.LockItemsForRead(true);
1824 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1834 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1825 { 1835 {
1826 if (item.Type == 7 && item.Name == name) 1836 if (item.Type == 7 && item.Name == name)
@@ -1828,6 +1838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 assetID = item.AssetID; 1838 assetID = item.AssetID;
1829 } 1839 }
1830 } 1840 }
1841 m_host.TaskInventory.LockItemsForRead(false);
1831 } 1842 }
1832 1843
1833 if (assetID == UUID.Zero) 1844 if (assetID == UUID.Zero)
@@ -1878,6 +1889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1878 1889
1879 if (!UUID.TryParse(name, out assetID)) 1890 if (!UUID.TryParse(name, out assetID))
1880 { 1891 {
1892 m_host.TaskInventory.LockItemsForRead(true);
1881 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1893 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1882 { 1894 {
1883 if (item.Type == 7 && item.Name == name) 1895 if (item.Type == 7 && item.Name == name)
@@ -1885,6 +1897,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 assetID = item.AssetID; 1897 assetID = item.AssetID;
1886 } 1898 }
1887 } 1899 }
1900 m_host.TaskInventory.LockItemsForRead(false);
1888 } 1901 }
1889 1902
1890 if (assetID == UUID.Zero) 1903 if (assetID == UUID.Zero)
@@ -2366,9 +2379,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2366 { 2379 {
2367 if (avatar.IsChildAgent == false) 2380 if (avatar.IsChildAgent == false)
2368 { 2381 {
2369 result.Add(avatar.UUID); 2382 result.Add(new LSL_Key(avatar.UUID.ToString()));
2370 result.Add(avatar.AbsolutePosition); 2383 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2371 result.Add(avatar.Name); 2384 result.Add(new LSL_String(avatar.Name));
2372 } 2385 }
2373 } 2386 }
2374 }); 2387 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index e53a61a..d695a0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.RootPart.IsAttachment) 307 if (SensePoint.ParentGroup.RootPart.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -428,7 +430,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
428 // In attachments, the sensor cone always orients with the 430 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
433
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 434 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
435 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 436 q = avatar.Rotation;
433 } 437 }
434 438
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 654ea81..ce13d6b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -121,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
121 LSL_Float llGetEnergy(); 121 LSL_Float llGetEnergy();
122 LSL_Vector llGetForce(); 122 LSL_Vector llGetForce();
123 LSL_Integer llGetFreeMemory(); 123 LSL_Integer llGetFreeMemory();
124 LSL_Integer llGetUsedMemory();
124 LSL_Integer llGetFreeURLs(); 125 LSL_Integer llGetFreeURLs();
125 LSL_Vector llGetGeometricCenter(); 126 LSL_Vector llGetGeometricCenter();
126 LSL_Float llGetGMTclock(); 127 LSL_Float llGetGMTclock();
@@ -402,7 +403,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
402 LSL_Vector llWind(LSL_Vector offset); 403 LSL_Vector llWind(LSL_Vector offset);
403 LSL_String llXorBase64Strings(string str1, string str2); 404 LSL_String llXorBase64Strings(string str1, string str2);
404 LSL_String llXorBase64StringsCorrect(string str1, string str2); 405 LSL_String llXorBase64StringsCorrect(string str1, string str2);
405 void print(string str); 406 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
406 407
407 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 408 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
408 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 409 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 19352f0..5a809e6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 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 9377cda..5f94ff5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 303d75e..7d7e54e 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;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
@@ -459,6 +461,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
459 return m_LSL_Functions.llGetFreeMemory(); 461 return m_LSL_Functions.llGetFreeMemory();
460 } 462 }
461 463
464 public LSL_Integer llGetUsedMemory()
465 {
466 return m_LSL_Functions.llGetUsedMemory();
467 }
468
462 public LSL_Integer llGetFreeURLs() 469 public LSL_Integer llGetFreeURLs()
463 { 470 {
464 return m_LSL_Functions.llGetFreeURLs(); 471 return m_LSL_Functions.llGetFreeURLs();
@@ -1868,9 +1875,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1868 return m_LSL_Functions.llClearPrimMedia(face); 1875 return m_LSL_Functions.llClearPrimMedia(face);
1869 } 1876 }
1870 1877
1871 public void print(string str) 1878 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1872 { 1879 {
1873 m_LSL_Functions.print(str); 1880 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1874 } 1881 }
1875 } 1882 }
1876} 1883}
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 3575889..e9edf6c 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 783791f..9548253 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 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 461b473..6bfee91 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index d253c6a..4f3432d 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 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.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 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.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 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.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 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.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -269,43 +337,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
269 337
270 public void RemoveRegion(Scene scene) 338 public void RemoveRegion(Scene scene)
271 { 339 {
272 lock (m_Scripts) 340 lockScriptsForRead(true);
341 foreach (IScriptInstance instance in m_Scripts.Values)
273 { 342 {
274 foreach (IScriptInstance instance in m_Scripts.Values) 343 // Force a final state save
344 //
345 if (m_Assemblies.ContainsKey(instance.AssetID))
275 { 346 {
276 // Force a final state save 347 string assembly = m_Assemblies[instance.AssetID];
277 // 348 instance.SaveState(assembly);
278 if (m_Assemblies.ContainsKey(instance.AssetID)) 349 }
279 {
280 string assembly = m_Assemblies[instance.AssetID];
281 instance.SaveState(assembly);
282 }
283 350
284 // Clear the event queue and abort the instance thread 351 // Clear the event queue and abort the instance thread
285 // 352 //
286 instance.ClearQueue(); 353 instance.ClearQueue();
287 instance.Stop(0); 354 instance.Stop(0);
288 355
289 // Release events, timer, etc 356 // Release events, timer, etc
290 // 357 //
291 instance.DestroyScriptInstance(); 358 instance.DestroyScriptInstance();
292 359
293 // Unload scripts and app domains 360 // Unload scripts and app domains
294 // Must be done explicitly because they have infinite 361 // Must be done explicitly because they have infinite
295 // lifetime 362 // lifetime
296 // 363 //
297 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 364 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
298 if (m_DomainScripts[instance.AppDomain].Count == 0) 365 if (m_DomainScripts[instance.AppDomain].Count == 0)
299 { 366 {
300 m_DomainScripts.Remove(instance.AppDomain); 367 m_DomainScripts.Remove(instance.AppDomain);
301 UnloadAppDomain(instance.AppDomain); 368 UnloadAppDomain(instance.AppDomain);
302 }
303 } 369 }
304 m_Scripts.Clear();
305 m_PrimObjects.Clear();
306 m_Assemblies.Clear();
307 m_DomainScripts.Clear();
308 } 370 }
371 lockScriptsForRead(false);
372 lockScriptsForWrite(true);
373 m_Scripts.Clear();
374 lockScriptsForWrite(false);
375 m_PrimObjects.Clear();
376 m_Assemblies.Clear();
377 m_DomainScripts.Clear();
378
309 lock (m_ScriptEngines) 379 lock (m_ScriptEngines)
310 { 380 {
311 m_ScriptEngines.Remove(this); 381 m_ScriptEngines.Remove(this);
@@ -364,22 +434,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
364 434
365 List<IScriptInstance> instances = new List<IScriptInstance>(); 435 List<IScriptInstance> instances = new List<IScriptInstance>();
366 436
367 lock (m_Scripts) 437 lockScriptsForRead(true);
368 { 438 foreach (IScriptInstance instance in m_Scripts.Values)
369 foreach (IScriptInstance instance in m_Scripts.Values)
370 instances.Add(instance); 439 instances.Add(instance);
371 } 440 lockScriptsForRead(false);
372 441
373 foreach (IScriptInstance i in instances) 442 foreach (IScriptInstance i in instances)
374 { 443 {
375 string assembly = String.Empty; 444 string assembly = String.Empty;
376 445
377 lock (m_Scripts) 446
378 {
379 if (!m_Assemblies.ContainsKey(i.AssetID)) 447 if (!m_Assemblies.ContainsKey(i.AssetID))
380 continue; 448 continue;
381 assembly = m_Assemblies[i.AssetID]; 449 assembly = m_Assemblies[i.AssetID];
382 } 450
383 451
384 i.SaveState(assembly); 452 i.SaveState(assembly);
385 } 453 }
@@ -713,92 +781,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
713 } 781 }
714 782
715 ScriptInstance instance = null; 783 ScriptInstance instance = null;
716 lock (m_Scripts) 784 // Create the object record
785 lockScriptsForRead(true);
786 if ((!m_Scripts.ContainsKey(itemID)) ||
787 (m_Scripts[itemID].AssetID != assetID))
717 { 788 {
718 // Create the object record 789 lockScriptsForRead(false);
719 790
720 if ((!m_Scripts.ContainsKey(itemID)) || 791 UUID appDomain = assetID;
721 (m_Scripts[itemID].AssetID != assetID))
722 {
723 UUID appDomain = assetID;
724 792
725 if (part.ParentGroup.IsAttachment) 793 if (part.ParentGroup.IsAttachment)
726 appDomain = part.ParentGroup.RootPart.UUID; 794 appDomain = part.ParentGroup.RootPart.UUID;
727 795
728 if (!m_AppDomains.ContainsKey(appDomain)) 796 if (!m_AppDomains.ContainsKey(appDomain))
797 {
798 try
729 { 799 {
730 try 800 AppDomainSetup appSetup = new AppDomainSetup();
731 { 801 appSetup.PrivateBinPath = Path.Combine(
732 AppDomainSetup appSetup = new AppDomainSetup(); 802 m_ScriptEnginesPath,
733 appSetup.PrivateBinPath = Path.Combine( 803 m_Scene.RegionInfo.RegionID.ToString());
734 m_ScriptEnginesPath, 804
735 m_Scene.RegionInfo.RegionID.ToString()); 805 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
736 806 Evidence evidence = new Evidence(baseEvidence);
737 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 807
738 Evidence evidence = new Evidence(baseEvidence); 808 AppDomain sandbox;
739 809 if (m_AppDomainLoading)
740 AppDomain sandbox; 810 sandbox = AppDomain.CreateDomain(
741 if (m_AppDomainLoading) 811 m_Scene.RegionInfo.RegionID.ToString(),
742 sandbox = AppDomain.CreateDomain( 812 evidence, appSetup);
743 m_Scene.RegionInfo.RegionID.ToString(), 813 else
744 evidence, appSetup); 814 sandbox = AppDomain.CurrentDomain;
745 else 815
746 sandbox = AppDomain.CurrentDomain; 816 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
747 817 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
748 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 818 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
749 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 819 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
750 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 820 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
751 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 821 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
752 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 822 //sandbox.SetAppDomainPolicy(sandboxPolicy);
753 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 823
754 //sandbox.SetAppDomainPolicy(sandboxPolicy); 824 m_AppDomains[appDomain] = sandbox;
755 825
756 m_AppDomains[appDomain] = sandbox; 826 m_AppDomains[appDomain].AssemblyResolve +=
757 827 new ResolveEventHandler(
758 m_AppDomains[appDomain].AssemblyResolve += 828 AssemblyResolver.OnAssemblyResolve);
759 new ResolveEventHandler( 829 m_DomainScripts[appDomain] = new List<UUID>();
760 AssemblyResolver.OnAssemblyResolve); 830 }
761 m_DomainScripts[appDomain] = new List<UUID>(); 831 catch (Exception e)
762 } 832 {
763 catch (Exception e) 833 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
834 m_ScriptErrorMessage += "Exception creating app domain:\n";
835 m_ScriptFailCount++;
836 lock (m_AddingAssemblies)
764 { 837 {
765 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 838 m_AddingAssemblies[assembly]--;
766 m_ScriptErrorMessage += "Exception creating app domain:\n";
767 m_ScriptFailCount++;
768 lock (m_AddingAssemblies)
769 {
770 m_AddingAssemblies[assembly]--;
771 }
772 return false;
773 } 839 }
840 return false;
774 } 841 }
775 m_DomainScripts[appDomain].Add(itemID); 842 }
776 843 m_DomainScripts[appDomain].Add(itemID);
777 instance = new ScriptInstance(this, part, 844
778 itemID, assetID, assembly, 845 instance = new ScriptInstance(this, part,
779 m_AppDomains[appDomain], 846 itemID, assetID, assembly,
780 part.ParentGroup.RootPart.Name, 847 m_AppDomains[appDomain],
781 item.Name, startParam, postOnRez, 848 part.ParentGroup.RootPart.Name,
782 stateSource, m_MaxScriptQueue); 849 item.Name, startParam, postOnRez,
783 850 stateSource, m_MaxScriptQueue);
784 m_log.DebugFormat( 851
852 m_log.DebugFormat(
785 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 853 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
786 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 854 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
787 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 855 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
788 856
789 if (presence != null) 857 if (presence != null)
790 { 858 {
791 ShowScriptSaveResponse(item.OwnerID, 859 ShowScriptSaveResponse(item.OwnerID,
792 assetID, "Compile successful", true); 860 assetID, "Compile successful", true);
793 }
794
795 instance.AppDomain = appDomain;
796 instance.LineMap = linemap;
797
798 m_Scripts[itemID] = instance;
799 } 861 }
800 }
801 862
863 instance.AppDomain = appDomain;
864 instance.LineMap = linemap;
865 lockScriptsForWrite(true);
866 m_Scripts[itemID] = instance;
867 lockScriptsForWrite(false);
868 }
869 else
870 {
871 lockScriptsForRead(false);
872 }
802 lock (m_PrimObjects) 873 lock (m_PrimObjects)
803 { 874 {
804 if (!m_PrimObjects.ContainsKey(localID)) 875 if (!m_PrimObjects.ContainsKey(localID))
@@ -817,9 +888,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
817 m_AddingAssemblies[assembly]--; 888 m_AddingAssemblies[assembly]--;
818 } 889 }
819 890
820 if (instance != null) 891 if (instance!=null)
821 instance.Init(); 892 instance.Init();
822 893
823 return true; 894 return true;
824 } 895 }
825 896
@@ -832,20 +903,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
832 m_CompileDict.Remove(itemID); 903 m_CompileDict.Remove(itemID);
833 } 904 }
834 905
835 IScriptInstance instance = null; 906 lockScriptsForRead(true);
836 907 // Do we even have it?
837 lock (m_Scripts) 908 if (!m_Scripts.ContainsKey(itemID))
838 { 909 {
839 // Do we even have it? 910 lockScriptsForRead(false);
840 if (!m_Scripts.ContainsKey(itemID)) 911 return;
841 return;
842
843 instance=m_Scripts[itemID];
844 m_Scripts.Remove(itemID);
845 } 912 }
913
846 914
915 IScriptInstance instance=m_Scripts[itemID];
916 lockScriptsForRead(false);
917 lockScriptsForWrite(true);
918 m_Scripts.Remove(itemID);
919 lockScriptsForWrite(false);
847 instance.ClearQueue(); 920 instance.ClearQueue();
848 instance.Stop(0); 921 instance.Stop(0);
922
849// bool objectRemoved = false; 923// bool objectRemoved = false;
850 924
851 lock (m_PrimObjects) 925 lock (m_PrimObjects)
@@ -881,11 +955,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
881 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 955 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
882 if (handlerObjectRemoved != null) 956 if (handlerObjectRemoved != null)
883 { 957 {
884 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 958 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
885 handlerObjectRemoved(part.UUID); 959 handlerObjectRemoved(part.UUID);
886 } 960 }
887 961
888 962 CleanAssemblies();
963
889 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 964 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
890 if (handlerScriptRemoved != null) 965 if (handlerScriptRemoved != null)
891 handlerScriptRemoved(itemID); 966 handlerScriptRemoved(itemID);
@@ -1027,7 +1102,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1027 return false; 1102 return false;
1028 1103
1029 uuids = m_PrimObjects[localID]; 1104 uuids = m_PrimObjects[localID];
1030 } 1105
1031 1106
1032 foreach (UUID itemID in uuids) 1107 foreach (UUID itemID in uuids)
1033 { 1108 {
@@ -1045,6 +1120,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1045 result = true; 1120 result = true;
1046 } 1121 }
1047 } 1122 }
1123 }
1048 1124
1049 return result; 1125 return result;
1050 } 1126 }
@@ -1144,12 +1220,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1144 private IScriptInstance GetInstance(UUID itemID) 1220 private IScriptInstance GetInstance(UUID itemID)
1145 { 1221 {
1146 IScriptInstance instance; 1222 IScriptInstance instance;
1147 lock (m_Scripts) 1223 lockScriptsForRead(true);
1224 if (!m_Scripts.ContainsKey(itemID))
1148 { 1225 {
1149 if (!m_Scripts.ContainsKey(itemID)) 1226 lockScriptsForRead(false);
1150 return null; 1227 return null;
1151 instance = m_Scripts[itemID];
1152 } 1228 }
1229 instance = m_Scripts[itemID];
1230 lockScriptsForRead(false);
1153 return instance; 1231 return instance;
1154 } 1232 }
1155 1233
@@ -1173,6 +1251,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1173 return false; 1251 return false;
1174 } 1252 }
1175 1253
1254 [DebuggerNonUserCode]
1176 public void ApiResetScript(UUID itemID) 1255 public void ApiResetScript(UUID itemID)
1177 { 1256 {
1178 IScriptInstance instance = GetInstance(itemID); 1257 IScriptInstance instance = GetInstance(itemID);
@@ -1224,6 +1303,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1224 return UUID.Zero; 1303 return UUID.Zero;
1225 } 1304 }
1226 1305
1306 [DebuggerNonUserCode]
1227 public void SetState(UUID itemID, string newState) 1307 public void SetState(UUID itemID, string newState)
1228 { 1308 {
1229 IScriptInstance instance = GetInstance(itemID); 1309 IScriptInstance instance = GetInstance(itemID);
@@ -1244,11 +1324,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1244 { 1324 {
1245 List<IScriptInstance> instances = new List<IScriptInstance>(); 1325 List<IScriptInstance> instances = new List<IScriptInstance>();
1246 1326
1247 lock (m_Scripts) 1327 lockScriptsForRead(true);
1248 { 1328 foreach (IScriptInstance instance in m_Scripts.Values)
1249 foreach (IScriptInstance instance in m_Scripts.Values)
1250 instances.Add(instance); 1329 instances.Add(instance);
1251 } 1330 lockScriptsForRead(false);
1252 1331
1253 foreach (IScriptInstance i in instances) 1332 foreach (IScriptInstance i in instances)
1254 { 1333 {
@@ -1620,5 +1699,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1620 1699
1621 instance.Resume(); 1700 instance.Resume();
1622 } 1701 }
1702
1703 public bool HasScript(UUID itemID, out bool running)
1704 {
1705 running = true;
1706
1707 IScriptInstance instance = GetInstance(itemID);
1708 if (instance == null)
1709 return false;
1710
1711 running = instance.Running;
1712 return true;
1713 }
1623 } 1714 }
1624} 1715}