aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2194
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-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.cs2
-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.cs6
-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, 2065 insertions, 968 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 e3d0dac..64eb6d0 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;
@@ -65,6 +67,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 69using System.Reflection;
70using Timer = System.Timers.Timer;
68 71
69namespace OpenSim.Region.ScriptEngine.Shared.Api 72namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 73{
@@ -81,7 +84,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 84 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 85 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 86 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 87// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 88 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 89 protected SceneObjectPart m_host;
87 protected uint m_localID; 90 protected uint m_localID;
@@ -99,16 +102,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 102 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 103 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 104 protected bool m_scriptConsoleChannelEnabled = false;
105 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 106 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 108 new Dictionary<UUID, UserInfoCacheEntry>();
105 109
110 protected Timer m_ShoutSayTimer;
111 protected int m_SayShoutCount = 0;
112
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 113 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 114 {
115 m_ShoutSayTimer = new Timer(1000);
116 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
117 m_ShoutSayTimer.AutoReset = true;
118 m_ShoutSayTimer.Start();
119
108 m_ScriptEngine = ScriptEngine; 120 m_ScriptEngine = ScriptEngine;
109 m_host = host; 121 m_host = host;
110 m_localID = localID; 122 m_localID = localID;
111 m_itemID = itemID; 123 m_itemID = itemID;
124 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 125
113 m_ScriptDelayFactor = 126 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 127 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 174 get { return m_ScriptEngine.World; }
162 } 175 }
163 176
177 [DebuggerNonUserCode]
164 public void state(string newState) 178 public void state(string newState)
165 { 179 {
166 m_ScriptEngine.SetState(m_itemID, newState); 180 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 184 /// Reset the named script. The script must be present
171 /// in the same prim. 185 /// in the same prim.
172 /// </summary> 186 /// </summary>
187 [DebuggerNonUserCode]
173 public void llResetScript() 188 public void llResetScript()
174 { 189 {
175 m_host.AddScriptLPS(1); 190 m_host.AddScriptLPS(1);
@@ -226,9 +241,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 241 }
227 } 242 }
228 243
244 public List<ScenePresence> GetLinkAvatars(int linkType)
245 {
246 List<ScenePresence> ret = new List<ScenePresence>();
247 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
248 return ret;
249
250 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
251
252 switch (linkType)
253 {
254 case ScriptBaseClass.LINK_SET:
255 return avs;
256
257 case ScriptBaseClass.LINK_ROOT:
258 return ret;
259
260 case ScriptBaseClass.LINK_ALL_OTHERS:
261 return avs;
262
263 case ScriptBaseClass.LINK_ALL_CHILDREN:
264 return avs;
265
266 case ScriptBaseClass.LINK_THIS:
267 return ret;
268
269 default:
270 if (linkType < 0)
271 return ret;
272
273 int partCount = m_host.ParentGroup.GetPartCount();
274
275 if (linkType <= partCount)
276 {
277 return ret;
278 }
279 else
280 {
281 linkType = linkType - partCount;
282 if (linkType > avs.Count)
283 {
284 return ret;
285 }
286 else
287 {
288 ret.Add(avs[linkType-1]);
289 return ret;
290 }
291 }
292 }
293 }
294
229 public List<SceneObjectPart> GetLinkParts(int linkType) 295 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 296 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 297 List<SceneObjectPart> ret = new List<SceneObjectPart>();
298 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
299 return ret;
232 ret.Add(m_host); 300 ret.Add(m_host);
233 301
234 switch (linkType) 302 switch (linkType)
@@ -288,40 +356,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 356 protected UUID InventorySelf()
289 { 357 {
290 UUID invItemID = new UUID(); 358 UUID invItemID = new UUID();
291 359 bool unlock = false;
292 lock (m_host.TaskInventory) 360 if (!m_host.TaskInventory.IsReadLockedByMe())
361 {
362 m_host.TaskInventory.LockItemsForRead(true);
363 unlock = true;
364 }
365 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 366 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 367 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 368 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 369 invItemID = inv.Key;
297 { 370 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 371 }
302 } 372 }
303 373 if (unlock)
374 {
375 m_host.TaskInventory.LockItemsForRead(false);
376 }
304 return invItemID; 377 return invItemID;
305 } 378 }
306 379
307 protected UUID InventoryKey(string name, int type) 380 protected UUID InventoryKey(string name, int type)
308 { 381 {
309 m_host.AddScriptLPS(1); 382 m_host.AddScriptLPS(1);
310 383 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 384
385 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 386 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 387 if (inv.Value.Name == name)
314 { 388 {
315 if (inv.Value.Name == name) 389 m_host.TaskInventory.LockItemsForRead(false);
390
391 if (inv.Value.Type != type)
316 { 392 {
317 if (inv.Value.Type != type) 393 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 394 }
395
396 return inv.Value.AssetID;
322 } 397 }
323 } 398 }
324 399
400 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 401 return UUID.Zero;
326 } 402 }
327 403
@@ -329,17 +405,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 405 {
330 m_host.AddScriptLPS(1); 406 m_host.AddScriptLPS(1);
331 407
332 lock (m_host.TaskInventory) 408
409 m_host.TaskInventory.LockItemsForRead(true);
410
411 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 412 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 413 if (inv.Value.Name == name)
335 { 414 {
336 if (inv.Value.Name == name) 415 m_host.TaskInventory.LockItemsForRead(false);
337 { 416 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 417 }
341 } 418 }
342 419
420 m_host.TaskInventory.LockItemsForRead(false);
421
422
343 return UUID.Zero; 423 return UUID.Zero;
344 } 424 }
345 425
@@ -481,26 +561,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 561
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 562 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 563
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 564 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
486 565
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 566 // normalize an angle between -PI and PI (-180 to +180 degrees)
567 protected double NormalizeAngle(double angle)
568 {
569 if (angle > -Math.PI && angle < Math.PI)
570 return angle;
571
572 int numPis = (int)(Math.PI / angle);
573 double remainder = angle - Math.PI * numPis;
574 if (numPis % 2 == 1)
575 return Math.PI - angle;
576 return remainder;
577 }
578
579 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 580 {
489 m_host.AddScriptLPS(1); 581 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 582 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); 583
492 double m = (t.x + t.y + t.z + t.s); 584 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 585 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 586 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 587 double sqz = q1.y*q1.y;
496 if (p > 0) 588 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)), 589 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 590 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))); 591 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 592 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)); 593 eul.x = 0;
502 else 594 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)); 595 }
596 if (test < -0.4999*unit) { // singularity at south pole
597 eul.z = -2 * Math.Atan2(q1.x,q1.s);
598 eul.y = -Math.PI/2;
599 eul.x = 0;
600 return eul;
601 }
602 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
603 eul.y = Math.Asin(2*test/unit);
604 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
605 return eul;
504 } 606 }
505 607
506 /* From wiki: 608 /* From wiki:
@@ -702,77 +804,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 804 {
703 //A and B should both be normalized 805 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 806 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 807 /* 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, 808 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 809
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 810 double dotProduct = LSL_Vector.Dot(a, b);
811 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
812 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
813 double angle = Math.Acos(dotProduct / magProduct);
814 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
815 double s = Math.Sin(angle / 2);
816
817 double x = axis.x * s;
818 double y = axis.y * s;
819 double z = axis.z * s;
820 double w = Math.Cos(angle / 2);
821
822 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
823 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
824
825 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
826 */
827
828 // This method mimics the 180 errors found in SL
829 // See www.euclideanspace.com... angleBetween
830 LSL_Vector vec_a = a;
831 LSL_Vector vec_b = b;
832
833 // Eliminate zero length
834 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
835 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
836 if (vec_a_mag < 0.00001 ||
837 vec_b_mag < 0.00001)
709 { 838 {
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 839 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 } 840 }
712 else 841
842 // Normalize
843 vec_a = llVecNorm(vec_a);
844 vec_b = llVecNorm(vec_b);
845
846 // Calculate axis and rotation angle
847 LSL_Vector axis = vec_a % vec_b;
848 LSL_Float cos_theta = vec_a * vec_b;
849
850 // Check if parallel
851 if (cos_theta > 0.99999)
713 { 852 {
714 a = LSL_Vector.Norm(a); 853 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 b = LSL_Vector.Norm(b); 854 }
716 double dotProduct = LSL_Vector.Dot(a, b); 855
717 // There are two degenerate cases possible. These are for vectors 180 or 856 // Check if anti-parallel
718 // 0 degrees apart. These have to be detected and handled individually. 857 else if (cos_theta < -0.99999)
719 // 858 {
720 // Check for vectors 180 degrees apart. 859 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. 860 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
722 if (dotProduct < -0.9999999f) 861 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
723 { 862 }
724 // First assume X axis is orthogonal to the vectors. 863 else // other rotation
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 864 {
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 865 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 866 axis = llVecNorm(axis);
728 // a rotation in an undesired direction. 867 double x, y, z, s, t;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 868 s = Math.Cos(theta);
730 { 869 t = Math.Sin(theta);
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 870 x = axis.x * t;
732 } 871 y = axis.y * t;
733 // If the magnitude of the vector was near zero, then assume the X axis is not 872 z = axis.z * t;
734 // orthogonal and use the Z axis instead. 873 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 } 874 }
773 return rotBetween;
774 } 875 }
775 876
776 public void llWhisper(int channelID, string text) 877 public void llWhisper(int channelID, string text)
777 { 878 {
778 m_host.AddScriptLPS(1); 879 m_host.AddScriptLPS(1);
@@ -792,6 +893,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
792 { 893 {
793 m_host.AddScriptLPS(1); 894 m_host.AddScriptLPS(1);
794 895
896 if (channelID == 0)
897 m_SayShoutCount++;
898
899 if (m_SayShoutCount >= 11)
900 ScriptSleep(2000);
901
795 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 902 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
796 { 903 {
797 Console.WriteLine(text); 904 Console.WriteLine(text);
@@ -814,6 +921,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
814 { 921 {
815 m_host.AddScriptLPS(1); 922 m_host.AddScriptLPS(1);
816 923
924 if (channelID == 0)
925 m_SayShoutCount++;
926
927 if (m_SayShoutCount >= 11)
928 ScriptSleep(2000);
929
817 if (text.Length > 1023) 930 if (text.Length > 1023)
818 text = text.Substring(0, 1023); 931 text = text.Substring(0, 1023);
819 932
@@ -1096,10 +1209,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1209 return detectedParams.TouchUV;
1097 } 1210 }
1098 1211
1212 [DebuggerNonUserCode]
1099 public virtual void llDie() 1213 public virtual void llDie()
1100 { 1214 {
1101 m_host.AddScriptLPS(1); 1215 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1216 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1217 }
1104 1218
1105 public LSL_Float llGround(LSL_Vector offset) 1219 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1286,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1286
1173 public void llSetStatus(int status, int value) 1287 public void llSetStatus(int status, int value)
1174 { 1288 {
1289 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1290 return;
1175 m_host.AddScriptLPS(1); 1291 m_host.AddScriptLPS(1);
1176 1292
1177 int statusrotationaxis = 0; 1293 int statusrotationaxis = 0;
@@ -1402,6 +1518,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1518 {
1403 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1404 1520
1521 SetColor(m_host, color, face);
1522 }
1523
1524 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1525 {
1526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1527 return;
1528
1529 Primitive.TextureEntry tex = part.Shape.Textures;
1530 Color4 texcolor;
1531 if (face >= 0 && face < GetNumberOfSides(part))
1532 {
1533 texcolor = tex.CreateFace((uint)face).RGBA;
1534 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1535 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1536 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1537 tex.FaceTextures[face].RGBA = texcolor;
1538 part.UpdateTexture(tex);
1539 return;
1540 }
1541 else if (face == ScriptBaseClass.ALL_SIDES)
1542 {
1543 for (uint i = 0; i < GetNumberOfSides(part); i++)
1544 {
1545 if (tex.FaceTextures[i] != null)
1546 {
1547 texcolor = tex.FaceTextures[i].RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[i].RGBA = texcolor;
1552 }
1553 texcolor = tex.DefaultTexture.RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.DefaultTexture.RGBA = texcolor;
1558 }
1559 part.UpdateTexture(tex);
1560 return;
1561 }
1562
1405 if (face == ScriptBaseClass.ALL_SIDES) 1563 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1564 face = SceneObjectPart.ALL_SIDES;
1407 1565
@@ -1410,6 +1568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1568
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1569 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1570 {
1571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1572 return;
1573
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1574 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1575 MappingType textype;
1415 textype = MappingType.Default; 1576 textype = MappingType.Default;
@@ -1440,6 +1601,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1601
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1602 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1607 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1608 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1609 {
@@ -1465,6 +1629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1629
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1630 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1631 {
1632 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1633 return;
1468 1634
1469 Shininess sval = new Shininess(); 1635 Shininess sval = new Shininess();
1470 1636
@@ -1515,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1681
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1682 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1689 {
@@ -1575,13 +1744,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1744 m_host.AddScriptLPS(1);
1576 1745
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1746 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1747 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1748 {
1580 SetAlpha(part, alpha, face); 1749 try
1750 {
1751 parts[0].ParentGroup.areUpdatesSuspended = true;
1752 foreach (SceneObjectPart part in parts)
1753 SetAlpha(part, alpha, face);
1754 }
1755 finally
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = false;
1758 }
1759 }
1581 } 1760 }
1582 1761
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1762 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1768 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1809 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1810 float wind, float tension, LSL_Vector Force)
1629 { 1811 {
1630 if (part == null) 1812 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1813 return;
1632 1814
1633 if (flexi) 1815 if (flexi)
@@ -1662,7 +1844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1844 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1845 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1846 {
1665 if (part == null) 1847 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1848 return;
1667 1849
1668 if (light) 1850 if (light)
@@ -1739,15 +1921,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1921 m_host.AddScriptLPS(1);
1740 1922
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1923 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1924 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1925 {
1744 SetTexture(part, texture, face); 1926 try
1745 1927 {
1928 parts[0].ParentGroup.areUpdatesSuspended = true;
1929 foreach (SceneObjectPart part in parts)
1930 SetTexture(part, texture, face);
1931 }
1932 finally
1933 {
1934 parts[0].ParentGroup.areUpdatesSuspended = false;
1935 }
1936 }
1746 ScriptSleep(200); 1937 ScriptSleep(200);
1747 } 1938 }
1748 1939
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1940 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1941 {
1942 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1943 return;
1944
1751 UUID textureID = new UUID(); 1945 UUID textureID = new UUID();
1752 1946
1753 textureID = InventoryKey(texture, (int)AssetType.Texture); 1947 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1792,6 +1986,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1986
1793 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1987 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1794 { 1988 {
1989 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1990 return;
1991
1795 Primitive.TextureEntry tex = part.Shape.Textures; 1992 Primitive.TextureEntry tex = part.Shape.Textures;
1796 if (face >= 0 && face < GetNumberOfSides(part)) 1993 if (face >= 0 && face < GetNumberOfSides(part))
1797 { 1994 {
@@ -1828,6 +2025,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 2025
1829 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2026 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1830 { 2027 {
2028 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2029 return;
2030
1831 Primitive.TextureEntry tex = part.Shape.Textures; 2031 Primitive.TextureEntry tex = part.Shape.Textures;
1832 if (face >= 0 && face < GetNumberOfSides(part)) 2032 if (face >= 0 && face < GetNumberOfSides(part))
1833 { 2033 {
@@ -1864,6 +2064,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1864 2064
1865 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2065 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1866 { 2066 {
2067 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2068 return;
2069
1867 Primitive.TextureEntry tex = part.Shape.Textures; 2070 Primitive.TextureEntry tex = part.Shape.Textures;
1868 if (face >= 0 && face < GetNumberOfSides(part)) 2071 if (face >= 0 && face < GetNumberOfSides(part))
1869 { 2072 {
@@ -1932,10 +2135,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 return end; 2135 return end;
1933 } 2136 }
1934 2137
1935 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2138 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1936 { 2139 {
2140 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2141 return fromPos;
2142
1937 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2143 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1938 LSL_Vector currentPos = GetPartLocalPos(part); 2144
1939 2145
1940 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2146 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1941 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2147 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1944,14 +2150,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 { 2150 {
1945 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2151 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
1946 targetPos.z = ground; 2152 targetPos.z = ground;
2153 }
2154 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2155
2156 return real_vec;
2157 }
2158
2159 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2160 {
2161 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2162 return;
2163
2164 LSL_Vector currentPos = GetPartLocalPos(part);
2165 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2166
2167 if (part.ParentGroup.RootPart == part)
2168 {
1947 SceneObjectGroup parent = part.ParentGroup; 2169 SceneObjectGroup parent = part.ParentGroup;
1948 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2170 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 } 2171 }
1951 else 2172 else
1952 { 2173 {
1953 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2174 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; 2175 SceneObjectGroup parent = part.ParentGroup;
1956 parent.HasGroupChanged = true; 2176 parent.HasGroupChanged = true;
1957 parent.ScheduleGroupForTerseUpdate(); 2177 parent.ScheduleGroupForTerseUpdate();
@@ -2002,9 +2222,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 m_host.AddScriptLPS(1); 2222 m_host.AddScriptLPS(1);
2003 2223
2004 // try to let this work as in SL... 2224 // try to let this work as in SL...
2005 if (m_host.ParentID == 0) 2225 if (m_host.LinkNum < 2)
2006 { 2226 {
2007 // special case: If we are root, rotate complete SOG to new rotation 2227 // Special case: If we are root, rotate complete SOG to new
2228 // rotation.
2229 // We are root if the link number is 0 (single prim) or 1
2230 // (root prim). ParentID may be nonzero in attachments and
2231 // using it would cause attachments and HUDs to rotate
2232 // to the wrong positions.
2008 SetRot(m_host, Rot2Quaternion(rot)); 2233 SetRot(m_host, Rot2Quaternion(rot));
2009 } 2234 }
2010 else 2235 else
@@ -2033,6 +2258,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2033 2258
2034 protected void SetRot(SceneObjectPart part, Quaternion rot) 2259 protected void SetRot(SceneObjectPart part, Quaternion rot)
2035 { 2260 {
2261 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2262 return;
2263
2036 part.UpdateRotation(rot); 2264 part.UpdateRotation(rot);
2037 // Update rotation does not move the object in the physics scene if it's a linkset. 2265 // Update rotation does not move the object in the physics scene if it's a linkset.
2038 2266
@@ -2652,12 +2880,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 2880
2653 m_host.AddScriptLPS(1); 2881 m_host.AddScriptLPS(1);
2654 2882
2883 m_host.TaskInventory.LockItemsForRead(true);
2655 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2884 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2656 2885 m_host.TaskInventory.LockItemsForRead(false);
2657 lock (m_host.TaskInventory)
2658 {
2659 item = m_host.TaskInventory[invItemID];
2660 }
2661 2886
2662 if (item.PermsGranter == UUID.Zero) 2887 if (item.PermsGranter == UUID.Zero)
2663 return 0; 2888 return 0;
@@ -2732,6 +2957,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 if (dist > m_ScriptDistanceFactor * 10.0f) 2957 if (dist > m_ScriptDistanceFactor * 10.0f)
2733 return; 2958 return;
2734 2959
2960 //Clone is thread-safe
2735 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2961 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2736 2962
2737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2963 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2794,6 +3020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 3020
2795 public void llLookAt(LSL_Vector target, double strength, double damping) 3021 public void llLookAt(LSL_Vector target, double strength, double damping)
2796 { 3022 {
3023 /*
2797 m_host.AddScriptLPS(1); 3024 m_host.AddScriptLPS(1);
2798 // Determine where we are looking from 3025 // Determine where we are looking from
2799 LSL_Vector from = llGetPos(); 3026 LSL_Vector from = llGetPos();
@@ -2813,10 +3040,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 // the angles of rotation in radians into rotation value 3040 // the angles of rotation in radians into rotation value
2814 3041
2815 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3042 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2816 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3043
2817 m_host.startLookAt(rotation, (float)damping, (float)strength); 3044 // This would only work if your physics system contains an APID controller:
3045 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3046 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3047
2818 // Orient the object to the angle calculated 3048 // Orient the object to the angle calculated
2819 //llSetRot(rot); 3049 llSetRot(rot);
3050 */
3051
3052 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3053 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3054 // http://bugs.meta7.com/view.php?id=28
3055 // - Tom
3056
3057 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3058 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3059 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3060 */
3061 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3062 {
3063 // Part is non-phys, convert this to a llSetRot()
3064 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3065 Vector3 dir = tgt - m_host.GroupPosition;
3066 dir.Normalize();
3067 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3068 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3069 float terot = (float)Math.Atan2(-dir.Z, txy);
3070 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3071 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3072 LSL_Types.Quaternion spin = llEuler2Rot(az);
3073 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3074 llSetRot(rot);
3075 }
3076 else
3077 {
3078 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3079 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3080 m_host.RotLookAt(q, (float)strength, (float)damping);
3081 }
3082
3083 }
3084
3085 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3086 {
3087 m_host.AddScriptLPS(1);
3088// NotImplemented("llRotLookAt");
3089 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3090
2820 } 3091 }
2821 3092
2822 public void llStopLookAt() 3093 public void llStopLookAt()
@@ -2865,13 +3136,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 { 3136 {
2866 TaskInventoryItem item; 3137 TaskInventoryItem item;
2867 3138
2868 lock (m_host.TaskInventory) 3139 m_host.TaskInventory.LockItemsForRead(true);
3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2869 { 3141 {
2870 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3142 m_host.TaskInventory.LockItemsForRead(false);
2871 return; 3143 return;
2872 else
2873 item = m_host.TaskInventory[InventorySelf()];
2874 } 3144 }
3145 else
3146 {
3147 item = m_host.TaskInventory[InventorySelf()];
3148 }
3149 m_host.TaskInventory.LockItemsForRead(false);
2875 3150
2876 if (item.PermsGranter != UUID.Zero) 3151 if (item.PermsGranter != UUID.Zero)
2877 { 3152 {
@@ -2893,13 +3168,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2893 { 3168 {
2894 TaskInventoryItem item; 3169 TaskInventoryItem item;
2895 3170
3171 m_host.TaskInventory.LockItemsForRead(true);
2896 lock (m_host.TaskInventory) 3172 lock (m_host.TaskInventory)
2897 { 3173 {
3174
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3175 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3176 {
3177 m_host.TaskInventory.LockItemsForRead(false);
2899 return; 3178 return;
3179 }
2900 else 3180 else
3181 {
2901 item = m_host.TaskInventory[InventorySelf()]; 3182 item = m_host.TaskInventory[InventorySelf()];
3183 }
2902 } 3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
2903 3186
2904 m_host.AddScriptLPS(1); 3187 m_host.AddScriptLPS(1);
2905 3188
@@ -2931,19 +3214,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2931 { 3214 {
2932 m_host.AddScriptLPS(1); 3215 m_host.AddScriptLPS(1);
2933 3216
2934 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2935 return;
2936
2937 TaskInventoryItem item; 3217 TaskInventoryItem item;
2938 3218
2939 lock (m_host.TaskInventory) 3219 m_host.TaskInventory.LockItemsForRead(true);
3220
3221 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2940 { 3222 {
2941 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3223 m_host.TaskInventory.LockItemsForRead(false);
2942 return; 3224 return;
2943 else 3225 }
2944 item = m_host.TaskInventory[InventorySelf()]; 3226 else
3227 {
3228 item = m_host.TaskInventory[InventorySelf()];
2945 } 3229 }
2946 3230
3231 m_host.TaskInventory.LockItemsForRead(false);
3232
2947 if (item.PermsGranter != m_host.OwnerID) 3233 if (item.PermsGranter != m_host.OwnerID)
2948 return; 3234 return;
2949 3235
@@ -2953,10 +3239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 3239
2954 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3240 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2955 3241
2956 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3242 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 } 3243 }
2961 } 3244 }
2962 3245
@@ -2969,13 +3252,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2969 3252
2970 TaskInventoryItem item; 3253 TaskInventoryItem item;
2971 3254
2972 lock (m_host.TaskInventory) 3255 m_host.TaskInventory.LockItemsForRead(true);
3256
3257 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2973 { 3258 {
2974 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3259 m_host.TaskInventory.LockItemsForRead(false);
2975 return; 3260 return;
2976 else 3261 }
2977 item = m_host.TaskInventory[InventorySelf()]; 3262 else
3263 {
3264 item = m_host.TaskInventory[InventorySelf()];
2978 } 3265 }
3266 m_host.TaskInventory.LockItemsForRead(false);
3267
2979 3268
2980 if (item.PermsGranter != m_host.OwnerID) 3269 if (item.PermsGranter != m_host.OwnerID)
2981 return; 3270 return;
@@ -3022,6 +3311,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3311
3023 public void llInstantMessage(string user, string message) 3312 public void llInstantMessage(string user, string message)
3024 { 3313 {
3314 UUID result;
3315 if (!UUID.TryParse(user, out result))
3316 {
3317 ShoutError("An invalid key was passed to llInstantMessage");
3318 ScriptSleep(2000);
3319 return;
3320 }
3321
3322
3025 m_host.AddScriptLPS(1); 3323 m_host.AddScriptLPS(1);
3026 3324
3027 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3325 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3036,14 +3334,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 UUID friendTransactionID = UUID.Random(); 3334 UUID friendTransactionID = UUID.Random();
3037 3335
3038 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3336 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3039 3337
3040 GridInstantMessage msg = new GridInstantMessage(); 3338 GridInstantMessage msg = new GridInstantMessage();
3041 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3339 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3042 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3340 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3043 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3341 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); 3342// 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()); 3343// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3046 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3344// DateTime dt = DateTime.UtcNow;
3345//
3346// // Ticks from UtcNow, but make it look like local. Evil, huh?
3347// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3348//
3349// try
3350// {
3351// // Convert that to the PST timezone
3352// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3353// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3354// }
3355// catch
3356// {
3357// // No logging here, as it could be VERY spammy
3358// }
3359//
3360// // And make it look local again to fool the unix time util
3361// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3362
3363 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3364
3047 //if (client != null) 3365 //if (client != null)
3048 //{ 3366 //{
3049 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3367 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3057,12 +3375,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 msg.message = message.Substring(0, 1024); 3375 msg.message = message.Substring(0, 1024);
3058 else 3376 else
3059 msg.message = message; 3377 msg.message = message;
3060 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3378 msg.dialog = (byte)19; // MessageFromObject
3061 msg.fromGroup = false;// fromGroup; 3379 msg.fromGroup = false;// fromGroup;
3062 msg.offline = (byte)0; //offline; 3380 msg.offline = (byte)0; //offline;
3063 msg.ParentEstateID = 0; //ParentEstateID; 3381 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3064 msg.Position = new Vector3(m_host.AbsolutePosition); 3382 msg.Position = new Vector3(m_host.AbsolutePosition);
3065 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3383 msg.RegionID = World.RegionInfo.RegionID.Guid;
3066 msg.binaryBucket 3384 msg.binaryBucket
3067 = Util.StringToBytes256( 3385 = Util.StringToBytes256(
3068 "{0}/{1}/{2}/{3}", 3386 "{0}/{1}/{2}/{3}",
@@ -3090,7 +3408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3408 }
3091 3409
3092 emailModule.SendEmail(m_host.UUID, address, subject, message); 3410 emailModule.SendEmail(m_host.UUID, address, subject, message);
3093 ScriptSleep(20000); 3411 ScriptSleep(15000);
3094 } 3412 }
3095 3413
3096 public void llGetNextEmail(string address, string subject) 3414 public void llGetNextEmail(string address, string subject)
@@ -3192,13 +3510,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 m_host.AddScriptLPS(1); 3510 m_host.AddScriptLPS(1);
3193 } 3511 }
3194 3512
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) 3513 public LSL_Integer llStringLength(string str)
3203 { 3514 {
3204 m_host.AddScriptLPS(1); 3515 m_host.AddScriptLPS(1);
@@ -3222,14 +3533,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3222 3533
3223 TaskInventoryItem item; 3534 TaskInventoryItem item;
3224 3535
3225 lock (m_host.TaskInventory) 3536 m_host.TaskInventory.LockItemsForRead(true);
3537 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 { 3538 {
3227 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3539 m_host.TaskInventory.LockItemsForRead(false);
3228 return; 3540 return;
3229 else
3230 item = m_host.TaskInventory[InventorySelf()];
3231 } 3541 }
3232 3542 else
3543 {
3544 item = m_host.TaskInventory[InventorySelf()];
3545 }
3546 m_host.TaskInventory.LockItemsForRead(false);
3233 if (item.PermsGranter == UUID.Zero) 3547 if (item.PermsGranter == UUID.Zero)
3234 return; 3548 return;
3235 3549
@@ -3259,13 +3573,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3259 3573
3260 TaskInventoryItem item; 3574 TaskInventoryItem item;
3261 3575
3262 lock (m_host.TaskInventory) 3576 m_host.TaskInventory.LockItemsForRead(true);
3577 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3263 { 3578 {
3264 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3579 m_host.TaskInventory.LockItemsForRead(false);
3265 return; 3580 return;
3266 else
3267 item = m_host.TaskInventory[InventorySelf()];
3268 } 3581 }
3582 else
3583 {
3584 item = m_host.TaskInventory[InventorySelf()];
3585 }
3586 m_host.TaskInventory.LockItemsForRead(false);
3587
3269 3588
3270 if (item.PermsGranter == UUID.Zero) 3589 if (item.PermsGranter == UUID.Zero)
3271 return; 3590 return;
@@ -3330,10 +3649,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3330 3649
3331 TaskInventoryItem item; 3650 TaskInventoryItem item;
3332 3651
3333 lock (m_host.TaskInventory) 3652
3653 m_host.TaskInventory.LockItemsForRead(true);
3654 if (!m_host.TaskInventory.ContainsKey(invItemID))
3655 {
3656 m_host.TaskInventory.LockItemsForRead(false);
3657 return;
3658 }
3659 else
3334 { 3660 {
3335 item = m_host.TaskInventory[invItemID]; 3661 item = m_host.TaskInventory[invItemID];
3336 } 3662 }
3663 m_host.TaskInventory.LockItemsForRead(false);
3337 3664
3338 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3665 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3339 { 3666 {
@@ -3361,15 +3688,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3361 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3688 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3362 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3689 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3363 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3690 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3691 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3364 ScriptBaseClass.PERMISSION_ATTACH; 3692 ScriptBaseClass.PERMISSION_ATTACH;
3365 3693
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3694 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3695 {
3368 lock (m_host.TaskInventory) 3696 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3697 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3698 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3699 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3700
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3701 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3702 "run_time_permissions", new Object[] {
@@ -3389,11 +3716,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3716
3390 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3717 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3391 { 3718 {
3392 lock (m_host.TaskInventory) 3719 m_host.TaskInventory.LockItemsForWrite(true);
3393 { 3720 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3394 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3721 m_host.TaskInventory[invItemID].PermsMask = perm;
3395 m_host.TaskInventory[invItemID].PermsMask = perm; 3722 m_host.TaskInventory.LockItemsForWrite(false);
3396 }
3397 3723
3398 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3724 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3399 "run_time_permissions", new Object[] { 3725 "run_time_permissions", new Object[] {
@@ -3414,11 +3740,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 3740
3415 if (!m_waitingForScriptAnswer) 3741 if (!m_waitingForScriptAnswer)
3416 { 3742 {
3417 lock (m_host.TaskInventory) 3743 m_host.TaskInventory.LockItemsForWrite(true);
3418 { 3744 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3419 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3745 m_host.TaskInventory[invItemID].PermsMask = 0;
3420 m_host.TaskInventory[invItemID].PermsMask = 0; 3746 m_host.TaskInventory.LockItemsForWrite(false);
3421 }
3422 3747
3423 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3748 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3424 m_waitingForScriptAnswer=true; 3749 m_waitingForScriptAnswer=true;
@@ -3453,10 +3778,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3453 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3778 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3454 llReleaseControls(); 3779 llReleaseControls();
3455 3780
3456 lock (m_host.TaskInventory) 3781
3457 { 3782 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsMask = answer; 3783 m_host.TaskInventory[invItemID].PermsMask = answer;
3459 } 3784 m_host.TaskInventory.LockItemsForWrite(false);
3785
3460 3786
3461 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3787 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3788 "run_time_permissions", new Object[] {
@@ -3468,16 +3794,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3468 { 3794 {
3469 m_host.AddScriptLPS(1); 3795 m_host.AddScriptLPS(1);
3470 3796
3471 lock (m_host.TaskInventory) 3797 m_host.TaskInventory.LockItemsForRead(true);
3798
3799 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3472 { 3800 {
3473 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3801 if (item.Type == 10 && item.ItemID == m_itemID)
3474 { 3802 {
3475 if (item.Type == 10 && item.ItemID == m_itemID) 3803 m_host.TaskInventory.LockItemsForRead(false);
3476 { 3804 return item.PermsGranter.ToString();
3477 return item.PermsGranter.ToString();
3478 }
3479 } 3805 }
3480 } 3806 }
3807 m_host.TaskInventory.LockItemsForRead(false);
3481 3808
3482 return UUID.Zero.ToString(); 3809 return UUID.Zero.ToString();
3483 } 3810 }
@@ -3486,19 +3813,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3486 { 3813 {
3487 m_host.AddScriptLPS(1); 3814 m_host.AddScriptLPS(1);
3488 3815
3489 lock (m_host.TaskInventory) 3816 m_host.TaskInventory.LockItemsForRead(true);
3817
3818 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3490 { 3819 {
3491 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3820 if (item.Type == 10 && item.ItemID == m_itemID)
3492 { 3821 {
3493 if (item.Type == 10 && item.ItemID == m_itemID) 3822 int perms = item.PermsMask;
3494 { 3823 if (m_automaticLinkPermission)
3495 int perms = item.PermsMask; 3824 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3496 if (m_automaticLinkPermission) 3825 m_host.TaskInventory.LockItemsForRead(false);
3497 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3826 return perms;
3498 return perms;
3499 }
3500 } 3827 }
3501 } 3828 }
3829 m_host.TaskInventory.LockItemsForRead(false);
3502 3830
3503 return 0; 3831 return 0;
3504 } 3832 }
@@ -3520,9 +3848,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3520 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3848 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3521 { 3849 {
3522 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3850 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3523 3851 if (parts.Count > 0)
3524 foreach (SceneObjectPart part in parts) 3852 {
3525 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3853 try
3854 {
3855 parts[0].ParentGroup.areUpdatesSuspended = true;
3856 foreach (SceneObjectPart part in parts)
3857 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3858 }
3859 finally
3860 {
3861 parts[0].ParentGroup.areUpdatesSuspended = false;
3862 }
3863 }
3526 } 3864 }
3527 3865
3528 public void llCreateLink(string target, int parent) 3866 public void llCreateLink(string target, int parent)
@@ -3535,11 +3873,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3535 return; 3873 return;
3536 3874
3537 TaskInventoryItem item; 3875 TaskInventoryItem item;
3538 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForRead(true);
3539 { 3877 item = m_host.TaskInventory[invItemID];
3540 item = m_host.TaskInventory[invItemID]; 3878 m_host.TaskInventory.LockItemsForRead(false);
3541 } 3879
3542
3543 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3880 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3544 && !m_automaticLinkPermission) 3881 && !m_automaticLinkPermission)
3545 { 3882 {
@@ -3556,11 +3893,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 3893
3557 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3894 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0)
3558 return; // Fail silently if attached 3895 return; // Fail silently if attached
3896
3897 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3898 return;
3899
3559 SceneObjectGroup parentPrim = null, childPrim = null; 3900 SceneObjectGroup parentPrim = null, childPrim = null;
3560 3901
3561 if (targetPart != null) 3902 if (targetPart != null)
3562 { 3903 {
3563 if (parent != 0) { 3904 if (parent != 0)
3905 {
3564 parentPrim = m_host.ParentGroup; 3906 parentPrim = m_host.ParentGroup;
3565 childPrim = targetPart.ParentGroup; 3907 childPrim = targetPart.ParentGroup;
3566 } 3908 }
@@ -3592,16 +3934,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3592 m_host.AddScriptLPS(1); 3934 m_host.AddScriptLPS(1);
3593 UUID invItemID = InventorySelf(); 3935 UUID invItemID = InventorySelf();
3594 3936
3595 lock (m_host.TaskInventory) 3937 m_host.TaskInventory.LockItemsForRead(true);
3596 {
3597 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3938 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3598 && !m_automaticLinkPermission) 3939 && !m_automaticLinkPermission)
3599 { 3940 {
3600 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3941 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3942 m_host.TaskInventory.LockItemsForRead(false);
3601 return; 3943 return;
3602 } 3944 }
3603 } 3945 m_host.TaskInventory.LockItemsForRead(false);
3604 3946
3605 if (linknum < ScriptBaseClass.LINK_THIS) 3947 if (linknum < ScriptBaseClass.LINK_THIS)
3606 return; 3948 return;
3607 3949
@@ -3640,10 +3982,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 // Restructuring Multiple Prims. 3982 // Restructuring Multiple Prims.
3641 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3983 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3642 parts.Remove(parentPrim.RootPart); 3984 parts.Remove(parentPrim.RootPart);
3643 foreach (SceneObjectPart part in parts) 3985 if (parts.Count > 0)
3644 { 3986 {
3645 parentPrim.DelinkFromGroup(part.LocalId, true); 3987 try
3988 {
3989 parts[0].ParentGroup.areUpdatesSuspended = true;
3990 foreach (SceneObjectPart part in parts)
3991 {
3992 parentPrim.DelinkFromGroup(part.LocalId, true);
3993 }
3994 }
3995 finally
3996 {
3997 parts[0].ParentGroup.areUpdatesSuspended = false;
3998 }
3646 } 3999 }
4000
3647 parentPrim.HasGroupChanged = true; 4001 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 4002 parentPrim.ScheduleGroupForFullUpdate();
3649 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4003 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3652,11 +4006,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3652 { 4006 {
3653 SceneObjectPart newRoot = parts[0]; 4007 SceneObjectPart newRoot = parts[0];
3654 parts.Remove(newRoot); 4008 parts.Remove(newRoot);
3655 foreach (SceneObjectPart part in parts) 4009
4010 try
3656 { 4011 {
3657 part.UpdateFlag = 0; 4012 parts[0].ParentGroup.areUpdatesSuspended = true;
3658 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4013 foreach (SceneObjectPart part in parts)
4014 {
4015 part.UpdateFlag = 0;
4016 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4017 }
3659 } 4018 }
4019 finally
4020 {
4021 parts[0].ParentGroup.areUpdatesSuspended = false;
4022 }
4023
4024
3660 newRoot.ParentGroup.HasGroupChanged = true; 4025 newRoot.ParentGroup.HasGroupChanged = true;
3661 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4026 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3662 } 4027 }
@@ -3676,6 +4041,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3676 public void llBreakAllLinks() 4041 public void llBreakAllLinks()
3677 { 4042 {
3678 m_host.AddScriptLPS(1); 4043 m_host.AddScriptLPS(1);
4044
4045 UUID invItemID = InventorySelf();
4046
4047 TaskInventoryItem item;
4048 m_host.TaskInventory.LockItemsForRead(true);
4049 item = m_host.TaskInventory[invItemID];
4050 m_host.TaskInventory.LockItemsForRead(false);
4051
4052 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4053 && !m_automaticLinkPermission)
4054 {
4055 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4056 return;
4057 }
4058
3679 SceneObjectGroup parentPrim = m_host.ParentGroup; 4059 SceneObjectGroup parentPrim = m_host.ParentGroup;
3680 if (parentPrim.RootPart.AttachmentPoint != 0) 4060 if (parentPrim.RootPart.AttachmentPoint != 0)
3681 return; // Fail silently if attached 4061 return; // Fail silently if attached
@@ -3702,6 +4082,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3702 } 4082 }
3703 else 4083 else
3704 { 4084 {
4085 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4086 {
4087 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4088
4089 if (linknum < 0)
4090 return UUID.Zero.ToString();
4091
4092 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4093 if (avatars.Count > linknum)
4094 {
4095 return avatars[linknum].UUID.ToString();
4096 }
4097 }
3705 return UUID.Zero.ToString(); 4098 return UUID.Zero.ToString();
3706 } 4099 }
3707 } 4100 }
@@ -3778,17 +4171,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3778 m_host.AddScriptLPS(1); 4171 m_host.AddScriptLPS(1);
3779 int count = 0; 4172 int count = 0;
3780 4173
3781 lock (m_host.TaskInventory) 4174 m_host.TaskInventory.LockItemsForRead(true);
4175 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3782 { 4176 {
3783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4177 if (inv.Value.Type == type || type == -1)
3784 { 4178 {
3785 if (inv.Value.Type == type || type == -1) 4179 count = count + 1;
3786 {
3787 count = count + 1;
3788 }
3789 } 4180 }
3790 } 4181 }
3791 4182
4183 m_host.TaskInventory.LockItemsForRead(false);
3792 return count; 4184 return count;
3793 } 4185 }
3794 4186
@@ -3797,16 +4189,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3797 m_host.AddScriptLPS(1); 4189 m_host.AddScriptLPS(1);
3798 ArrayList keys = new ArrayList(); 4190 ArrayList keys = new ArrayList();
3799 4191
3800 lock (m_host.TaskInventory) 4192 m_host.TaskInventory.LockItemsForRead(true);
4193 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3801 { 4194 {
3802 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4195 if (inv.Value.Type == type || type == -1)
3803 { 4196 {
3804 if (inv.Value.Type == type || type == -1) 4197 keys.Add(inv.Value.Name);
3805 {
3806 keys.Add(inv.Value.Name);
3807 }
3808 } 4198 }
3809 } 4199 }
4200 m_host.TaskInventory.LockItemsForRead(false);
3810 4201
3811 if (keys.Count == 0) 4202 if (keys.Count == 0)
3812 { 4203 {
@@ -3843,30 +4234,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 } 4234 }
3844 4235
3845 // move the first object found with this inventory name 4236 // move the first object found with this inventory name
3846 lock (m_host.TaskInventory) 4237 m_host.TaskInventory.LockItemsForRead(true);
4238 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3847 { 4239 {
3848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4240 if (inv.Value.Name == inventory)
3849 { 4241 {
3850 if (inv.Value.Name == inventory) 4242 found = true;
3851 { 4243 objId = inv.Key;
3852 found = true; 4244 assetType = inv.Value.Type;
3853 objId = inv.Key; 4245 objName = inv.Value.Name;
3854 assetType = inv.Value.Type; 4246 break;
3855 objName = inv.Value.Name;
3856 break;
3857 }
3858 } 4247 }
3859 } 4248 }
4249 m_host.TaskInventory.LockItemsForRead(false);
3860 4250
3861 if (!found) 4251 if (!found)
3862 { 4252 {
3863 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4253 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)); 4254 return;
4255// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3865 } 4256 }
3866 4257
3867 // check if destination is an avatar 4258 // check if destination is an object
3868 if (World.GetScenePresence(destId) != null) 4259 if (World.GetSceneObjectPart(destId) != null)
4260 {
4261 // destination is an object
4262 World.MoveTaskInventoryItem(destId, m_host, objId);
4263 }
4264 else
3869 { 4265 {
4266 ScenePresence presence = World.GetScenePresence(destId);
4267
4268 if (presence == null)
4269 {
4270 UserAccount account =
4271 World.UserAccountService.GetUserAccount(
4272 World.RegionInfo.ScopeID,
4273 destId);
4274
4275 if (account == null)
4276 {
4277 llSay(0, "Can't find destination "+destId.ToString());
4278 return;
4279 }
4280 }
4281
3870 // destination is an avatar 4282 // destination is an avatar
3871 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4283 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3872 4284
@@ -3890,31 +4302,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 4302
3891 if (m_TransferModule != null) 4303 if (m_TransferModule != null)
3892 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4304 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4305
4306 //This delay should only occur when giving inventory to avatars.
4307 ScriptSleep(3000);
3893 } 4308 }
3894 else
3895 {
3896 // destination is an object
3897 World.MoveTaskInventoryItem(destId, m_host, objId);
3898 }
3899 ScriptSleep(3000);
3900 } 4309 }
3901 4310
4311 [DebuggerNonUserCode]
3902 public void llRemoveInventory(string name) 4312 public void llRemoveInventory(string name)
3903 { 4313 {
3904 m_host.AddScriptLPS(1); 4314 m_host.AddScriptLPS(1);
3905 4315
3906 lock (m_host.TaskInventory) 4316 List<TaskInventoryItem> inv;
4317 try
3907 { 4318 {
3908 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4319 m_host.TaskInventory.LockItemsForRead(true);
4320 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4321 }
4322 finally
4323 {
4324 m_host.TaskInventory.LockItemsForRead(false);
4325 }
4326 foreach (TaskInventoryItem item in inv)
4327 {
4328 if (item.Name == name)
3909 { 4329 {
3910 if (item.Name == name) 4330 if (item.ItemID == m_itemID)
3911 { 4331 throw new ScriptDeleteException();
3912 if (item.ItemID == m_itemID) 4332 else
3913 throw new ScriptDeleteException(); 4333 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3914 else 4334 return;
3915 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3916 return;
3917 }
3918 } 4335 }
3919 } 4336 }
3920 } 4337 }
@@ -3949,112 +4366,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3949 { 4366 {
3950 m_host.AddScriptLPS(1); 4367 m_host.AddScriptLPS(1);
3951 4368
3952 UUID uuid = (UUID)id; 4369 UUID uuid;
3953 PresenceInfo pinfo = null; 4370 if (UUID.TryParse(id, out uuid))
3954 UserAccount account;
3955
3956 UserInfoCacheEntry ce;
3957 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3958 { 4371 {
3959 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4372 PresenceInfo pinfo = null;
3960 if (account == null) 4373 UserAccount account;
4374
4375 UserInfoCacheEntry ce;
4376 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3961 { 4377 {
3962 m_userInfoCache[uuid] = null; // Cache negative 4378 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3963 return UUID.Zero.ToString(); 4379 if (account == null)
3964 } 4380 {
4381 m_userInfoCache[uuid] = null; // Cache negative
4382 return UUID.Zero.ToString();
4383 }
3965 4384
3966 4385
3967 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4386 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3968 if (pinfos != null && pinfos.Length > 0) 4387 if (pinfos != null && pinfos.Length > 0)
3969 {
3970 foreach (PresenceInfo p in pinfos)
3971 { 4388 {
3972 if (p.RegionID != UUID.Zero) 4389 foreach (PresenceInfo p in pinfos)
3973 { 4390 {
3974 pinfo = p; 4391 if (p.RegionID != UUID.Zero)
4392 {
4393 pinfo = p;
4394 }
3975 } 4395 }
3976 } 4396 }
3977 }
3978 4397
3979 ce = new UserInfoCacheEntry(); 4398 ce = new UserInfoCacheEntry();
3980 ce.time = Util.EnvironmentTickCount(); 4399 ce.time = Util.EnvironmentTickCount();
3981 ce.account = account; 4400 ce.account = account;
3982 ce.pinfo = pinfo; 4401 ce.pinfo = pinfo;
3983 } 4402 m_userInfoCache[uuid] = ce;
3984 else 4403 }
3985 { 4404 else
3986 if (ce == null) 4405 {
3987 return UUID.Zero.ToString(); 4406 if (ce == null)
4407 return UUID.Zero.ToString();
3988 4408
3989 account = ce.account; 4409 account = ce.account;
3990 pinfo = ce.pinfo; 4410 pinfo = ce.pinfo;
3991 } 4411 }
3992 4412
3993 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4413 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
3994 {
3995 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3996 if (pinfos != null && pinfos.Length > 0)
3997 { 4414 {
3998 foreach (PresenceInfo p in pinfos) 4415 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4416 if (pinfos != null && pinfos.Length > 0)
3999 { 4417 {
4000 if (p.RegionID != UUID.Zero) 4418 foreach (PresenceInfo p in pinfos)
4001 { 4419 {
4002 pinfo = p; 4420 if (p.RegionID != UUID.Zero)
4421 {
4422 pinfo = p;
4423 }
4003 } 4424 }
4004 } 4425 }
4005 } 4426 else
4006 else 4427 pinfo = null;
4007 pinfo = null;
4008 4428
4009 ce.time = Util.EnvironmentTickCount(); 4429 ce.time = Util.EnvironmentTickCount();
4010 ce.pinfo = pinfo; 4430 ce.pinfo = pinfo;
4011 } 4431 }
4012 4432
4013 string reply = String.Empty; 4433 string reply = String.Empty;
4014 4434
4015 switch (data) 4435 switch (data)
4016 { 4436 {
4017 case 1: // DATA_ONLINE (0|1) 4437 case 1: // DATA_ONLINE (0|1)
4018 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4438 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4019 reply = "1"; 4439 reply = "1";
4020 else 4440 else
4021 reply = "0"; 4441 reply = "0";
4022 break; 4442 break;
4023 case 2: // DATA_NAME (First Last) 4443 case 2: // DATA_NAME (First Last)
4024 reply = account.FirstName + " " + account.LastName; 4444 reply = account.FirstName + " " + account.LastName;
4025 break; 4445 break;
4026 case 3: // DATA_BORN (YYYY-MM-DD) 4446 case 3: // DATA_BORN (YYYY-MM-DD)
4027 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4447 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4028 born = born.AddSeconds(account.Created); 4448 born = born.AddSeconds(account.Created);
4029 reply = born.ToString("yyyy-MM-dd"); 4449 reply = born.ToString("yyyy-MM-dd");
4030 break; 4450 break;
4031 case 4: // DATA_RATING (0,0,0,0,0,0) 4451 case 4: // DATA_RATING (0,0,0,0,0,0)
4032 reply = "0,0,0,0,0,0"; 4452 reply = "0,0,0,0,0,0";
4033 break; 4453 break;
4034 case 8: // DATA_PAYINFO (0|1|2|3) 4454 case 8: // DATA_PAYINFO (0|1|2|3)
4035 reply = "0"; 4455 reply = "0";
4036 break; 4456 break;
4037 default: 4457 default:
4038 return UUID.Zero.ToString(); // Raise no event 4458 return UUID.Zero.ToString(); // Raise no event
4039 } 4459 }
4040 4460
4041 UUID rq = UUID.Random(); 4461 UUID rq = UUID.Random();
4042 4462
4043 UUID tid = AsyncCommands. 4463 UUID tid = AsyncCommands.
4044 DataserverPlugin.RegisterRequest(m_localID, 4464 DataserverPlugin.RegisterRequest(m_localID,
4045 m_itemID, rq.ToString()); 4465 m_itemID, rq.ToString());
4046 4466
4047 AsyncCommands. 4467 AsyncCommands.
4048 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4468 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4049 4469
4050 ScriptSleep(100); 4470 ScriptSleep(100);
4051 return tid.ToString(); 4471 return tid.ToString();
4472 }
4473 else
4474 {
4475 ShoutError("Invalid UUID passed to llRequestAgentData.");
4476 }
4477 return "";
4052 } 4478 }
4053 4479
4054 public LSL_String llRequestInventoryData(string name) 4480 public LSL_String llRequestInventoryData(string name)
4055 { 4481 {
4056 m_host.AddScriptLPS(1); 4482 m_host.AddScriptLPS(1);
4057 4483
4484 //Clone is thread safe
4058 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4485 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4059 4486
4060 foreach (TaskInventoryItem item in itemDictionary.Values) 4487 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4108,6 +4535,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4108 ScenePresence presence = World.GetScenePresence(agentId); 4535 ScenePresence presence = World.GetScenePresence(agentId);
4109 if (presence != null) 4536 if (presence != null)
4110 { 4537 {
4538 // agent must not be a god
4539 if (presence.UserLevel >= 200) return;
4540
4111 // agent must be over the owners land 4541 // agent must be over the owners land
4112 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4542 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4113 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4543 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4130,7 +4560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4130 UUID av = new UUID(); 4560 UUID av = new UUID();
4131 if (!UUID.TryParse(agent,out av)) 4561 if (!UUID.TryParse(agent,out av))
4132 { 4562 {
4133 LSLError("First parameter to llDialog needs to be a key"); 4563 //LSLError("First parameter to llDialog needs to be a key");
4134 return; 4564 return;
4135 } 4565 }
4136 4566
@@ -4167,17 +4597,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4167 UUID soundId = UUID.Zero; 4597 UUID soundId = UUID.Zero;
4168 if (!UUID.TryParse(impact_sound, out soundId)) 4598 if (!UUID.TryParse(impact_sound, out soundId))
4169 { 4599 {
4170 lock (m_host.TaskInventory) 4600 m_host.TaskInventory.LockItemsForRead(true);
4601 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4171 { 4602 {
4172 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4603 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4173 { 4604 {
4174 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4605 soundId = item.AssetID;
4175 { 4606 break;
4176 soundId = item.AssetID;
4177 break;
4178 }
4179 } 4607 }
4180 } 4608 }
4609 m_host.TaskInventory.LockItemsForRead(false);
4181 } 4610 }
4182 m_host.CollisionSound = soundId; 4611 m_host.CollisionSound = soundId;
4183 m_host.CollisionSoundVolume = (float)impact_volume; 4612 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4217,6 +4646,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4217 UUID partItemID; 4646 UUID partItemID;
4218 foreach (SceneObjectPart part in parts) 4647 foreach (SceneObjectPart part in parts)
4219 { 4648 {
4649 //Clone is thread safe
4220 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4650 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4221 4651
4222 foreach (TaskInventoryItem item in itemsDictionary.Values) 4652 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4431,17 +4861,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4431 4861
4432 m_host.AddScriptLPS(1); 4862 m_host.AddScriptLPS(1);
4433 4863
4434 lock (m_host.TaskInventory) 4864 m_host.TaskInventory.LockItemsForRead(true);
4865 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4435 { 4866 {
4436 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4867 if (item.Type == 10 && item.ItemID == m_itemID)
4437 { 4868 {
4438 if (item.Type == 10 && item.ItemID == m_itemID) 4869 result = item.Name!=null?item.Name:String.Empty;
4439 { 4870 break;
4440 result = item.Name != null ? item.Name : String.Empty;
4441 break;
4442 }
4443 } 4871 }
4444 } 4872 }
4873 m_host.TaskInventory.LockItemsForRead(false);
4445 4874
4446 return result; 4875 return result;
4447 } 4876 }
@@ -4610,23 +5039,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4610 { 5039 {
4611 m_host.AddScriptLPS(1); 5040 m_host.AddScriptLPS(1);
4612 5041
4613 lock (m_host.TaskInventory) 5042 m_host.TaskInventory.LockItemsForRead(true);
5043 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4614 { 5044 {
4615 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5045 if (inv.Value.Name == name)
4616 { 5046 {
4617 if (inv.Value.Name == name) 5047 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4618 { 5048 {
4619 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5049 m_host.TaskInventory.LockItemsForRead(false);
4620 { 5050 return inv.Value.AssetID.ToString();
4621 return inv.Value.AssetID.ToString(); 5051 }
4622 } 5052 else
4623 else 5053 {
4624 { 5054 m_host.TaskInventory.LockItemsForRead(false);
4625 return UUID.Zero.ToString(); 5055 return UUID.Zero.ToString();
4626 }
4627 } 5056 }
4628 } 5057 }
4629 } 5058 }
5059 m_host.TaskInventory.LockItemsForRead(false);
4630 5060
4631 return UUID.Zero.ToString(); 5061 return UUID.Zero.ToString();
4632 } 5062 }
@@ -4779,14 +5209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4779 { 5209 {
4780 m_host.AddScriptLPS(1); 5210 m_host.AddScriptLPS(1);
4781 5211
4782 if (src == null) 5212 return src.Length;
4783 {
4784 return 0;
4785 }
4786 else
4787 {
4788 return src.Length;
4789 }
4790 } 5213 }
4791 5214
4792 public LSL_Integer llList2Integer(LSL_List src, int index) 5215 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4832,7 +5255,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4832 else if (src.Data[index] is LSL_Float) 5255 else if (src.Data[index] is LSL_Float)
4833 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5256 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4834 else if (src.Data[index] is LSL_String) 5257 else if (src.Data[index] is LSL_String)
4835 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5258 {
5259 string str = ((LSL_String) src.Data[index]).m_string;
5260 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5261 if (m != Match.Empty)
5262 {
5263 str = m.Value;
5264 double d = 0.0;
5265 if (!Double.TryParse(str, out d))
5266 return 0.0;
5267
5268 return d;
5269 }
5270 return 0.0;
5271 }
4836 return Convert.ToDouble(src.Data[index]); 5272 return Convert.ToDouble(src.Data[index]);
4837 } 5273 }
4838 catch (FormatException) 5274 catch (FormatException)
@@ -5105,7 +5541,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5105 } 5541 }
5106 } 5542 }
5107 } 5543 }
5108 else { 5544 else
5545 {
5109 object[] array = new object[src.Length]; 5546 object[] array = new object[src.Length];
5110 Array.Copy(src.Data, 0, array, 0, src.Length); 5547 Array.Copy(src.Data, 0, array, 0, src.Length);
5111 result = new LSL_List(array); 5548 result = new LSL_List(array);
@@ -5556,10 +5993,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5556 m_host.AddScriptLPS(1); 5993 m_host.AddScriptLPS(1);
5557 5994
5558 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5995 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5559 5996 if (parts.Count > 0)
5560 foreach (var part in parts)
5561 { 5997 {
5562 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5998 try
5999 {
6000 parts[0].ParentGroup.areUpdatesSuspended = true;
6001 foreach (var part in parts)
6002 {
6003 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6004 }
6005 }
6006 finally
6007 {
6008 parts[0].ParentGroup.areUpdatesSuspended = false;
6009 }
5563 } 6010 }
5564 } 6011 }
5565 6012
@@ -5613,6 +6060,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5613 ScriptSleep(5000); 6060 ScriptSleep(5000);
5614 } 6061 }
5615 6062
6063 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6064 {
6065 return ParseString2List(str, separators, in_spacers, false);
6066 }
6067
5616 public LSL_Integer llOverMyLand(string id) 6068 public LSL_Integer llOverMyLand(string id)
5617 { 6069 {
5618 m_host.AddScriptLPS(1); 6070 m_host.AddScriptLPS(1);
@@ -5813,7 +6265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5813 return m_host.ParentGroup.RootPart.AttachmentPoint; 6265 return m_host.ParentGroup.RootPart.AttachmentPoint;
5814 } 6266 }
5815 6267
5816 public LSL_Integer llGetFreeMemory() 6268 public virtual LSL_Integer llGetFreeMemory()
5817 { 6269 {
5818 m_host.AddScriptLPS(1); 6270 m_host.AddScriptLPS(1);
5819 // Make scripts designed for LSO happy 6271 // Make scripts designed for LSO happy
@@ -5930,7 +6382,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5930 SetParticleSystem(m_host, rules); 6382 SetParticleSystem(m_host, rules);
5931 } 6383 }
5932 6384
5933 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6385 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6386 {
5934 6387
5935 6388
5936 if (rules.Length == 0) 6389 if (rules.Length == 0)
@@ -6124,14 +6577,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6124 6577
6125 protected UUID GetTaskInventoryItem(string name) 6578 protected UUID GetTaskInventoryItem(string name)
6126 { 6579 {
6127 lock (m_host.TaskInventory) 6580 m_host.TaskInventory.LockItemsForRead(true);
6581 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6128 { 6582 {
6129 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6583 if (inv.Value.Name == name)
6130 { 6584 {
6131 if (inv.Value.Name == name) 6585 m_host.TaskInventory.LockItemsForRead(false);
6132 return inv.Key; 6586 return inv.Key;
6133 } 6587 }
6134 } 6588 }
6589 m_host.TaskInventory.LockItemsForRead(false);
6135 6590
6136 return UUID.Zero; 6591 return UUID.Zero;
6137 } 6592 }
@@ -6381,13 +6836,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6381 UUID av = new UUID(); 6836 UUID av = new UUID();
6382 if (!UUID.TryParse(avatar,out av)) 6837 if (!UUID.TryParse(avatar,out av))
6383 { 6838 {
6384 LSLError("First parameter to llDialog needs to be a key"); 6839 //LSLError("First parameter to llDialog needs to be a key");
6385 return; 6840 return;
6386 } 6841 }
6387 if (buttons.Length < 1) 6842 if (buttons.Length < 1)
6388 { 6843 {
6389 LSLError("No less than 1 button can be shown"); 6844 buttons.Add("OK");
6390 return;
6391 } 6845 }
6392 if (buttons.Length > 12) 6846 if (buttons.Length > 12)
6393 { 6847 {
@@ -6404,7 +6858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6404 } 6858 }
6405 if (buttons.Data[i].ToString().Length > 24) 6859 if (buttons.Data[i].ToString().Length > 24)
6406 { 6860 {
6407 LSLError("button label cannot be longer than 24 characters"); 6861 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6408 return; 6862 return;
6409 } 6863 }
6410 buts[i] = buttons.Data[i].ToString(); 6864 buts[i] = buttons.Data[i].ToString();
@@ -6468,22 +6922,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6468 } 6922 }
6469 6923
6470 // copy the first script found with this inventory name 6924 // copy the first script found with this inventory name
6471 lock (m_host.TaskInventory) 6925 TaskInventoryItem scriptItem = null;
6926 m_host.TaskInventory.LockItemsForRead(true);
6927 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6472 { 6928 {
6473 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6929 if (inv.Value.Name == name)
6474 { 6930 {
6475 if (inv.Value.Name == name) 6931 // make sure the object is a script
6932 if (10 == inv.Value.Type)
6476 { 6933 {
6477 // make sure the object is a script 6934 found = true;
6478 if (10 == inv.Value.Type) 6935 srcId = inv.Key;
6479 { 6936 scriptItem = inv.Value;
6480 found = true; 6937 break;
6481 srcId = inv.Key;
6482 break;
6483 }
6484 } 6938 }
6485 } 6939 }
6486 } 6940 }
6941 m_host.TaskInventory.LockItemsForRead(false);
6487 6942
6488 if (!found) 6943 if (!found)
6489 { 6944 {
@@ -6491,8 +6946,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6491 return; 6946 return;
6492 } 6947 }
6493 6948
6494 // the rest of the permission checks are done in RezScript, so check the pin there as well 6949 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6495 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6950 if (dest != null)
6951 {
6952 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6953 {
6954 // the rest of the permission checks are done in RezScript, so check the pin there as well
6955 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6956
6957 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6958 m_host.Inventory.RemoveInventoryItem(srcId);
6959 }
6960 }
6496 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6961 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6497 ScriptSleep(3000); 6962 ScriptSleep(3000);
6498 } 6963 }
@@ -6555,18 +7020,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6555 public LSL_String llMD5String(string src, int nonce) 7020 public LSL_String llMD5String(string src, int nonce)
6556 { 7021 {
6557 m_host.AddScriptLPS(1); 7022 m_host.AddScriptLPS(1);
6558 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7023 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6559 } 7024 }
6560 7025
6561 public LSL_String llSHA1String(string src) 7026 public LSL_String llSHA1String(string src)
6562 { 7027 {
6563 m_host.AddScriptLPS(1); 7028 m_host.AddScriptLPS(1);
6564 return Util.SHA1Hash(src).ToLower(); 7029 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6565 } 7030 }
6566 7031
6567 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7032 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6568 { 7033 {
6569 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7034 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7035 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7036 return shapeBlock;
6570 7037
6571 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7038 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6572 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7039 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6642,6 +7109,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6642 7109
6643 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7110 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6644 { 7111 {
7112 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7113 return;
7114
6645 ObjectShapePacket.ObjectDataBlock shapeBlock; 7115 ObjectShapePacket.ObjectDataBlock shapeBlock;
6646 7116
6647 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7117 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6691,6 +7161,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6691 7161
6692 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7162 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6693 { 7163 {
7164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7165 return;
7166
6694 ObjectShapePacket.ObjectDataBlock shapeBlock; 7167 ObjectShapePacket.ObjectDataBlock shapeBlock;
6695 7168
6696 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7169 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6733,6 +7206,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6733 7206
6734 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) 7207 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)
6735 { 7208 {
7209 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7210 return;
7211
6736 ObjectShapePacket.ObjectDataBlock shapeBlock; 7212 ObjectShapePacket.ObjectDataBlock shapeBlock;
6737 7213
6738 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7214 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6859,6 +7335,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6859 7335
6860 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7336 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6861 { 7337 {
7338 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7339 return;
7340
6862 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7341 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6863 UUID sculptId; 7342 UUID sculptId;
6864 7343
@@ -6874,13 +7353,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6874 shapeBlock.PathScaleX = 100; 7353 shapeBlock.PathScaleX = 100;
6875 shapeBlock.PathScaleY = 150; 7354 shapeBlock.PathScaleY = 150;
6876 7355
6877 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7356 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6878 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7357 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6879 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7358 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6880 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7359 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6881 { 7360 {
6882 // default 7361 // default
6883 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7362 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6884 } 7363 }
6885 7364
6886 // retain pathcurve 7365 // retain pathcurve
@@ -6899,32 +7378,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6899 ScriptSleep(200); 7378 ScriptSleep(200);
6900 } 7379 }
6901 7380
6902 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7381 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6903 { 7382 {
6904 m_host.AddScriptLPS(1); 7383 m_host.AddScriptLPS(1);
6905 7384
6906 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7385 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7386 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7387 if (parts.Count>0)
7388 {
7389 try
7390 {
7391 parts[0].ParentGroup.areUpdatesSuspended = true;
7392 foreach (SceneObjectPart part in parts)
7393 SetPrimParams(part, rules);
7394 }
7395 finally
7396 {
7397 parts[0].ParentGroup.areUpdatesSuspended = false;
7398 }
7399 }
7400 if (avatars.Count > 0)
7401 {
7402 foreach (ScenePresence avatar in avatars)
7403 SetPrimParams(avatar, rules);
7404 }
7405 }
6907 7406
6908 foreach (SceneObjectPart part in parts) 7407 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6909 SetPrimParams(part, rules); 7408 {
6910 7409 llSetLinkPrimitiveParamsFast(linknumber, rules);
6911 ScriptSleep(200); 7410 ScriptSleep(200);
6912 } 7411 }
6913 7412
6914 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7413 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6915 { 7414 {
6916 m_host.AddScriptLPS(1); 7415 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7416 //We only support PRIM_POSITION and PRIM_ROTATION
6917 7417
6918 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7418 int idx = 0;
6919 7419
6920 foreach (SceneObjectPart part in parts) 7420 while (idx < rules.Length)
6921 SetPrimParams(part, rules); 7421 {
7422 int code = rules.GetLSLIntegerItem(idx++);
7423
7424 int remain = rules.Length - idx;
7425
7426
7427
7428 switch (code)
7429 {
7430 case (int)ScriptBaseClass.PRIM_POSITION:
7431 if (remain < 1)
7432 return;
7433 LSL_Vector v;
7434 v = rules.GetVector3Item(idx++);
7435 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7436 av.SendAvatarDataToAllAgents();
7437
7438 break;
7439
7440 case (int)ScriptBaseClass.PRIM_ROTATION:
7441 if (remain < 1)
7442 return;
7443 LSL_Rotation r;
7444 r = rules.GetQuaternionItem(idx++);
7445 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7446 av.SendAvatarDataToAllAgents();
7447 break;
7448 }
7449 }
6922 } 7450 }
6923 7451
6924 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7452 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6925 { 7453 {
7454 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7455 return;
7456
6926 int idx = 0; 7457 int idx = 0;
6927 7458
7459 bool positionChanged = false;
7460 LSL_Vector currentPosition = GetPartLocalPos(part);
7461
6928 while (idx < rules.Length) 7462 while (idx < rules.Length)
6929 { 7463 {
6930 int code = rules.GetLSLIntegerItem(idx++); 7464 int code = rules.GetLSLIntegerItem(idx++);
@@ -6933,7 +7467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6933 7467
6934 int face; 7468 int face;
6935 LSL_Vector v; 7469 LSL_Vector v;
6936 7470
6937 switch (code) 7471 switch (code)
6938 { 7472 {
6939 case (int)ScriptBaseClass.PRIM_POSITION: 7473 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6941,7 +7475,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 return; 7475 return;
6942 7476
6943 v=rules.GetVector3Item(idx++); 7477 v=rules.GetVector3Item(idx++);
6944 SetPos(part, v); 7478 positionChanged = true;
7479 currentPosition = GetSetPosTarget(part, v, currentPosition);
6945 7480
6946 break; 7481 break;
6947 case (int)ScriptBaseClass.PRIM_SIZE: 7482 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7309,6 +7844,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7309 break; 7844 break;
7310 } 7845 }
7311 } 7846 }
7847
7848 if (positionChanged)
7849 {
7850 if (part.ParentGroup.RootPart == part)
7851 {
7852 SceneObjectGroup parent = part.ParentGroup;
7853 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7854 }
7855 else
7856 {
7857 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7858 SceneObjectGroup parent = part.ParentGroup;
7859 parent.HasGroupChanged = true;
7860 parent.ScheduleGroupForTerseUpdate();
7861 }
7862 }
7312 } 7863 }
7313 7864
7314 public LSL_String llStringToBase64(string str) 7865 public LSL_String llStringToBase64(string str)
@@ -7457,13 +8008,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7457 public LSL_Integer llGetNumberOfPrims() 8008 public LSL_Integer llGetNumberOfPrims()
7458 { 8009 {
7459 m_host.AddScriptLPS(1); 8010 m_host.AddScriptLPS(1);
7460 int avatarCount = 0; 8011 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7461 World.ForEachScenePresence(delegate(ScenePresence presence) 8012
7462 {
7463 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7464 avatarCount++;
7465 });
7466
7467 return m_host.ParentGroup.PrimCount + avatarCount; 8013 return m_host.ParentGroup.PrimCount + avatarCount;
7468 } 8014 }
7469 8015
@@ -7479,55 +8025,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7479 m_host.AddScriptLPS(1); 8025 m_host.AddScriptLPS(1);
7480 UUID objID = UUID.Zero; 8026 UUID objID = UUID.Zero;
7481 LSL_List result = new LSL_List(); 8027 LSL_List result = new LSL_List();
8028
8029 // If the ID is not valid, return null result
7482 if (!UUID.TryParse(obj, out objID)) 8030 if (!UUID.TryParse(obj, out objID))
7483 { 8031 {
7484 result.Add(new LSL_Vector()); 8032 result.Add(new LSL_Vector());
7485 result.Add(new LSL_Vector()); 8033 result.Add(new LSL_Vector());
7486 return result; 8034 return result;
7487 } 8035 }
8036
8037 // Check if this is an attached prim. If so, replace
8038 // the UUID with the avatar UUID and report it's bounding box
8039 SceneObjectPart part = World.GetSceneObjectPart(objID);
8040 if (part != null && part.ParentGroup.IsAttachment)
8041 objID = part.ParentGroup.RootPart.AttachedAvatar;
8042
8043 // Find out if this is an avatar ID. If so, return it's box
7488 ScenePresence presence = World.GetScenePresence(objID); 8044 ScenePresence presence = World.GetScenePresence(objID);
7489 if (presence != null) 8045 if (presence != null)
7490 { 8046 {
7491 if (presence.ParentID == 0) // not sat on an object 8047 // As per LSL Wiki, there is no difference between sitting
8048 // and standing avatar since server 1.36
8049 LSL_Vector lower;
8050 LSL_Vector upper;
8051 if (presence.Animator.Animations.DefaultAnimation.AnimID
8052 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7492 { 8053 {
7493 LSL_Vector lower; 8054 // This is for ground sitting avatars
7494 LSL_Vector upper; 8055 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7495 if (presence.Animator.Animations.DefaultAnimation.AnimID 8056 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7496 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8057 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7497 {
7498 // This is for ground sitting avatars
7499 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7500 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7501 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7502 }
7503 else
7504 {
7505 // This is for standing/flying avatars
7506 float height = presence.Appearance.AvatarHeight / 2.0f;
7507 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7508 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7509 }
7510 result.Add(lower);
7511 result.Add(upper);
7512 return result;
7513 } 8058 }
7514 else 8059 else
7515 { 8060 {
7516 // sitting on an object so we need the bounding box of that 8061 // This is for standing/flying avatars
7517 // which should include the avatar so set the UUID to the 8062 float height = presence.Appearance.AvatarHeight / 2.0f;
7518 // UUID of the object the avatar is sat on and allow it to fall through 8063 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7519 // to processing an object 8064 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7520 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7521 objID = p.UUID;
7522 } 8065 }
8066
8067 // Adjust to the documented error offsets (see LSL Wiki)
8068 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8069 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8070
8071 if (lower.x > upper.x)
8072 lower.x = upper.x;
8073 if (lower.y > upper.y)
8074 lower.y = upper.y;
8075 if (lower.z > upper.z)
8076 lower.z = upper.z;
8077
8078 result.Add(lower);
8079 result.Add(upper);
8080 return result;
7523 } 8081 }
7524 SceneObjectPart part = World.GetSceneObjectPart(objID); 8082
8083 part = World.GetSceneObjectPart(objID);
7525 // Currently only works for single prims without a sitting avatar 8084 // Currently only works for single prims without a sitting avatar
7526 if (part != null) 8085 if (part != null)
7527 { 8086 {
7528 Vector3 halfSize = part.Scale / 2.0f; 8087 float minX;
7529 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8088 float maxX;
7530 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8089 float minY;
8090 float maxY;
8091 float minZ;
8092 float maxZ;
8093
8094 // This BBox is in sim coordinates, with the offset being
8095 // a contained point.
8096 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8097 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8098
8099 minX -= offsets[0].X;
8100 maxX -= offsets[0].X;
8101 minY -= offsets[0].Y;
8102 maxY -= offsets[0].Y;
8103 minZ -= offsets[0].Z;
8104 maxZ -= offsets[0].Z;
8105
8106 LSL_Vector lower;
8107 LSL_Vector upper;
8108
8109 // Adjust to the documented error offsets (see LSL Wiki)
8110 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8111 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8112
8113 if (lower.x > upper.x)
8114 lower.x = upper.x;
8115 if (lower.y > upper.y)
8116 lower.y = upper.y;
8117 if (lower.z > upper.z)
8118 lower.z = upper.z;
8119
7531 result.Add(lower); 8120 result.Add(lower);
7532 result.Add(upper); 8121 result.Add(upper);
7533 return result; 8122 return result;
@@ -7607,13 +8196,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7607 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8196 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7608 part.AbsolutePosition.Y, 8197 part.AbsolutePosition.Y,
7609 part.AbsolutePosition.Z); 8198 part.AbsolutePosition.Z);
7610 // For some reason, the part.AbsolutePosition.* values do not change if the
7611 // linkset is rotated; they always reflect the child prim's world position
7612 // as though the linkset is unrotated. This is incompatible behavior with SL's
7613 // implementation, so will break scripts imported from there (not to mention it
7614 // makes it more difficult to determine a child prim's actual inworld position).
7615 if (part.ParentID != 0)
7616 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7617 res.Add(v); 8199 res.Add(v);
7618 break; 8200 break;
7619 8201
@@ -7774,56 +8356,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7774 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8356 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7775 if (remain < 1) 8357 if (remain < 1)
7776 return res; 8358 return res;
7777 8359 face = (int)rules.GetLSLIntegerItem(idx++);
7778 face=(int)rules.GetLSLIntegerItem(idx++);
7779 8360
7780 tex = part.Shape.Textures; 8361 tex = part.Shape.Textures;
8362 int shiny;
7781 if (face == ScriptBaseClass.ALL_SIDES) 8363 if (face == ScriptBaseClass.ALL_SIDES)
7782 { 8364 {
7783 for (face = 0; face < GetNumberOfSides(part); face++) 8365 for (face = 0; face < GetNumberOfSides(part); face++)
7784 { 8366 {
7785 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8367 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7786 // Convert Shininess to PRIM_SHINY_* 8368 if (shinyness == Shininess.High)
7787 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8369 {
7788 // PRIM_BUMP_* 8370 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7789 res.Add(new LSL_Integer((int)texface.Bump)); 8371 }
8372 else if (shinyness == Shininess.Medium)
8373 {
8374 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8375 }
8376 else if (shinyness == Shininess.Low)
8377 {
8378 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8379 }
8380 else
8381 {
8382 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8383 }
8384 res.Add(new LSL_Integer(shiny));
8385 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7790 } 8386 }
7791 } 8387 }
7792 else 8388 else
7793 { 8389 {
7794 if (face >= 0 && face < GetNumberOfSides(part)) 8390 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8391 if (shinyness == Shininess.High)
7795 { 8392 {
7796 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8393 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7797 // Convert Shininess to PRIM_SHINY_* 8394 }
7798 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8395 else if (shinyness == Shininess.Medium)
7799 // PRIM_BUMP_* 8396 {
7800 res.Add(new LSL_Integer((int)texface.Bump)); 8397 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8398 }
8399 else if (shinyness == Shininess.Low)
8400 {
8401 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8402 }
8403 else
8404 {
8405 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7801 } 8406 }
8407 res.Add(new LSL_Integer(shiny));
8408 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7802 } 8409 }
7803 break; 8410 break;
7804 8411
7805 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8412 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7806 if (remain < 1) 8413 if (remain < 1)
7807 return res; 8414 return res;
7808 8415 face = (int)rules.GetLSLIntegerItem(idx++);
7809 face=(int)rules.GetLSLIntegerItem(idx++);
7810 8416
7811 tex = part.Shape.Textures; 8417 tex = part.Shape.Textures;
8418 int fullbright;
7812 if (face == ScriptBaseClass.ALL_SIDES) 8419 if (face == ScriptBaseClass.ALL_SIDES)
7813 { 8420 {
7814 for (face = 0; face < GetNumberOfSides(part); face++) 8421 for (face = 0; face < GetNumberOfSides(part); face++)
7815 { 8422 {
7816 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8423 if (tex.GetFace((uint)face).Fullbright == true)
7817 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8424 {
8425 fullbright = ScriptBaseClass.TRUE;
8426 }
8427 else
8428 {
8429 fullbright = ScriptBaseClass.FALSE;
8430 }
8431 res.Add(new LSL_Integer(fullbright));
7818 } 8432 }
7819 } 8433 }
7820 else 8434 else
7821 { 8435 {
7822 if (face >= 0 && face < GetNumberOfSides(part)) 8436 if (tex.GetFace((uint)face).Fullbright == true)
7823 { 8437 {
7824 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8438 fullbright = ScriptBaseClass.TRUE;
7825 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8439 }
8440 else
8441 {
8442 fullbright = ScriptBaseClass.FALSE;
7826 } 8443 }
8444 res.Add(new LSL_Integer(fullbright));
7827 } 8445 }
7828 break; 8446 break;
7829 8447
@@ -7845,27 +8463,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7845 break; 8463 break;
7846 8464
7847 case (int)ScriptBaseClass.PRIM_TEXGEN: 8465 case (int)ScriptBaseClass.PRIM_TEXGEN:
8466 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7848 if (remain < 1) 8467 if (remain < 1)
7849 return res; 8468 return res;
7850 8469 face = (int)rules.GetLSLIntegerItem(idx++);
7851 face=(int)rules.GetLSLIntegerItem(idx++);
7852 8470
7853 tex = part.Shape.Textures; 8471 tex = part.Shape.Textures;
7854 if (face == ScriptBaseClass.ALL_SIDES) 8472 if (face == ScriptBaseClass.ALL_SIDES)
7855 { 8473 {
7856 for (face = 0; face < GetNumberOfSides(part); face++) 8474 for (face = 0; face < GetNumberOfSides(part); face++)
7857 { 8475 {
7858 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8476 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7859 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8477 {
7860 res.Add(new LSL_Integer((uint)texgen >> 1)); 8478 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8479 }
8480 else
8481 {
8482 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8483 }
7861 } 8484 }
7862 } 8485 }
7863 else 8486 else
7864 { 8487 {
7865 if (face >= 0 && face < GetNumberOfSides(part)) 8488 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8489 {
8490 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8491 }
8492 else
7866 { 8493 {
7867 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8494 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7868 res.Add(new LSL_Integer((uint)texgen >> 1));
7869 } 8495 }
7870 } 8496 }
7871 break; 8497 break;
@@ -7888,28 +8514,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7888 case (int)ScriptBaseClass.PRIM_GLOW: 8514 case (int)ScriptBaseClass.PRIM_GLOW:
7889 if (remain < 1) 8515 if (remain < 1)
7890 return res; 8516 return res;
7891 8517 face = (int)rules.GetLSLIntegerItem(idx++);
7892 face=(int)rules.GetLSLIntegerItem(idx++);
7893 8518
7894 tex = part.Shape.Textures; 8519 tex = part.Shape.Textures;
8520 float primglow;
7895 if (face == ScriptBaseClass.ALL_SIDES) 8521 if (face == ScriptBaseClass.ALL_SIDES)
7896 { 8522 {
7897 for (face = 0; face < GetNumberOfSides(part); face++) 8523 for (face = 0; face < GetNumberOfSides(part); face++)
7898 { 8524 {
7899 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8525 primglow = tex.GetFace((uint)face).Glow;
7900 res.Add(new LSL_Float(texface.Glow)); 8526 res.Add(new LSL_Float(primglow));
7901 } 8527 }
7902 } 8528 }
7903 else 8529 else
7904 { 8530 {
7905 if (face >= 0 && face < GetNumberOfSides(part)) 8531 primglow = tex.GetFace((uint)face).Glow;
7906 { 8532 res.Add(new LSL_Float(primglow));
7907 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7908 res.Add(new LSL_Float(texface.Glow));
7909 }
7910 } 8533 }
7911 break; 8534 break;
7912
7913 case (int)ScriptBaseClass.PRIM_TEXT: 8535 case (int)ScriptBaseClass.PRIM_TEXT:
7914 Color4 textColor = part.GetTextColor(); 8536 Color4 textColor = part.GetTextColor();
7915 res.Add(part.Text); 8537 res.Add(part.Text);
@@ -8458,8 +9080,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8458 // The function returns an ordered list 9080 // The function returns an ordered list
8459 // representing the tokens found in the supplied 9081 // representing the tokens found in the supplied
8460 // sources string. If two successive tokenizers 9082 // sources string. If two successive tokenizers
8461 // are encountered, then a NULL entry is added 9083 // are encountered, then a null-string entry is
8462 // to the list. 9084 // added to the list.
8463 // 9085 //
8464 // It is a precondition that the source and 9086 // It is a precondition that the source and
8465 // toekizer lisst are non-null. If they are null, 9087 // toekizer lisst are non-null. If they are null,
@@ -8467,7 +9089,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8467 // while their lengths are being determined. 9089 // while their lengths are being determined.
8468 // 9090 //
8469 // A small amount of working memoryis required 9091 // A small amount of working memoryis required
8470 // of approximately 8*#tokenizers. 9092 // of approximately 8*#tokenizers + 8*srcstrlen.
8471 // 9093 //
8472 // There are many ways in which this function 9094 // There are many ways in which this function
8473 // can be implemented, this implementation is 9095 // can be implemented, this implementation is
@@ -8483,155 +9105,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8483 // and eliminates redundant tokenizers as soon 9105 // and eliminates redundant tokenizers as soon
8484 // as is possible. 9106 // as is possible.
8485 // 9107 //
8486 // The implementation tries to avoid any copying 9108 // The implementation tries to minimize temporary
8487 // of arrays or other objects. 9109 // garbage generation.
8488 // </remarks> 9110 // </remarks>
8489 9111
8490 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9112 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8491 { 9113 {
8492 int beginning = 0; 9114 return ParseString2List(src, separators, spacers, true);
8493 int srclen = src.Length; 9115 }
8494 int seplen = separators.Length;
8495 object[] separray = separators.Data;
8496 int spclen = spacers.Length;
8497 object[] spcarray = spacers.Data;
8498 int mlen = seplen+spclen;
8499
8500 int[] offset = new int[mlen+1];
8501 bool[] active = new bool[mlen];
8502
8503 int best;
8504 int j;
8505
8506 // Initial capacity reduces resize cost
8507 9116
8508 LSL_List tokens = new LSL_List(); 9117 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9118 {
9119 int srclen = src.Length;
9120 int seplen = separators.Length;
9121 object[] separray = separators.Data;
9122 int spclen = spacers.Length;
9123 object[] spcarray = spacers.Data;
9124 int dellen = 0;
9125 string[] delarray = new string[seplen+spclen];
8509 9126
8510 // All entries are initially valid 9127 int outlen = 0;
9128 string[] outarray = new string[srclen*2+1];
8511 9129
8512 for (int i = 0; i < mlen; i++) 9130 int i, j;
8513 active[i] = true; 9131 string d;
8514 9132
8515 offset[mlen] = srclen; 9133 m_host.AddScriptLPS(1);
8516 9134
8517 while (beginning < srclen) 9135 /*
9136 * Convert separator and spacer lists to C# strings.
9137 * Also filter out null strings so we don't hang.
9138 */
9139 for (i = 0; i < seplen; i ++)
8518 { 9140 {
9141 d = separray[i].ToString();
9142 if (d.Length > 0)
9143 {
9144 delarray[dellen++] = d;
9145 }
9146 }
9147 seplen = dellen;
8519 9148
8520 best = mlen; // as bad as it gets 9149 for (i = 0; i < spclen; i ++)
9150 {
9151 d = spcarray[i].ToString();
9152 if (d.Length > 0)
9153 {
9154 delarray[dellen++] = d;
9155 }
9156 }
8521 9157
8522 // Scan for separators 9158 /*
9159 * Scan through source string from beginning to end.
9160 */
9161 for (i = 0;;)
9162 {
8523 9163
8524 for (j = 0; j < seplen; j++) 9164 /*
9165 * Find earliest delimeter in src starting at i (if any).
9166 */
9167 int earliestDel = -1;
9168 int earliestSrc = srclen;
9169 string earliestStr = null;
9170 for (j = 0; j < dellen; j ++)
8525 { 9171 {
8526 if (separray[j].ToString() == String.Empty) 9172 d = delarray[j];
8527 active[j] = false; 9173 if (d != null)
8528
8529 if (active[j])
8530 { 9174 {
8531 // scan all of the markers 9175 int index = src.IndexOf(d, i);
8532 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9176 if (index < 0)
8533 { 9177 {
8534 // not present at all 9178 delarray[j] = null; // delim nowhere in src, don't check it anymore
8535 active[j] = false;
8536 } 9179 }
8537 else 9180 else if (index < earliestSrc)
8538 { 9181 {
8539 // present and correct 9182 earliestSrc = index; // where delimeter starts in source string
8540 if (offset[j] < offset[best]) 9183 earliestDel = j; // where delimeter is in delarray[]
8541 { 9184 earliestStr = d; // the delimeter string from delarray[]
8542 // closest so far 9185 if (index == i) break; // can't do any better than found at beg of string
8543 best = j;
8544 if (offset[best] == beginning)
8545 break;
8546 }
8547 } 9186 }
8548 } 9187 }
8549 } 9188 }
8550 9189
8551 // Scan for spacers 9190 /*
8552 9191 * Output source string starting at i through start of earliest delimeter.
8553 if (offset[best] != beginning) 9192 */
9193 if (keepNulls || (earliestSrc > i))
8554 { 9194 {
8555 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9195 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8556 {
8557 if (spcarray[j-seplen].ToString() == String.Empty)
8558 active[j] = false;
8559
8560 if (active[j])
8561 {
8562 // scan all of the markers
8563 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8564 {
8565 // not present at all
8566 active[j] = false;
8567 }
8568 else
8569 {
8570 // present and correct
8571 if (offset[j] < offset[best])
8572 {
8573 // closest so far
8574 best = j;
8575 }
8576 }
8577 }
8578 }
8579 } 9196 }
8580 9197
8581 // This is the normal exit from the scanning loop 9198 /*
9199 * If no delimeter found at or after i, we're done scanning.
9200 */
9201 if (earliestDel < 0) break;
8582 9202
8583 if (best == mlen) 9203 /*
9204 * If delimeter was a spacer, output the spacer.
9205 */
9206 if (earliestDel >= seplen)
8584 { 9207 {
8585 // no markers were found on this pass 9208 outarray[outlen++] = earliestStr;
8586 // so we're pretty much done
8587 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8588 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8589 break;
8590 } 9209 }
8591 9210
8592 // Otherwise we just add the newly delimited token 9211 /*
8593 // and recalculate where the search should continue. 9212 * Look at rest of src string following delimeter.
8594 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9213 */
8595 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9214 i = earliestSrc + earliestStr.Length;
8596
8597 if (best < seplen)
8598 {
8599 beginning = offset[best] + (separray[best].ToString()).Length;
8600 }
8601 else
8602 {
8603 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8604 string str = spcarray[best - seplen].ToString();
8605 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8606 tokens.Add(new LSL_String(str));
8607 }
8608 } 9215 }
8609 9216
8610 // This an awkward an not very intuitive boundary case. If the 9217 /*
8611 // last substring is a tokenizer, then there is an implied trailing 9218 * Make up an exact-sized output array suitable for an LSL_List object.
8612 // null list entry. Hopefully the single comparison will not be too 9219 */
8613 // arduous. Alternatively the 'break' could be replced with a return 9220 object[] outlist = new object[outlen];
8614 // but that's shabby programming. 9221 for (i = 0; i < outlen; i ++)
8615
8616 if ((beginning == srclen) && (keepNulls))
8617 { 9222 {
8618 if (srclen != 0) 9223 outlist[i] = new LSL_String(outarray[i]);
8619 tokens.Add(new LSL_String(""));
8620 } 9224 }
8621 9225 return new LSL_List(outlist);
8622 return tokens;
8623 }
8624
8625 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8626 {
8627 m_host.AddScriptLPS(1);
8628 return this.ParseString(src, separators, spacers, false);
8629 }
8630
8631 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8632 {
8633 m_host.AddScriptLPS(1);
8634 return this.ParseString(src, separators, spacers, true);
8635 } 9226 }
8636 9227
8637 public LSL_Integer llGetObjectPermMask(int mask) 9228 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8708,28 +9299,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8708 { 9299 {
8709 m_host.AddScriptLPS(1); 9300 m_host.AddScriptLPS(1);
8710 9301
8711 lock (m_host.TaskInventory) 9302 m_host.TaskInventory.LockItemsForRead(true);
9303 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8712 { 9304 {
8713 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9305 if (inv.Value.Name == item)
8714 { 9306 {
8715 if (inv.Value.Name == item) 9307 m_host.TaskInventory.LockItemsForRead(false);
9308 switch (mask)
8716 { 9309 {
8717 switch (mask) 9310 case 0:
8718 { 9311 return (int)inv.Value.BasePermissions;
8719 case 0: 9312 case 1:
8720 return (int)inv.Value.BasePermissions; 9313 return (int)inv.Value.CurrentPermissions;
8721 case 1: 9314 case 2:
8722 return (int)inv.Value.CurrentPermissions; 9315 return (int)inv.Value.GroupPermissions;
8723 case 2: 9316 case 3:
8724 return (int)inv.Value.GroupPermissions; 9317 return (int)inv.Value.EveryonePermissions;
8725 case 3: 9318 case 4:
8726 return (int)inv.Value.EveryonePermissions; 9319 return (int)inv.Value.NextPermissions;
8727 case 4:
8728 return (int)inv.Value.NextPermissions;
8729 }
8730 } 9320 }
8731 } 9321 }
8732 } 9322 }
9323 m_host.TaskInventory.LockItemsForRead(false);
8733 9324
8734 return -1; 9325 return -1;
8735 } 9326 }
@@ -8776,16 +9367,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8776 { 9367 {
8777 m_host.AddScriptLPS(1); 9368 m_host.AddScriptLPS(1);
8778 9369
8779 lock (m_host.TaskInventory) 9370 m_host.TaskInventory.LockItemsForRead(true);
9371 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8780 { 9372 {
8781 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9373 if (inv.Value.Name == item)
8782 { 9374 {
8783 if (inv.Value.Name == item) 9375 m_host.TaskInventory.LockItemsForRead(false);
8784 { 9376 return inv.Value.CreatorID.ToString();
8785 return inv.Value.CreatorID.ToString();
8786 }
8787 } 9377 }
8788 } 9378 }
9379 m_host.TaskInventory.LockItemsForRead(false);
8789 9380
8790 llSay(0, "No item name '" + item + "'"); 9381 llSay(0, "No item name '" + item + "'");
8791 9382
@@ -8933,7 +9524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8933 } 9524 }
8934 9525
8935 /// <summary> 9526 /// <summary>
8936 /// illListReplaceList removes the sub-list defined by the inclusive indices 9527 /// llListReplaceList removes the sub-list defined by the inclusive indices
8937 /// start and end and inserts the src list in its place. The inclusive 9528 /// start and end and inserts the src list in its place. The inclusive
8938 /// nature of the indices means that at least one element must be deleted 9529 /// nature of the indices means that at least one element must be deleted
8939 /// if the indices are within the bounds of the existing list. I.e. 2,2 9530 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8990,16 +9581,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8990 // based upon end. Note that if end exceeds the upper 9581 // based upon end. Note that if end exceeds the upper
8991 // bound in this case, the entire destination list 9582 // bound in this case, the entire destination list
8992 // is removed. 9583 // is removed.
8993 else 9584 else if (start == 0)
8994 { 9585 {
8995 if (end + 1 < dest.Length) 9586 if (end + 1 < dest.Length)
8996 {
8997 return src + dest.GetSublist(end + 1, -1); 9587 return src + dest.GetSublist(end + 1, -1);
8998 }
8999 else 9588 else
9000 {
9001 return src; 9589 return src;
9002 } 9590 }
9591 else // Start < 0
9592 {
9593 if (end + 1 < dest.Length)
9594 return dest.GetSublist(end + 1, -1);
9595 else
9596 return new LSL_List();
9003 } 9597 }
9004 } 9598 }
9005 // Finally, if start > end, we strip away a prefix and 9599 // Finally, if start > end, we strip away a prefix and
@@ -9050,17 +9644,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9050 int width = 0; 9644 int width = 0;
9051 int height = 0; 9645 int height = 0;
9052 9646
9053 ParcelMediaCommandEnum? commandToSend = null; 9647 uint commandToSend = 0;
9054 float time = 0.0f; // default is from start 9648 float time = 0.0f; // default is from start
9055 9649
9056 ScenePresence presence = null; 9650 ScenePresence presence = null;
9057 9651
9058 for (int i = 0; i < commandList.Data.Length; i++) 9652 for (int i = 0; i < commandList.Data.Length; i++)
9059 { 9653 {
9060 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9654 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9061 switch (command) 9655 switch (command)
9062 { 9656 {
9063 case ParcelMediaCommandEnum.Agent: 9657 case (uint)ParcelMediaCommandEnum.Agent:
9064 // we send only to one agent 9658 // we send only to one agent
9065 if ((i + 1) < commandList.Length) 9659 if ((i + 1) < commandList.Length)
9066 { 9660 {
@@ -9077,25 +9671,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9077 } 9671 }
9078 break; 9672 break;
9079 9673
9080 case ParcelMediaCommandEnum.Loop: 9674 case (uint)ParcelMediaCommandEnum.Loop:
9081 loop = 1; 9675 loop = 1;
9082 commandToSend = command; 9676 commandToSend = command;
9083 update = true; //need to send the media update packet to set looping 9677 update = true; //need to send the media update packet to set looping
9084 break; 9678 break;
9085 9679
9086 case ParcelMediaCommandEnum.Play: 9680 case (uint)ParcelMediaCommandEnum.Play:
9087 loop = 0; 9681 loop = 0;
9088 commandToSend = command; 9682 commandToSend = command;
9089 update = true; //need to send the media update packet to make sure it doesn't loop 9683 update = true; //need to send the media update packet to make sure it doesn't loop
9090 break; 9684 break;
9091 9685
9092 case ParcelMediaCommandEnum.Pause: 9686 case (uint)ParcelMediaCommandEnum.Pause:
9093 case ParcelMediaCommandEnum.Stop: 9687 case (uint)ParcelMediaCommandEnum.Stop:
9094 case ParcelMediaCommandEnum.Unload: 9688 case (uint)ParcelMediaCommandEnum.Unload:
9095 commandToSend = command; 9689 commandToSend = command;
9096 break; 9690 break;
9097 9691
9098 case ParcelMediaCommandEnum.Url: 9692 case (uint)ParcelMediaCommandEnum.Url:
9099 if ((i + 1) < commandList.Length) 9693 if ((i + 1) < commandList.Length)
9100 { 9694 {
9101 if (commandList.Data[i + 1] is LSL_String) 9695 if (commandList.Data[i + 1] is LSL_String)
@@ -9108,7 +9702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9108 } 9702 }
9109 break; 9703 break;
9110 9704
9111 case ParcelMediaCommandEnum.Texture: 9705 case (uint)ParcelMediaCommandEnum.Texture:
9112 if ((i + 1) < commandList.Length) 9706 if ((i + 1) < commandList.Length)
9113 { 9707 {
9114 if (commandList.Data[i + 1] is LSL_String) 9708 if (commandList.Data[i + 1] is LSL_String)
@@ -9121,7 +9715,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9121 } 9715 }
9122 break; 9716 break;
9123 9717
9124 case ParcelMediaCommandEnum.Time: 9718 case (uint)ParcelMediaCommandEnum.Time:
9125 if ((i + 1) < commandList.Length) 9719 if ((i + 1) < commandList.Length)
9126 { 9720 {
9127 if (commandList.Data[i + 1] is LSL_Float) 9721 if (commandList.Data[i + 1] is LSL_Float)
@@ -9133,7 +9727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9133 } 9727 }
9134 break; 9728 break;
9135 9729
9136 case ParcelMediaCommandEnum.AutoAlign: 9730 case (uint)ParcelMediaCommandEnum.AutoAlign:
9137 if ((i + 1) < commandList.Length) 9731 if ((i + 1) < commandList.Length)
9138 { 9732 {
9139 if (commandList.Data[i + 1] is LSL_Integer) 9733 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9147,7 +9741,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9147 } 9741 }
9148 break; 9742 break;
9149 9743
9150 case ParcelMediaCommandEnum.Type: 9744 case (uint)ParcelMediaCommandEnum.Type:
9151 if ((i + 1) < commandList.Length) 9745 if ((i + 1) < commandList.Length)
9152 { 9746 {
9153 if (commandList.Data[i + 1] is LSL_String) 9747 if (commandList.Data[i + 1] is LSL_String)
@@ -9160,7 +9754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9160 } 9754 }
9161 break; 9755 break;
9162 9756
9163 case ParcelMediaCommandEnum.Desc: 9757 case (uint)ParcelMediaCommandEnum.Desc:
9164 if ((i + 1) < commandList.Length) 9758 if ((i + 1) < commandList.Length)
9165 { 9759 {
9166 if (commandList.Data[i + 1] is LSL_String) 9760 if (commandList.Data[i + 1] is LSL_String)
@@ -9173,7 +9767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9173 } 9767 }
9174 break; 9768 break;
9175 9769
9176 case ParcelMediaCommandEnum.Size: 9770 case (uint)ParcelMediaCommandEnum.Size:
9177 if ((i + 2) < commandList.Length) 9771 if ((i + 2) < commandList.Length)
9178 { 9772 {
9179 if (commandList.Data[i + 1] is LSL_Integer) 9773 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9243,7 +9837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9243 } 9837 }
9244 } 9838 }
9245 9839
9246 if (commandToSend != null) 9840 if (commandToSend != 0)
9247 { 9841 {
9248 // the commandList contained a start/stop/... command, too 9842 // the commandList contained a start/stop/... command, too
9249 if (presence == null) 9843 if (presence == null)
@@ -9280,7 +9874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9280 9874
9281 if (aList.Data[i] != null) 9875 if (aList.Data[i] != null)
9282 { 9876 {
9283 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9877 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9284 { 9878 {
9285 case ParcelMediaCommandEnum.Url: 9879 case ParcelMediaCommandEnum.Url:
9286 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9880 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9323,16 +9917,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 { 9917 {
9324 m_host.AddScriptLPS(1); 9918 m_host.AddScriptLPS(1);
9325 9919
9326 lock (m_host.TaskInventory) 9920 m_host.TaskInventory.LockItemsForRead(true);
9921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9327 { 9922 {
9328 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9923 if (inv.Value.Name == name)
9329 { 9924 {
9330 if (inv.Value.Name == name) 9925 m_host.TaskInventory.LockItemsForRead(false);
9331 { 9926 return inv.Value.Type;
9332 return inv.Value.Type;
9333 }
9334 } 9927 }
9335 } 9928 }
9929 m_host.TaskInventory.LockItemsForRead(false);
9336 9930
9337 return -1; 9931 return -1;
9338 } 9932 }
@@ -9343,15 +9937,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9343 9937
9344 if (quick_pay_buttons.Data.Length < 4) 9938 if (quick_pay_buttons.Data.Length < 4)
9345 { 9939 {
9346 LSLError("List must have at least 4 elements"); 9940 int x;
9347 return; 9941 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9942 {
9943 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9944 }
9348 } 9945 }
9349 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9946 int[] nPrice = new int[5];
9350 9947 nPrice[0] = price;
9351 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9948 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9352 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9949 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9353 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9950 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9354 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9951 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9952 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9355 m_host.ParentGroup.HasGroupChanged = true; 9953 m_host.ParentGroup.HasGroupChanged = true;
9356 } 9954 }
9357 9955
@@ -9363,17 +9961,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9363 if (invItemID == UUID.Zero) 9961 if (invItemID == UUID.Zero)
9364 return new LSL_Vector(); 9962 return new LSL_Vector();
9365 9963
9366 lock (m_host.TaskInventory) 9964 m_host.TaskInventory.LockItemsForRead(true);
9965 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9367 { 9966 {
9368 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9967 m_host.TaskInventory.LockItemsForRead(false);
9369 return new LSL_Vector(); 9968 return new LSL_Vector();
9969 }
9370 9970
9371 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9971 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9372 { 9972 {
9373 ShoutError("No permissions to track the camera"); 9973 ShoutError("No permissions to track the camera");
9374 return new LSL_Vector(); 9974 m_host.TaskInventory.LockItemsForRead(false);
9375 } 9975 return new LSL_Vector();
9376 } 9976 }
9977 m_host.TaskInventory.LockItemsForRead(false);
9377 9978
9378 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9979 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9379 if (presence != null) 9980 if (presence != null)
@@ -9391,17 +9992,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9391 if (invItemID == UUID.Zero) 9992 if (invItemID == UUID.Zero)
9392 return new LSL_Rotation(); 9993 return new LSL_Rotation();
9393 9994
9394 lock (m_host.TaskInventory) 9995 m_host.TaskInventory.LockItemsForRead(true);
9996 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9395 { 9997 {
9396 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9998 m_host.TaskInventory.LockItemsForRead(false);
9397 return new LSL_Rotation(); 9999 return new LSL_Rotation();
9398 10000 }
9399 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10001 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9400 { 10002 {
9401 ShoutError("No permissions to track the camera"); 10003 ShoutError("No permissions to track the camera");
9402 return new LSL_Rotation(); 10004 m_host.TaskInventory.LockItemsForRead(false);
9403 } 10005 return new LSL_Rotation();
9404 } 10006 }
10007 m_host.TaskInventory.LockItemsForRead(false);
9405 10008
9406 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10009 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9407 if (presence != null) 10010 if (presence != null)
@@ -9463,8 +10066,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9463 { 10066 {
9464 m_host.AddScriptLPS(1); 10067 m_host.AddScriptLPS(1);
9465 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10068 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9466 if (detectedParams == null) return; // only works on the first detected avatar 10069 if (detectedParams == null)
9467 10070 {
10071 if (m_host.IsAttachment == true)
10072 {
10073 detectedParams = new DetectParams();
10074 detectedParams.Key = m_host.OwnerID;
10075 }
10076 else
10077 {
10078 return;
10079 }
10080 }
10081
9468 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10082 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9469 if (avatar != null) 10083 if (avatar != null)
9470 { 10084 {
@@ -9472,6 +10086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9472 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10086 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9473 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10087 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9474 } 10088 }
10089
9475 ScriptSleep(1000); 10090 ScriptSleep(1000);
9476 } 10091 }
9477 10092
@@ -9564,14 +10179,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9564 if (objectID == UUID.Zero) return; 10179 if (objectID == UUID.Zero) return;
9565 10180
9566 UUID agentID; 10181 UUID agentID;
9567 lock (m_host.TaskInventory) 10182 m_host.TaskInventory.LockItemsForRead(true);
9568 { 10183 // we need the permission first, to know which avatar we want to set the camera for
9569 // we need the permission first, to know which avatar we want to set the camera for 10184 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9570 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9571 10185
9572 if (agentID == UUID.Zero) return; 10186 if (agentID == UUID.Zero)
9573 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10187 {
10188 m_host.TaskInventory.LockItemsForRead(false);
10189 return;
10190 }
10191 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10192 {
10193 m_host.TaskInventory.LockItemsForRead(false);
10194 return;
9574 } 10195 }
10196 m_host.TaskInventory.LockItemsForRead(false);
9575 10197
9576 ScenePresence presence = World.GetScenePresence(agentID); 10198 ScenePresence presence = World.GetScenePresence(agentID);
9577 10199
@@ -9580,12 +10202,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9580 10202
9581 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10203 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9582 object[] data = rules.Data; 10204 object[] data = rules.Data;
9583 for (int i = 0; i < data.Length; ++i) { 10205 for (int i = 0; i < data.Length; ++i)
10206 {
9584 int type = Convert.ToInt32(data[i++].ToString()); 10207 int type = Convert.ToInt32(data[i++].ToString());
9585 if (i >= data.Length) break; // odd number of entries => ignore the last 10208 if (i >= data.Length) break; // odd number of entries => ignore the last
9586 10209
9587 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10210 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9588 switch (type) { 10211 switch (type)
10212 {
9589 case ScriptBaseClass.CAMERA_FOCUS: 10213 case ScriptBaseClass.CAMERA_FOCUS:
9590 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10214 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9591 case ScriptBaseClass.CAMERA_POSITION: 10215 case ScriptBaseClass.CAMERA_POSITION:
@@ -9621,12 +10245,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9621 10245
9622 // we need the permission first, to know which avatar we want to clear the camera for 10246 // we need the permission first, to know which avatar we want to clear the camera for
9623 UUID agentID; 10247 UUID agentID;
9624 lock (m_host.TaskInventory) 10248 m_host.TaskInventory.LockItemsForRead(true);
10249 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10250 if (agentID == UUID.Zero)
10251 {
10252 m_host.TaskInventory.LockItemsForRead(false);
10253 return;
10254 }
10255 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9625 { 10256 {
9626 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10257 m_host.TaskInventory.LockItemsForRead(false);
9627 if (agentID == UUID.Zero) return; 10258 return;
9628 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9629 } 10259 }
10260 m_host.TaskInventory.LockItemsForRead(false);
9630 10261
9631 ScenePresence presence = World.GetScenePresence(agentID); 10262 ScenePresence presence = World.GetScenePresence(agentID);
9632 10263
@@ -9693,19 +10324,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9693 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10324 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9694 { 10325 {
9695 m_host.AddScriptLPS(1); 10326 m_host.AddScriptLPS(1);
9696 string ret = String.Empty; 10327
9697 string src1 = llBase64ToString(str1); 10328 if (str1 == String.Empty)
9698 string src2 = llBase64ToString(str2); 10329 return String.Empty;
9699 int c = 0; 10330 if (str2 == String.Empty)
9700 for (int i = 0; i < src1.Length; i++) 10331 return str1;
10332
10333 int len = str2.Length;
10334 if ((len % 4) != 0) // LL is EVIL!!!!
10335 {
10336 while (str2.EndsWith("="))
10337 str2 = str2.Substring(0, str2.Length - 1);
10338
10339 len = str2.Length;
10340 int mod = len % 4;
10341
10342 if (mod == 1)
10343 str2 = str2.Substring(0, str2.Length - 1);
10344 else if (mod == 2)
10345 str2 += "==";
10346 else if (mod == 3)
10347 str2 += "=";
10348 }
10349
10350 byte[] data1;
10351 byte[] data2;
10352 try
10353 {
10354 data1 = Convert.FromBase64String(str1);
10355 data2 = Convert.FromBase64String(str2);
10356 }
10357 catch (Exception)
9701 { 10358 {
9702 ret += (char) (src1[i] ^ src2[c]); 10359 return new LSL_String(String.Empty);
10360 }
9703 10361
9704 c++; 10362 byte[] d2 = new Byte[data1.Length];
9705 if (c >= src2.Length) 10363 int pos = 0;
9706 c = 0; 10364
10365 if (data1.Length <= data2.Length)
10366 {
10367 Array.Copy(data2, 0, d2, 0, data1.Length);
9707 } 10368 }
9708 return llStringToBase64(ret); 10369 else
10370 {
10371 while (pos < data1.Length)
10372 {
10373 len = data1.Length - pos;
10374 if (len > data2.Length)
10375 len = data2.Length;
10376
10377 Array.Copy(data2, 0, d2, pos, len);
10378 pos += len;
10379 }
10380 }
10381
10382 for (pos = 0 ; pos < data1.Length ; pos++ )
10383 data1[pos] ^= d2[pos];
10384
10385 return Convert.ToBase64String(data1);
9709 } 10386 }
9710 10387
9711 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10388 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9764,12 +10441,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9764 Regex r = new Regex(authregex); 10441 Regex r = new Regex(authregex);
9765 int[] gnums = r.GetGroupNumbers(); 10442 int[] gnums = r.GetGroupNumbers();
9766 Match m = r.Match(url); 10443 Match m = r.Match(url);
9767 if (m.Success) { 10444 if (m.Success)
9768 for (int i = 1; i < gnums.Length; i++) { 10445 {
10446 for (int i = 1; i < gnums.Length; i++)
10447 {
9769 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10448 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9770 //CaptureCollection cc = g.Captures; 10449 //CaptureCollection cc = g.Captures;
9771 } 10450 }
9772 if (m.Groups.Count == 5) { 10451 if (m.Groups.Count == 5)
10452 {
9773 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10453 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9774 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10454 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9775 } 10455 }
@@ -9881,7 +10561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9881 { 10561 {
9882 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10562 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9883 { 10563 {
9884 ret.Add(detectedParams.Key.ToString()); 10564 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9885 ret.Add(detectedParams.Value); 10565 ret.Add(detectedParams.Value);
9886 } 10566 }
9887 } 10567 }
@@ -10050,15 +10730,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10050 10730
10051 internal UUID ScriptByName(string name) 10731 internal UUID ScriptByName(string name)
10052 { 10732 {
10053 lock (m_host.TaskInventory) 10733 m_host.TaskInventory.LockItemsForRead(true);
10734
10735 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10054 { 10736 {
10055 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10737 if (item.Type == 10 && item.Name == name)
10056 { 10738 {
10057 if (item.Type == 10 && item.Name == name) 10739 m_host.TaskInventory.LockItemsForRead(false);
10058 return item.ItemID; 10740 return item.ItemID;
10059 } 10741 }
10060 } 10742 }
10061 10743
10744 m_host.TaskInventory.LockItemsForRead(false);
10745
10062 return UUID.Zero; 10746 return UUID.Zero;
10063 } 10747 }
10064 10748
@@ -10099,6 +10783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10099 { 10783 {
10100 m_host.AddScriptLPS(1); 10784 m_host.AddScriptLPS(1);
10101 10785
10786 //Clone is thread safe
10102 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10787 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10103 10788
10104 UUID assetID = UUID.Zero; 10789 UUID assetID = UUID.Zero;
@@ -10161,6 +10846,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10161 { 10846 {
10162 m_host.AddScriptLPS(1); 10847 m_host.AddScriptLPS(1);
10163 10848
10849 //Clone is thread safe
10164 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10850 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10165 10851
10166 UUID assetID = UUID.Zero; 10852 UUID assetID = UUID.Zero;
@@ -10241,15 +10927,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10241 return GetLinkPrimitiveParams(obj, rules); 10927 return GetLinkPrimitiveParams(obj, rules);
10242 } 10928 }
10243 10929
10244 public void print(string str) 10930 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10245 { 10931 {
10246 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10932 List<SceneObjectPart> parts = GetLinkParts(link);
10247 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10933 if (parts.Count < 1)
10248 if (ossl != null) 10934 return 0;
10249 { 10935
10250 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10936 return GetNumberOfSides(parts[0]);
10251 m_log.Info("LSL print():" + str);
10252 }
10253 } 10937 }
10254 10938
10255 private string Name2Username(string name) 10939 private string Name2Username(string name)
@@ -10295,6 +10979,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10295 return rq.ToString(); 10979 return rq.ToString();
10296 } 10980 }
10297 10981
10982 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
10983 {
10984 m_SayShoutCount = 0;
10985 }
10986
10298 #region Not Implemented 10987 #region Not Implemented
10299 // 10988 //
10300 // Listing the unimplemented lsl functions here, please move 10989 // Listing the unimplemented lsl functions here, please move
@@ -10321,7 +11010,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10321 11010
10322 } 11011 }
10323 11012
10324 public void llGetUsedMemory() 11013 public virtual void llGetUsedMemory()
10325 { 11014 {
10326 m_host.AddScriptLPS(1); 11015 m_host.AddScriptLPS(1);
10327 NotImplemented("llGetUsedMemory"); 11016 NotImplemented("llGetUsedMemory");
@@ -10338,14 +11027,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10338 public void llScriptProfiler( LSL_Integer flags ) 11027 public void llScriptProfiler( LSL_Integer flags )
10339 { 11028 {
10340 m_host.AddScriptLPS(1); 11029 m_host.AddScriptLPS(1);
10341 NotImplemented("llScriptProfiler"); 11030 //NotImplemented("llScriptProfiler");
10342 11031
10343 } 11032 }
10344 11033
10345 public void llSetSoundQueueing(int queue) 11034 public void llSetSoundQueueing(int queue)
10346 { 11035 {
10347 m_host.AddScriptLPS(1); 11036 m_host.AddScriptLPS(1);
10348 NotImplemented("llSetSoundQueueing");
10349 } 11037 }
10350 11038
10351 public void llCollisionSprite(string impact_sprite) 11039 public void llCollisionSprite(string impact_sprite)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 64931d0..39e1a27 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)
@@ -2364,9 +2377,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2364 { 2377 {
2365 if (avatar.IsChildAgent == false) 2378 if (avatar.IsChildAgent == false)
2366 { 2379 {
2367 result.Add(avatar.UUID); 2380 result.Add(new LSL_Key(avatar.UUID.ToString()));
2368 result.Add(avatar.AbsolutePosition); 2381 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2369 result.Add(avatar.Name); 2382 result.Add(new LSL_String(avatar.Name));
2370 } 2383 }
2371 } 2384 }
2372 }); 2385 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 47c7915..3afedc7 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,7 +302,8 @@ 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
@@ -310,6 +311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
310 // in mouselook. 311 // in mouselook.
311 312
312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 313 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
314 fromRegionPos = avatar.AbsolutePosition;
313 q = avatar.Rotation; 315 q = avatar.Rotation;
314 } 316 }
315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 317 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -423,6 +425,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
423 SceneObjectPart SensePoint = ts.host; 425 SceneObjectPart SensePoint = ts.host;
424 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 426 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
425 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment)
429 {
430 // In attachments, the sensor cone always orients with the
431 // avatar rotation. This may include a nonzero elevation if
432 // in mouselook.
433
434 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
435 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation;
437 }
426 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
427 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
428 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
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..0ae2388 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -402,7 +402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
402 LSL_Vector llWind(LSL_Vector offset); 402 LSL_Vector llWind(LSL_Vector offset);
403 LSL_String llXorBase64Strings(string str1, string str2); 403 LSL_String llXorBase64Strings(string str1, string str2);
404 LSL_String llXorBase64StringsCorrect(string str1, string str2); 404 LSL_String llXorBase64StringsCorrect(string str1, string str2);
405 void print(string str); 405 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
406 406
407 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 407 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
408 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 408 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 63007c6..c08ad3b 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..63cac9a 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();
@@ -1868,9 +1870,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1868 return m_LSL_Functions.llClearPrimMedia(face); 1870 return m_LSL_Functions.llClearPrimMedia(face);
1869 } 1871 }
1870 1872
1871 public void print(string str) 1873 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1872 { 1874 {
1873 m_LSL_Functions.print(str); 1875 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1874 } 1876 }
1875 } 1877 }
1876} 1878}
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 97ab411..9a78a42 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 }
@@ -708,92 +776,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
708 } 776 }
709 777
710 ScriptInstance instance = null; 778 ScriptInstance instance = null;
711 lock (m_Scripts) 779 // Create the object record
780 lockScriptsForRead(true);
781 if ((!m_Scripts.ContainsKey(itemID)) ||
782 (m_Scripts[itemID].AssetID != assetID))
712 { 783 {
713 // Create the object record 784 lockScriptsForRead(false);
714 785
715 if ((!m_Scripts.ContainsKey(itemID)) || 786 UUID appDomain = assetID;
716 (m_Scripts[itemID].AssetID != assetID))
717 {
718 UUID appDomain = assetID;
719 787
720 if (part.ParentGroup.IsAttachment) 788 if (part.ParentGroup.IsAttachment)
721 appDomain = part.ParentGroup.RootPart.UUID; 789 appDomain = part.ParentGroup.RootPart.UUID;
722 790
723 if (!m_AppDomains.ContainsKey(appDomain)) 791 if (!m_AppDomains.ContainsKey(appDomain))
792 {
793 try
724 { 794 {
725 try 795 AppDomainSetup appSetup = new AppDomainSetup();
726 { 796 appSetup.PrivateBinPath = Path.Combine(
727 AppDomainSetup appSetup = new AppDomainSetup(); 797 m_ScriptEnginesPath,
728 appSetup.PrivateBinPath = Path.Combine( 798 m_Scene.RegionInfo.RegionID.ToString());
729 m_ScriptEnginesPath, 799
730 m_Scene.RegionInfo.RegionID.ToString()); 800 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
731 801 Evidence evidence = new Evidence(baseEvidence);
732 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 802
733 Evidence evidence = new Evidence(baseEvidence); 803 AppDomain sandbox;
734 804 if (m_AppDomainLoading)
735 AppDomain sandbox; 805 sandbox = AppDomain.CreateDomain(
736 if (m_AppDomainLoading) 806 m_Scene.RegionInfo.RegionID.ToString(),
737 sandbox = AppDomain.CreateDomain( 807 evidence, appSetup);
738 m_Scene.RegionInfo.RegionID.ToString(), 808 else
739 evidence, appSetup); 809 sandbox = AppDomain.CurrentDomain;
740 else 810
741 sandbox = AppDomain.CurrentDomain; 811 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
742 812 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
743 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 813 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
744 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 814 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
745 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 815 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
746 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 816 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
747 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 817 //sandbox.SetAppDomainPolicy(sandboxPolicy);
748 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 818
749 //sandbox.SetAppDomainPolicy(sandboxPolicy); 819 m_AppDomains[appDomain] = sandbox;
750 820
751 m_AppDomains[appDomain] = sandbox; 821 m_AppDomains[appDomain].AssemblyResolve +=
752 822 new ResolveEventHandler(
753 m_AppDomains[appDomain].AssemblyResolve += 823 AssemblyResolver.OnAssemblyResolve);
754 new ResolveEventHandler( 824 m_DomainScripts[appDomain] = new List<UUID>();
755 AssemblyResolver.OnAssemblyResolve); 825 }
756 m_DomainScripts[appDomain] = new List<UUID>(); 826 catch (Exception e)
757 } 827 {
758 catch (Exception e) 828 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
829 m_ScriptErrorMessage += "Exception creating app domain:\n";
830 m_ScriptFailCount++;
831 lock (m_AddingAssemblies)
759 { 832 {
760 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 833 m_AddingAssemblies[assembly]--;
761 m_ScriptErrorMessage += "Exception creating app domain:\n";
762 m_ScriptFailCount++;
763 lock (m_AddingAssemblies)
764 {
765 m_AddingAssemblies[assembly]--;
766 }
767 return false;
768 } 834 }
835 return false;
769 } 836 }
770 m_DomainScripts[appDomain].Add(itemID); 837 }
771 838 m_DomainScripts[appDomain].Add(itemID);
772 instance = new ScriptInstance(this, part, 839
773 itemID, assetID, assembly, 840 instance = new ScriptInstance(this, part,
774 m_AppDomains[appDomain], 841 itemID, assetID, assembly,
775 part.ParentGroup.RootPart.Name, 842 m_AppDomains[appDomain],
776 item.Name, startParam, postOnRez, 843 part.ParentGroup.RootPart.Name,
777 stateSource, m_MaxScriptQueue); 844 item.Name, startParam, postOnRez,
778 845 stateSource, m_MaxScriptQueue);
779 m_log.DebugFormat( 846
847 m_log.DebugFormat(
780 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 848 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
781 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 849 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
782 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 850 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
783 851
784 if (presence != null) 852 if (presence != null)
785 { 853 {
786 ShowScriptSaveResponse(item.OwnerID, 854 ShowScriptSaveResponse(item.OwnerID,
787 assetID, "Compile successful", true); 855 assetID, "Compile successful", true);
788 }
789
790 instance.AppDomain = appDomain;
791 instance.LineMap = linemap;
792
793 m_Scripts[itemID] = instance;
794 } 856 }
795 }
796 857
858 instance.AppDomain = appDomain;
859 instance.LineMap = linemap;
860 lockScriptsForWrite(true);
861 m_Scripts[itemID] = instance;
862 lockScriptsForWrite(false);
863 }
864 else
865 {
866 lockScriptsForRead(false);
867 }
797 lock (m_PrimObjects) 868 lock (m_PrimObjects)
798 { 869 {
799 if (!m_PrimObjects.ContainsKey(localID)) 870 if (!m_PrimObjects.ContainsKey(localID))
@@ -812,9 +883,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
812 m_AddingAssemblies[assembly]--; 883 m_AddingAssemblies[assembly]--;
813 } 884 }
814 885
815 if (instance != null) 886 if (instance!=null)
816 instance.Init(); 887 instance.Init();
817 888
818 return true; 889 return true;
819 } 890 }
820 891
@@ -827,20 +898,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
827 m_CompileDict.Remove(itemID); 898 m_CompileDict.Remove(itemID);
828 } 899 }
829 900
830 IScriptInstance instance = null; 901 lockScriptsForRead(true);
831 902 // Do we even have it?
832 lock (m_Scripts) 903 if (!m_Scripts.ContainsKey(itemID))
833 { 904 {
834 // Do we even have it? 905 lockScriptsForRead(false);
835 if (!m_Scripts.ContainsKey(itemID)) 906 return;
836 return;
837
838 instance=m_Scripts[itemID];
839 m_Scripts.Remove(itemID);
840 } 907 }
908
841 909
910 IScriptInstance instance=m_Scripts[itemID];
911 lockScriptsForRead(false);
912 lockScriptsForWrite(true);
913 m_Scripts.Remove(itemID);
914 lockScriptsForWrite(false);
842 instance.ClearQueue(); 915 instance.ClearQueue();
843 instance.Stop(0); 916 instance.Stop(0);
917
844// bool objectRemoved = false; 918// bool objectRemoved = false;
845 919
846 lock (m_PrimObjects) 920 lock (m_PrimObjects)
@@ -876,11 +950,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
876 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 950 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
877 if (handlerObjectRemoved != null) 951 if (handlerObjectRemoved != null)
878 { 952 {
879 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 953 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
880 handlerObjectRemoved(part.UUID); 954 handlerObjectRemoved(part.UUID);
881 } 955 }
882 956
883 957 CleanAssemblies();
958
884 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 959 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
885 if (handlerScriptRemoved != null) 960 if (handlerScriptRemoved != null)
886 handlerScriptRemoved(itemID); 961 handlerScriptRemoved(itemID);
@@ -1022,7 +1097,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1022 return false; 1097 return false;
1023 1098
1024 uuids = m_PrimObjects[localID]; 1099 uuids = m_PrimObjects[localID];
1025 } 1100
1026 1101
1027 foreach (UUID itemID in uuids) 1102 foreach (UUID itemID in uuids)
1028 { 1103 {
@@ -1040,6 +1115,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1040 result = true; 1115 result = true;
1041 } 1116 }
1042 } 1117 }
1118 }
1043 1119
1044 return result; 1120 return result;
1045 } 1121 }
@@ -1139,12 +1215,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1139 private IScriptInstance GetInstance(UUID itemID) 1215 private IScriptInstance GetInstance(UUID itemID)
1140 { 1216 {
1141 IScriptInstance instance; 1217 IScriptInstance instance;
1142 lock (m_Scripts) 1218 lockScriptsForRead(true);
1219 if (!m_Scripts.ContainsKey(itemID))
1143 { 1220 {
1144 if (!m_Scripts.ContainsKey(itemID)) 1221 lockScriptsForRead(false);
1145 return null; 1222 return null;
1146 instance = m_Scripts[itemID];
1147 } 1223 }
1224 instance = m_Scripts[itemID];
1225 lockScriptsForRead(false);
1148 return instance; 1226 return instance;
1149 } 1227 }
1150 1228
@@ -1168,6 +1246,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1168 return false; 1246 return false;
1169 } 1247 }
1170 1248
1249 [DebuggerNonUserCode]
1171 public void ApiResetScript(UUID itemID) 1250 public void ApiResetScript(UUID itemID)
1172 { 1251 {
1173 IScriptInstance instance = GetInstance(itemID); 1252 IScriptInstance instance = GetInstance(itemID);
@@ -1219,6 +1298,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1219 return UUID.Zero; 1298 return UUID.Zero;
1220 } 1299 }
1221 1300
1301 [DebuggerNonUserCode]
1222 public void SetState(UUID itemID, string newState) 1302 public void SetState(UUID itemID, string newState)
1223 { 1303 {
1224 IScriptInstance instance = GetInstance(itemID); 1304 IScriptInstance instance = GetInstance(itemID);
@@ -1239,11 +1319,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1239 { 1319 {
1240 List<IScriptInstance> instances = new List<IScriptInstance>(); 1320 List<IScriptInstance> instances = new List<IScriptInstance>();
1241 1321
1242 lock (m_Scripts) 1322 lockScriptsForRead(true);
1243 { 1323 foreach (IScriptInstance instance in m_Scripts.Values)
1244 foreach (IScriptInstance instance in m_Scripts.Values)
1245 instances.Add(instance); 1324 instances.Add(instance);
1246 } 1325 lockScriptsForRead(false);
1247 1326
1248 foreach (IScriptInstance i in instances) 1327 foreach (IScriptInstance i in instances)
1249 { 1328 {
@@ -1615,5 +1694,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1615 1694
1616 instance.Resume(); 1695 instance.Resume();
1617 } 1696 }
1697
1698 public bool HasScript(UUID itemID, out bool running)
1699 {
1700 running = true;
1701
1702 IScriptInstance instance = GetInstance(itemID);
1703 if (instance == null)
1704 return false;
1705
1706 running = instance.Running;
1707 return true;
1708 }
1618 } 1709 }
1619} 1710}