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.cs2228
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs90
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs359
19 files changed, 2112 insertions, 989 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 5ed8c47..04f10c6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -275,40 +344,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
275 protected UUID InventorySelf() 344 protected UUID InventorySelf()
276 { 345 {
277 UUID invItemID = new UUID(); 346 UUID invItemID = new UUID();
278 347 bool unlock = false;
279 lock (m_host.TaskInventory) 348 if (!m_host.TaskInventory.IsReadLockedByMe())
349 {
350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
280 { 354 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
282 { 356 {
283 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 357 invItemID = inv.Key;
284 { 358 break;
285 invItemID = inv.Key;
286 break;
287 }
288 } 359 }
289 } 360 }
290 361 if (unlock)
362 {
363 m_host.TaskInventory.LockItemsForRead(false);
364 }
291 return invItemID; 365 return invItemID;
292 } 366 }
293 367
294 protected UUID InventoryKey(string name, int type) 368 protected UUID InventoryKey(string name, int type)
295 { 369 {
296 m_host.AddScriptLPS(1); 370 m_host.AddScriptLPS(1);
297 371 m_host.TaskInventory.LockItemsForRead(true);
298 lock (m_host.TaskInventory) 372
373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
299 { 374 {
300 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 375 if (inv.Value.Name == name)
301 { 376 {
302 if (inv.Value.Name == name) 377 m_host.TaskInventory.LockItemsForRead(false);
378
379 if (inv.Value.Type != type)
303 { 380 {
304 if (inv.Value.Type != type) 381 return UUID.Zero;
305 return UUID.Zero;
306
307 return inv.Value.AssetID;
308 } 382 }
383
384 return inv.Value.AssetID;
309 } 385 }
310 } 386 }
311 387
388 m_host.TaskInventory.LockItemsForRead(false);
312 return UUID.Zero; 389 return UUID.Zero;
313 } 390 }
314 391
@@ -316,17 +393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 { 393 {
317 m_host.AddScriptLPS(1); 394 m_host.AddScriptLPS(1);
318 395
319 lock (m_host.TaskInventory) 396
397 m_host.TaskInventory.LockItemsForRead(true);
398
399 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
320 { 400 {
321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 401 if (inv.Value.Name == name)
322 { 402 {
323 if (inv.Value.Name == name) 403 m_host.TaskInventory.LockItemsForRead(false);
324 { 404 return inv.Value.AssetID;
325 return inv.Value.AssetID;
326 }
327 } 405 }
328 } 406 }
329 407
408 m_host.TaskInventory.LockItemsForRead(false);
409
410
330 return UUID.Zero; 411 return UUID.Zero;
331 } 412 }
332 413
@@ -468,26 +549,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 549
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 550 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 551
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 552 // Utility function for llRot2Euler
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 553
554 // normalize an angle between -PI and PI (-180 to +180 degrees)
555 protected double NormalizeAngle(double angle)
556 {
557 if (angle > -Math.PI && angle < Math.PI)
558 return angle;
559
560 int numPis = (int)(Math.PI / angle);
561 double remainder = angle - Math.PI * numPis;
562 if (numPis % 2 == 1)
563 return Math.PI - angle;
564 return remainder;
565 }
473 566
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
475 { 568 {
476 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
479 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
480 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
481 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
482 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
483 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 577 double test = q1.x*q1.z + q1.y*q1.s;
485 Math.Atan2(n, Math.Sqrt(p)), 578 if (test > 0.4999*unit) { // singularity at north pole
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
487 else if (n > 0) 580 eul.y = Math.PI/2;
488 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)); 581 eul.x = 0;
489 else 582 return eul;
490 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)); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
491 } 594 }
492 595
493 /* From wiki: 596 /* From wiki:
@@ -689,77 +792,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 792 {
690 //A and B should both be normalized 793 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 794 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 795 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 796 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 797
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 798 double dotProduct = LSL_Vector.Dot(a, b);
799 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
800 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
801 double angle = Math.Acos(dotProduct / magProduct);
802 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
803 double s = Math.Sin(angle / 2);
804
805 double x = axis.x * s;
806 double y = axis.y * s;
807 double z = axis.z * s;
808 double w = Math.Cos(angle / 2);
809
810 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812
813 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
814 */
815
816 // This method mimics the 180 errors found in SL
817 // See www.euclideanspace.com... angleBetween
818 LSL_Vector vec_a = a;
819 LSL_Vector vec_b = b;
820
821 // Eliminate zero length
822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
824 if (vec_a_mag < 0.00001 ||
825 vec_b_mag < 0.00001)
696 { 826 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 828 }
699 else 829
830 // Normalize
831 vec_a = llVecNorm(vec_a);
832 vec_b = llVecNorm(vec_b);
833
834 // Calculate axis and rotation angle
835 LSL_Vector axis = vec_a % vec_b;
836 LSL_Float cos_theta = vec_a * vec_b;
837
838 // Check if parallel
839 if (cos_theta > 0.99999)
700 { 840 {
701 a = LSL_Vector.Norm(a); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 842 }
703 double dotProduct = LSL_Vector.Dot(a, b); 843
704 // There are two degenerate cases possible. These are for vectors 180 or 844 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 845 else if (cos_theta < -0.99999)
706 // 846 {
707 // Check for vectors 180 degrees apart. 847 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 850 }
711 // First assume X axis is orthogonal to the vectors. 851 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 852 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 853 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 854 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 855 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 856 s = Math.Cos(theta);
717 { 857 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 858 x = axis.x * t;
719 } 859 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 860 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 861 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 862 }
760 return rotBetween;
761 } 863 }
762 864
763 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
764 { 866 {
765 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -779,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 881 {
780 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
781 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 891 {
784 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -801,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 909 {
802 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
803 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
804 if (text.Length > 1023) 918 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
806 920
@@ -1101,10 +1215,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1215 return detectedParams.TouchUV;
1102 } 1216 }
1103 1217
1218 [DebuggerNonUserCode]
1104 public virtual void llDie() 1219 public virtual void llDie()
1105 { 1220 {
1106 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1223 }
1109 1224
1110 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1292
1178 public void llSetStatus(int status, int value) 1293 public void llSetStatus(int status, int value)
1179 { 1294 {
1295 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1296 return;
1180 m_host.AddScriptLPS(1); 1297 m_host.AddScriptLPS(1);
1181 1298
1182 int statusrotationaxis = 0; 1299 int statusrotationaxis = 0;
@@ -1406,6 +1523,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1523 {
1407 m_host.AddScriptLPS(1); 1524 m_host.AddScriptLPS(1);
1408 1525
1526 SetColor(m_host, color, face);
1527 }
1528
1529 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1530 {
1531 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1532 return;
1533
1534 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part))
1537 {
1538 texcolor = tex.CreateFace((uint)face).RGBA;
1539 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1542 tex.FaceTextures[face].RGBA = texcolor;
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546 else if (face == ScriptBaseClass.ALL_SIDES)
1547 {
1548 for (uint i = 0; i < GetNumberOfSides(part); i++)
1549 {
1550 if (tex.FaceTextures[i] != null)
1551 {
1552 texcolor = tex.FaceTextures[i].RGBA;
1553 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1554 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1555 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1556 tex.FaceTextures[i].RGBA = texcolor;
1557 }
1558 texcolor = tex.DefaultTexture.RGBA;
1559 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1560 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1562 tex.DefaultTexture.RGBA = texcolor;
1563 }
1564 part.UpdateTexture(tex);
1565 return;
1566 }
1567
1409 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1411 1570
@@ -1414,6 +1573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1573
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1574 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1575 {
1576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1577 return;
1578
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1579 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1580 MappingType textype;
1419 textype = MappingType.Default; 1581 textype = MappingType.Default;
@@ -1444,6 +1606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1606
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1607 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1608 {
1609 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1610 return;
1611
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1612 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1613 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1614 {
@@ -1469,6 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1634
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1635 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1636 {
1637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1638 return;
1472 1639
1473 Shininess sval = new Shininess(); 1640 Shininess sval = new Shininess();
1474 1641
@@ -1519,6 +1686,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1686
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1687 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1688 {
1689 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1690 return;
1691
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1692 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1693 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1694 {
@@ -1579,13 +1749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1580 1750
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1752 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1753 {
1584 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1585 } 1765 }
1586 1766
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1773 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1640 { 1823 {
1641 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1825 return;
1643 1826
1644 if (flexi) 1827 if (flexi)
@@ -1672,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1672 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1673 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1674 { 1857 {
1675 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1676 return; 1859 return;
1677 1860
1678 if (light) 1861 if (light)
@@ -1749,15 +1932,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 m_host.AddScriptLPS(1); 1932 m_host.AddScriptLPS(1);
1750 1933
1751 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1934 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1752 1935 if (parts.Count > 0)
1753 foreach (SceneObjectPart part in parts) 1936 {
1754 SetTexture(part, texture, face); 1937 try
1755 1938 {
1939 parts[0].ParentGroup.areUpdatesSuspended = true;
1940 foreach (SceneObjectPart part in parts)
1941 SetTexture(part, texture, face);
1942 }
1943 finally
1944 {
1945 parts[0].ParentGroup.areUpdatesSuspended = false;
1946 }
1947 }
1756 ScriptSleep(200); 1948 ScriptSleep(200);
1757 } 1949 }
1758 1950
1759 protected void SetTexture(SceneObjectPart part, string texture, int face) 1951 protected void SetTexture(SceneObjectPart part, string texture, int face)
1760 { 1952 {
1953 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1954 return;
1955
1761 UUID textureID = new UUID(); 1956 UUID textureID = new UUID();
1762 1957
1763 textureID = InventoryKey(texture, (int)AssetType.Texture); 1958 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1802,6 +1997,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 1997
1803 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1998 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1804 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1805 Primitive.TextureEntry tex = part.Shape.Textures; 2003 Primitive.TextureEntry tex = part.Shape.Textures;
1806 if (face >= 0 && face < GetNumberOfSides(part)) 2004 if (face >= 0 && face < GetNumberOfSides(part))
1807 { 2005 {
@@ -1838,6 +2036,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 2036
1839 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2037 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1840 { 2038 {
2039 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2040 return;
2041
1841 Primitive.TextureEntry tex = part.Shape.Textures; 2042 Primitive.TextureEntry tex = part.Shape.Textures;
1842 if (face >= 0 && face < GetNumberOfSides(part)) 2043 if (face >= 0 && face < GetNumberOfSides(part))
1843 { 2044 {
@@ -1874,6 +2075,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 2075
1875 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2076 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1876 { 2077 {
2078 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2079 return;
2080
1877 Primitive.TextureEntry tex = part.Shape.Textures; 2081 Primitive.TextureEntry tex = part.Shape.Textures;
1878 if (face >= 0 && face < GetNumberOfSides(part)) 2082 if (face >= 0 && face < GetNumberOfSides(part))
1879 { 2083 {
@@ -1980,24 +2184,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 2184
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2185 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2186 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2188 return;
1985 2189
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2190 LSL_Vector currentPos = GetPartLocalPos(part);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2191 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1988 2192
1989 if (part.ParentGroup.RootPart == part) 2193 if (part.ParentGroup.RootPart == part)
1990 { 2194 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2195 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2196 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1996 } 2197 }
1997 else 2198 else
1998 { 2199 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2200 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2001 SceneObjectGroup parent = part.ParentGroup; 2201 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2202 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2203 parent.ScheduleGroupForTerseUpdate();
@@ -2048,9 +2248,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2248 m_host.AddScriptLPS(1);
2049 2249
2050 // try to let this work as in SL... 2250 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2251 if (m_host.LinkNum < 2)
2052 { 2252 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2253 // Special case: If we are root, rotate complete SOG to new
2254 // rotation.
2255 // We are root if the link number is 0 (single prim) or 1
2256 // (root prim). ParentID may be nonzero in attachments and
2257 // using it would cause attachments and HUDs to rotate
2258 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2259 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2260 }
2056 else 2261 else
@@ -2075,6 +2280,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2280
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2281 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2282 {
2283 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2284 return;
2285
2078 part.UpdateRotation(rot); 2286 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2287 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2288
@@ -2698,12 +2906,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2906
2699 m_host.AddScriptLPS(1); 2907 m_host.AddScriptLPS(1);
2700 2908
2909 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2910 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2911 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2912
2708 if (item.PermsGranter == UUID.Zero) 2913 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2914 return 0;
@@ -2778,6 +2983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2983 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2984 return;
2780 2985
2986 //Clone is thread-safe
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2987 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2988
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2989 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2838,6 +3044,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2838 3044
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3045 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3046 {
3047 /*
2841 m_host.AddScriptLPS(1); 3048 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from 3049 // Determine where we are looking from
2843 LSL_Vector from = llGetPos(); 3050 LSL_Vector from = llGetPos();
@@ -2857,10 +3064,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2857 // the angles of rotation in radians into rotation value 3064 // the angles of rotation in radians into rotation value
2858 3065
2859 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3066 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2860 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3067
2861 m_host.startLookAt(rotation, (float)damping, (float)strength); 3068 // This would only work if your physics system contains an APID controller:
3069 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3070 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3071
2862 // Orient the object to the angle calculated 3072 // Orient the object to the angle calculated
2863 //llSetRot(rot); 3073 llSetRot(rot);
3074 */
3075
3076 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3077 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3078 // http://bugs.meta7.com/view.php?id=28
3079 // - Tom
3080
3081 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3082 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3083 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3084 */
3085 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3086 {
3087 // Part is non-phys, convert this to a llSetRot()
3088 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3089 Vector3 dir = tgt - m_host.GroupPosition;
3090 dir.Normalize();
3091 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3092 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3093 float terot = (float)Math.Atan2(-dir.Z, txy);
3094 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3095 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3096 LSL_Types.Quaternion spin = llEuler2Rot(az);
3097 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3098 llSetRot(rot);
3099 }
3100 else
3101 {
3102 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3103 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3104 m_host.RotLookAt(q, (float)strength, (float)damping);
3105 }
3106
3107 }
3108
3109 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3110 {
3111 m_host.AddScriptLPS(1);
3112// NotImplemented("llRotLookAt");
3113 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3114
2864 } 3115 }
2865 3116
2866 public void llStopLookAt() 3117 public void llStopLookAt()
@@ -2909,13 +3160,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2909 { 3160 {
2910 TaskInventoryItem item; 3161 TaskInventoryItem item;
2911 3162
2912 lock (m_host.TaskInventory) 3163 m_host.TaskInventory.LockItemsForRead(true);
3164 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2913 { 3165 {
2914 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3166 m_host.TaskInventory.LockItemsForRead(false);
2915 return; 3167 return;
2916 else
2917 item = m_host.TaskInventory[InventorySelf()];
2918 } 3168 }
3169 else
3170 {
3171 item = m_host.TaskInventory[InventorySelf()];
3172 }
3173 m_host.TaskInventory.LockItemsForRead(false);
2919 3174
2920 if (item.PermsGranter != UUID.Zero) 3175 if (item.PermsGranter != UUID.Zero)
2921 { 3176 {
@@ -2937,13 +3192,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 { 3192 {
2938 TaskInventoryItem item; 3193 TaskInventoryItem item;
2939 3194
3195 m_host.TaskInventory.LockItemsForRead(true);
2940 lock (m_host.TaskInventory) 3196 lock (m_host.TaskInventory)
2941 { 3197 {
3198
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3199 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3200 {
3201 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3202 return;
3203 }
2944 else 3204 else
3205 {
2945 item = m_host.TaskInventory[InventorySelf()]; 3206 item = m_host.TaskInventory[InventorySelf()];
3207 }
2946 } 3208 }
3209 m_host.TaskInventory.LockItemsForRead(false);
2947 3210
2948 m_host.AddScriptLPS(1); 3211 m_host.AddScriptLPS(1);
2949 3212
@@ -2975,18 +3238,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2975 { 3238 {
2976 m_host.AddScriptLPS(1); 3239 m_host.AddScriptLPS(1);
2977 3240
2978// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2979// return;
2980
2981 TaskInventoryItem item; 3241 TaskInventoryItem item;
2982 3242
2983 lock (m_host.TaskInventory) 3243 m_host.TaskInventory.LockItemsForRead(true);
3244
3245 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2984 { 3246 {
2985 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3247 m_host.TaskInventory.LockItemsForRead(false);
2986 return; 3248 return;
2987 else
2988 item = m_host.TaskInventory[InventorySelf()];
2989 } 3249 }
3250 else
3251 {
3252 item = m_host.TaskInventory[InventorySelf()];
3253 }
3254
3255 m_host.TaskInventory.LockItemsForRead(false);
2990 3256
2991 if (item.PermsGranter != m_host.OwnerID) 3257 if (item.PermsGranter != m_host.OwnerID)
2992 return; 3258 return;
@@ -3012,13 +3278,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3012 3278
3013 TaskInventoryItem item; 3279 TaskInventoryItem item;
3014 3280
3015 lock (m_host.TaskInventory) 3281 m_host.TaskInventory.LockItemsForRead(true);
3282
3283 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3016 { 3284 {
3017 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3285 m_host.TaskInventory.LockItemsForRead(false);
3018 return; 3286 return;
3019 else
3020 item = m_host.TaskInventory[InventorySelf()];
3021 } 3287 }
3288 else
3289 {
3290 item = m_host.TaskInventory[InventorySelf()];
3291 }
3292 m_host.TaskInventory.LockItemsForRead(false);
3293
3022 3294
3023 if (item.PermsGranter != m_host.OwnerID) 3295 if (item.PermsGranter != m_host.OwnerID)
3024 return; 3296 return;
@@ -3065,6 +3337,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3065 3337
3066 public void llInstantMessage(string user, string message) 3338 public void llInstantMessage(string user, string message)
3067 { 3339 {
3340 UUID result;
3341 if (!UUID.TryParse(user, out result))
3342 {
3343 ShoutError("An invalid key was passed to llInstantMessage");
3344 ScriptSleep(2000);
3345 return;
3346 }
3347
3348
3068 m_host.AddScriptLPS(1); 3349 m_host.AddScriptLPS(1);
3069 3350
3070 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3351 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3079,14 +3360,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3079 UUID friendTransactionID = UUID.Random(); 3360 UUID friendTransactionID = UUID.Random();
3080 3361
3081 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3362 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3082 3363
3083 GridInstantMessage msg = new GridInstantMessage(); 3364 GridInstantMessage msg = new GridInstantMessage();
3084 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3365 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3085 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3366 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3086 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3367 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3087// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3368// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3088// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3369// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3089 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3370// DateTime dt = DateTime.UtcNow;
3371//
3372// // Ticks from UtcNow, but make it look like local. Evil, huh?
3373// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3374//
3375// try
3376// {
3377// // Convert that to the PST timezone
3378// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3379// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3380// }
3381// catch
3382// {
3383// // No logging here, as it could be VERY spammy
3384// }
3385//
3386// // And make it look local again to fool the unix time util
3387// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3388
3389 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3390
3090 //if (client != null) 3391 //if (client != null)
3091 //{ 3392 //{
3092 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3393 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3100,12 +3401,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3100 msg.message = message.Substring(0, 1024); 3401 msg.message = message.Substring(0, 1024);
3101 else 3402 else
3102 msg.message = message; 3403 msg.message = message;
3103 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3404 msg.dialog = (byte)19; // MessageFromObject
3104 msg.fromGroup = false;// fromGroup; 3405 msg.fromGroup = false;// fromGroup;
3105 msg.offline = (byte)0; //offline; 3406 msg.offline = (byte)0; //offline;
3106 msg.ParentEstateID = 0; //ParentEstateID; 3407 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3107 msg.Position = new Vector3(m_host.AbsolutePosition); 3408 msg.Position = new Vector3(m_host.AbsolutePosition);
3108 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3409 msg.RegionID = World.RegionInfo.RegionID.Guid;
3109 msg.binaryBucket 3410 msg.binaryBucket
3110 = Util.StringToBytes256( 3411 = Util.StringToBytes256(
3111 "{0}/{1}/{2}/{3}", 3412 "{0}/{1}/{2}/{3}",
@@ -3133,7 +3434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3133 } 3434 }
3134 3435
3135 emailModule.SendEmail(m_host.UUID, address, subject, message); 3436 emailModule.SendEmail(m_host.UUID, address, subject, message);
3136 ScriptSleep(20000); 3437 ScriptSleep(15000);
3137 } 3438 }
3138 3439
3139 public void llGetNextEmail(string address, string subject) 3440 public void llGetNextEmail(string address, string subject)
@@ -3233,13 +3534,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3233 m_host.AddScriptLPS(1); 3534 m_host.AddScriptLPS(1);
3234 } 3535 }
3235 3536
3236 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3237 {
3238 m_host.AddScriptLPS(1);
3239 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3240 m_host.RotLookAt(rot, (float)strength, (float)damping);
3241 }
3242
3243 public LSL_Integer llStringLength(string str) 3537 public LSL_Integer llStringLength(string str)
3244 { 3538 {
3245 m_host.AddScriptLPS(1); 3539 m_host.AddScriptLPS(1);
@@ -3263,14 +3557,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3263 3557
3264 TaskInventoryItem item; 3558 TaskInventoryItem item;
3265 3559
3266 lock (m_host.TaskInventory) 3560 m_host.TaskInventory.LockItemsForRead(true);
3561 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3267 { 3562 {
3268 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3563 m_host.TaskInventory.LockItemsForRead(false);
3269 return; 3564 return;
3270 else
3271 item = m_host.TaskInventory[InventorySelf()];
3272 } 3565 }
3273 3566 else
3567 {
3568 item = m_host.TaskInventory[InventorySelf()];
3569 }
3570 m_host.TaskInventory.LockItemsForRead(false);
3274 if (item.PermsGranter == UUID.Zero) 3571 if (item.PermsGranter == UUID.Zero)
3275 return; 3572 return;
3276 3573
@@ -3300,13 +3597,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3300 3597
3301 TaskInventoryItem item; 3598 TaskInventoryItem item;
3302 3599
3303 lock (m_host.TaskInventory) 3600 m_host.TaskInventory.LockItemsForRead(true);
3601 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3304 { 3602 {
3305 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3603 m_host.TaskInventory.LockItemsForRead(false);
3306 return; 3604 return;
3307 else
3308 item = m_host.TaskInventory[InventorySelf()];
3309 } 3605 }
3606 else
3607 {
3608 item = m_host.TaskInventory[InventorySelf()];
3609 }
3610 m_host.TaskInventory.LockItemsForRead(false);
3611
3310 3612
3311 if (item.PermsGranter == UUID.Zero) 3613 if (item.PermsGranter == UUID.Zero)
3312 return; 3614 return;
@@ -3373,10 +3675,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 3675
3374 TaskInventoryItem item; 3676 TaskInventoryItem item;
3375 3677
3376 lock (m_host.TaskInventory) 3678
3679 m_host.TaskInventory.LockItemsForRead(true);
3680 if (!m_host.TaskInventory.ContainsKey(invItemID))
3681 {
3682 m_host.TaskInventory.LockItemsForRead(false);
3683 return;
3684 }
3685 else
3377 { 3686 {
3378 item = m_host.TaskInventory[invItemID]; 3687 item = m_host.TaskInventory[invItemID];
3379 } 3688 }
3689 m_host.TaskInventory.LockItemsForRead(false);
3380 3690
3381 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3691 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3382 { 3692 {
@@ -3404,15 +3714,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3404 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3714 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3405 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3715 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3406 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3716 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3717 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3407 ScriptBaseClass.PERMISSION_ATTACH; 3718 ScriptBaseClass.PERMISSION_ATTACH;
3408 3719
3409 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3720 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3410 { 3721 {
3411 lock (m_host.TaskInventory) 3722 m_host.TaskInventory.LockItemsForWrite(true);
3412 { 3723 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3413 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3724 m_host.TaskInventory[invItemID].PermsMask = perm;
3414 m_host.TaskInventory[invItemID].PermsMask = perm; 3725 m_host.TaskInventory.LockItemsForWrite(false);
3415 }
3416 3726
3417 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3727 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3418 "run_time_permissions", new Object[] { 3728 "run_time_permissions", new Object[] {
@@ -3422,28 +3732,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3422 return; 3732 return;
3423 } 3733 }
3424 } 3734 }
3425 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3735 else
3426 { 3736 {
3427 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3737 bool sitting = false;
3428 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3738 if (m_host.SitTargetAvatar == agentID)
3429 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3739 {
3430 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3740 sitting = true;
3431 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3741 }
3742 else
3743 {
3744 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3745 {
3746 if (p.SitTargetAvatar == agentID)
3747 sitting = true;
3748 }
3749 }
3432 3750
3433 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3751 if (sitting)
3434 { 3752 {
3435 lock (m_host.TaskInventory) 3753 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3754 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3755 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3756 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3757 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3758
3759 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3436 { 3760 {
3761 m_host.TaskInventory.LockItemsForWrite(true);
3437 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3762 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3438 m_host.TaskInventory[invItemID].PermsMask = perm; 3763 m_host.TaskInventory[invItemID].PermsMask = perm;
3439 } 3764 m_host.TaskInventory.LockItemsForWrite(false);
3440 3765
3441 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3766 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3442 "run_time_permissions", new Object[] { 3767 "run_time_permissions", new Object[] {
3443 new LSL_Integer(perm) }, 3768 new LSL_Integer(perm) },
3444 new DetectParams[0])); 3769 new DetectParams[0]));
3445 3770
3446 return; 3771 return;
3772 }
3447 } 3773 }
3448 } 3774 }
3449 3775
@@ -3457,11 +3783,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3457 3783
3458 if (!m_waitingForScriptAnswer) 3784 if (!m_waitingForScriptAnswer)
3459 { 3785 {
3460 lock (m_host.TaskInventory) 3786 m_host.TaskInventory.LockItemsForWrite(true);
3461 { 3787 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3462 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3788 m_host.TaskInventory[invItemID].PermsMask = 0;
3463 m_host.TaskInventory[invItemID].PermsMask = 0; 3789 m_host.TaskInventory.LockItemsForWrite(false);
3464 }
3465 3790
3466 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3791 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3467 m_waitingForScriptAnswer=true; 3792 m_waitingForScriptAnswer=true;
@@ -3496,10 +3821,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3496 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3821 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3497 llReleaseControls(); 3822 llReleaseControls();
3498 3823
3499 lock (m_host.TaskInventory) 3824
3500 { 3825 m_host.TaskInventory.LockItemsForWrite(true);
3501 m_host.TaskInventory[invItemID].PermsMask = answer; 3826 m_host.TaskInventory[invItemID].PermsMask = answer;
3502 } 3827 m_host.TaskInventory.LockItemsForWrite(false);
3828
3503 3829
3504 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3830 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3505 "run_time_permissions", new Object[] { 3831 "run_time_permissions", new Object[] {
@@ -3511,16 +3837,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 { 3837 {
3512 m_host.AddScriptLPS(1); 3838 m_host.AddScriptLPS(1);
3513 3839
3514 lock (m_host.TaskInventory) 3840 m_host.TaskInventory.LockItemsForRead(true);
3841
3842 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3515 { 3843 {
3516 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3844 if (item.Type == 10 && item.ItemID == m_itemID)
3517 { 3845 {
3518 if (item.Type == 10 && item.ItemID == m_itemID) 3846 m_host.TaskInventory.LockItemsForRead(false);
3519 { 3847 return item.PermsGranter.ToString();
3520 return item.PermsGranter.ToString();
3521 }
3522 } 3848 }
3523 } 3849 }
3850 m_host.TaskInventory.LockItemsForRead(false);
3524 3851
3525 return UUID.Zero.ToString(); 3852 return UUID.Zero.ToString();
3526 } 3853 }
@@ -3529,19 +3856,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3529 { 3856 {
3530 m_host.AddScriptLPS(1); 3857 m_host.AddScriptLPS(1);
3531 3858
3532 lock (m_host.TaskInventory) 3859 m_host.TaskInventory.LockItemsForRead(true);
3860
3861 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3533 { 3862 {
3534 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3863 if (item.Type == 10 && item.ItemID == m_itemID)
3535 { 3864 {
3536 if (item.Type == 10 && item.ItemID == m_itemID) 3865 int perms = item.PermsMask;
3537 { 3866 if (m_automaticLinkPermission)
3538 int perms = item.PermsMask; 3867 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3539 if (m_automaticLinkPermission) 3868 m_host.TaskInventory.LockItemsForRead(false);
3540 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3869 return perms;
3541 return perms;
3542 }
3543 } 3870 }
3544 } 3871 }
3872 m_host.TaskInventory.LockItemsForRead(false);
3545 3873
3546 return 0; 3874 return 0;
3547 } 3875 }
@@ -3563,9 +3891,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3563 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3891 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3564 { 3892 {
3565 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3893 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3566 3894 if (parts.Count > 0)
3567 foreach (SceneObjectPart part in parts) 3895 {
3568 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3896 try
3897 {
3898 parts[0].ParentGroup.areUpdatesSuspended = true;
3899 foreach (SceneObjectPart part in parts)
3900 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3901 }
3902 finally
3903 {
3904 parts[0].ParentGroup.areUpdatesSuspended = false;
3905 }
3906 }
3569 } 3907 }
3570 3908
3571 public void llCreateLink(string target, int parent) 3909 public void llCreateLink(string target, int parent)
@@ -3578,11 +3916,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3578 return; 3916 return;
3579 3917
3580 TaskInventoryItem item; 3918 TaskInventoryItem item;
3581 lock (m_host.TaskInventory) 3919 m_host.TaskInventory.LockItemsForRead(true);
3582 { 3920 item = m_host.TaskInventory[invItemID];
3583 item = m_host.TaskInventory[invItemID]; 3921 m_host.TaskInventory.LockItemsForRead(false);
3584 } 3922
3585
3586 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3923 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3587 && !m_automaticLinkPermission) 3924 && !m_automaticLinkPermission)
3588 { 3925 {
@@ -3599,11 +3936,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3599 3936
3600 if (targetPart.ParentGroup.AttachmentPoint != 0) 3937 if (targetPart.ParentGroup.AttachmentPoint != 0)
3601 return; // Fail silently if attached 3938 return; // Fail silently if attached
3939
3940 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3941 return;
3942
3602 SceneObjectGroup parentPrim = null, childPrim = null; 3943 SceneObjectGroup parentPrim = null, childPrim = null;
3603 3944
3604 if (targetPart != null) 3945 if (targetPart != null)
3605 { 3946 {
3606 if (parent != 0) { 3947 if (parent != 0)
3948 {
3607 parentPrim = m_host.ParentGroup; 3949 parentPrim = m_host.ParentGroup;
3608 childPrim = targetPart.ParentGroup; 3950 childPrim = targetPart.ParentGroup;
3609 } 3951 }
@@ -3634,16 +3976,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 m_host.AddScriptLPS(1); 3976 m_host.AddScriptLPS(1);
3635 UUID invItemID = InventorySelf(); 3977 UUID invItemID = InventorySelf();
3636 3978
3637 lock (m_host.TaskInventory) 3979 m_host.TaskInventory.LockItemsForRead(true);
3638 {
3639 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3640 && !m_automaticLinkPermission) 3981 && !m_automaticLinkPermission)
3641 { 3982 {
3642 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3983 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3984 m_host.TaskInventory.LockItemsForRead(false);
3643 return; 3985 return;
3644 } 3986 }
3645 } 3987 m_host.TaskInventory.LockItemsForRead(false);
3646 3988
3647 if (linknum < ScriptBaseClass.LINK_THIS) 3989 if (linknum < ScriptBaseClass.LINK_THIS)
3648 return; 3990 return;
3649 3991
@@ -3682,10 +4024,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 // Restructuring Multiple Prims. 4024 // Restructuring Multiple Prims.
3683 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4025 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3684 parts.Remove(parentPrim.RootPart); 4026 parts.Remove(parentPrim.RootPart);
3685 foreach (SceneObjectPart part in parts) 4027 if (parts.Count > 0)
3686 { 4028 {
3687 parentPrim.DelinkFromGroup(part.LocalId, true); 4029 try
4030 {
4031 parts[0].ParentGroup.areUpdatesSuspended = true;
4032 foreach (SceneObjectPart part in parts)
4033 {
4034 parentPrim.DelinkFromGroup(part.LocalId, true);
4035 }
4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
3688 } 4041 }
4042
3689 parentPrim.HasGroupChanged = true; 4043 parentPrim.HasGroupChanged = true;
3690 parentPrim.ScheduleGroupForFullUpdate(); 4044 parentPrim.ScheduleGroupForFullUpdate();
3691 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4045 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3694,12 +4048,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 { 4048 {
3695 SceneObjectPart newRoot = parts[0]; 4049 SceneObjectPart newRoot = parts[0];
3696 parts.Remove(newRoot); 4050 parts.Remove(newRoot);
3697 foreach (SceneObjectPart part in parts) 4051
4052 try
3698 { 4053 {
3699 // Required for linking 4054 parts[0].ParentGroup.areUpdatesSuspended = true;
3700 part.ClearUpdateSchedule(); 4055 foreach (SceneObjectPart part in parts)
3701 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4056 {
4057 part.ClearUpdateSchedule();
4058 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4059 }
3702 } 4060 }
4061 finally
4062 {
4063 parts[0].ParentGroup.areUpdatesSuspended = false;
4064 }
4065
4066
3703 newRoot.ParentGroup.HasGroupChanged = true; 4067 newRoot.ParentGroup.HasGroupChanged = true;
3704 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4068 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3705 } 4069 }
@@ -3719,6 +4083,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3719 public void llBreakAllLinks() 4083 public void llBreakAllLinks()
3720 { 4084 {
3721 m_host.AddScriptLPS(1); 4085 m_host.AddScriptLPS(1);
4086
4087 UUID invItemID = InventorySelf();
4088
4089 TaskInventoryItem item;
4090 m_host.TaskInventory.LockItemsForRead(true);
4091 item = m_host.TaskInventory[invItemID];
4092 m_host.TaskInventory.LockItemsForRead(false);
4093
4094 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4095 && !m_automaticLinkPermission)
4096 {
4097 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4098 return;
4099 }
4100
3722 SceneObjectGroup parentPrim = m_host.ParentGroup; 4101 SceneObjectGroup parentPrim = m_host.ParentGroup;
3723 if (parentPrim.AttachmentPoint != 0) 4102 if (parentPrim.AttachmentPoint != 0)
3724 return; // Fail silently if attached 4103 return; // Fail silently if attached
@@ -3764,6 +4143,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3764 } 4143 }
3765 else 4144 else
3766 { 4145 {
4146 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4147 {
4148 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4149
4150 if (linknum < 0)
4151 return UUID.Zero.ToString();
4152
4153 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4154 if (avatars.Count > linknum)
4155 {
4156 return avatars[linknum].UUID.ToString();
4157 }
4158 }
3767 return UUID.Zero.ToString(); 4159 return UUID.Zero.ToString();
3768 } 4160 }
3769 } 4161 }
@@ -3862,17 +4254,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3862 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3863 int count = 0; 4255 int count = 0;
3864 4256
3865 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3866 { 4259 {
3867 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3868 { 4261 {
3869 if (inv.Value.Type == type || type == -1) 4262 count = count + 1;
3870 {
3871 count = count + 1;
3872 }
3873 } 4263 }
3874 } 4264 }
3875 4265
4266 m_host.TaskInventory.LockItemsForRead(false);
3876 return count; 4267 return count;
3877 } 4268 }
3878 4269
@@ -3881,16 +4272,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3881 m_host.AddScriptLPS(1); 4272 m_host.AddScriptLPS(1);
3882 ArrayList keys = new ArrayList(); 4273 ArrayList keys = new ArrayList();
3883 4274
3884 lock (m_host.TaskInventory) 4275 m_host.TaskInventory.LockItemsForRead(true);
4276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3885 { 4277 {
3886 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4278 if (inv.Value.Type == type || type == -1)
3887 { 4279 {
3888 if (inv.Value.Type == type || type == -1) 4280 keys.Add(inv.Value.Name);
3889 {
3890 keys.Add(inv.Value.Name);
3891 }
3892 } 4281 }
3893 } 4282 }
4283 m_host.TaskInventory.LockItemsForRead(false);
3894 4284
3895 if (keys.Count == 0) 4285 if (keys.Count == 0)
3896 { 4286 {
@@ -3927,25 +4317,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 } 4317 }
3928 4318
3929 // move the first object found with this inventory name 4319 // move the first object found with this inventory name
3930 lock (m_host.TaskInventory) 4320 m_host.TaskInventory.LockItemsForRead(true);
4321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3931 { 4322 {
3932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4323 if (inv.Value.Name == inventory)
3933 { 4324 {
3934 if (inv.Value.Name == inventory) 4325 found = true;
3935 { 4326 objId = inv.Key;
3936 found = true; 4327 assetType = inv.Value.Type;
3937 objId = inv.Key; 4328 objName = inv.Value.Name;
3938 assetType = inv.Value.Type; 4329 break;
3939 objName = inv.Value.Name;
3940 break;
3941 }
3942 } 4330 }
3943 } 4331 }
4332 m_host.TaskInventory.LockItemsForRead(false);
3944 4333
3945 if (!found) 4334 if (!found)
3946 { 4335 {
3947 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4336 llSay(0, String.Format("Could not find object '{0}'", inventory));
3948 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4337 return;
4338// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3949 } 4339 }
3950 4340
3951 // check if destination is an object 4341 // check if destination is an object
@@ -3971,6 +4361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 return; 4361 return;
3972 } 4362 }
3973 } 4363 }
4364
3974 // destination is an avatar 4365 // destination is an avatar
3975 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4366 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3976 4367
@@ -3993,26 +4384,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3993 bucket); 4384 bucket);
3994 if (m_TransferModule != null) 4385 if (m_TransferModule != null)
3995 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4386 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4387
4388 //This delay should only occur when giving inventory to avatars.
3996 ScriptSleep(3000); 4389 ScriptSleep(3000);
3997 } 4390 }
3998 } 4391 }
3999 4392
4393 [DebuggerNonUserCode]
4000 public void llRemoveInventory(string name) 4394 public void llRemoveInventory(string name)
4001 { 4395 {
4002 m_host.AddScriptLPS(1); 4396 m_host.AddScriptLPS(1);
4003 4397
4004 lock (m_host.TaskInventory) 4398 List<TaskInventoryItem> inv;
4399 try
4005 { 4400 {
4006 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4401 m_host.TaskInventory.LockItemsForRead(true);
4402 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4403 }
4404 finally
4405 {
4406 m_host.TaskInventory.LockItemsForRead(false);
4407 }
4408 foreach (TaskInventoryItem item in inv)
4409 {
4410 if (item.Name == name)
4007 { 4411 {
4008 if (item.Name == name) 4412 if (item.ItemID == m_itemID)
4009 { 4413 throw new ScriptDeleteException();
4010 if (item.ItemID == m_itemID) 4414 else
4011 throw new ScriptDeleteException(); 4415 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4012 else 4416 return;
4013 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4014 return;
4015 }
4016 } 4417 }
4017 } 4418 }
4018 } 4419 }
@@ -4047,112 +4448,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4047 { 4448 {
4048 m_host.AddScriptLPS(1); 4449 m_host.AddScriptLPS(1);
4049 4450
4050 UUID uuid = (UUID)id; 4451 UUID uuid;
4051 PresenceInfo pinfo = null; 4452 if (UUID.TryParse(id, out uuid))
4052 UserAccount account;
4053
4054 UserInfoCacheEntry ce;
4055 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4056 { 4453 {
4057 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4454 PresenceInfo pinfo = null;
4058 if (account == null) 4455 UserAccount account;
4456
4457 UserInfoCacheEntry ce;
4458 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4059 { 4459 {
4060 m_userInfoCache[uuid] = null; // Cache negative 4460 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4061 return UUID.Zero.ToString(); 4461 if (account == null)
4062 } 4462 {
4463 m_userInfoCache[uuid] = null; // Cache negative
4464 return UUID.Zero.ToString();
4465 }
4063 4466
4064 4467
4065 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4468 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4066 if (pinfos != null && pinfos.Length > 0) 4469 if (pinfos != null && pinfos.Length > 0)
4067 {
4068 foreach (PresenceInfo p in pinfos)
4069 { 4470 {
4070 if (p.RegionID != UUID.Zero) 4471 foreach (PresenceInfo p in pinfos)
4071 { 4472 {
4072 pinfo = p; 4473 if (p.RegionID != UUID.Zero)
4474 {
4475 pinfo = p;
4476 }
4073 } 4477 }
4074 } 4478 }
4075 }
4076 4479
4077 ce = new UserInfoCacheEntry(); 4480 ce = new UserInfoCacheEntry();
4078 ce.time = Util.EnvironmentTickCount(); 4481 ce.time = Util.EnvironmentTickCount();
4079 ce.account = account; 4482 ce.account = account;
4080 ce.pinfo = pinfo; 4483 ce.pinfo = pinfo;
4081 } 4484 m_userInfoCache[uuid] = ce;
4082 else 4485 }
4083 { 4486 else
4084 if (ce == null) 4487 {
4085 return UUID.Zero.ToString(); 4488 if (ce == null)
4489 return UUID.Zero.ToString();
4086 4490
4087 account = ce.account; 4491 account = ce.account;
4088 pinfo = ce.pinfo; 4492 pinfo = ce.pinfo;
4089 } 4493 }
4090 4494
4091 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4495 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4092 {
4093 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4094 if (pinfos != null && pinfos.Length > 0)
4095 { 4496 {
4096 foreach (PresenceInfo p in pinfos) 4497 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4498 if (pinfos != null && pinfos.Length > 0)
4097 { 4499 {
4098 if (p.RegionID != UUID.Zero) 4500 foreach (PresenceInfo p in pinfos)
4099 { 4501 {
4100 pinfo = p; 4502 if (p.RegionID != UUID.Zero)
4503 {
4504 pinfo = p;
4505 }
4101 } 4506 }
4102 } 4507 }
4103 } 4508 else
4104 else 4509 pinfo = null;
4105 pinfo = null;
4106 4510
4107 ce.time = Util.EnvironmentTickCount(); 4511 ce.time = Util.EnvironmentTickCount();
4108 ce.pinfo = pinfo; 4512 ce.pinfo = pinfo;
4109 } 4513 }
4110 4514
4111 string reply = String.Empty; 4515 string reply = String.Empty;
4112 4516
4113 switch (data) 4517 switch (data)
4114 { 4518 {
4115 case 1: // DATA_ONLINE (0|1) 4519 case 1: // DATA_ONLINE (0|1)
4116 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4520 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4117 reply = "1"; 4521 reply = "1";
4118 else 4522 else
4119 reply = "0"; 4523 reply = "0";
4120 break; 4524 break;
4121 case 2: // DATA_NAME (First Last) 4525 case 2: // DATA_NAME (First Last)
4122 reply = account.FirstName + " " + account.LastName; 4526 reply = account.FirstName + " " + account.LastName;
4123 break; 4527 break;
4124 case 3: // DATA_BORN (YYYY-MM-DD) 4528 case 3: // DATA_BORN (YYYY-MM-DD)
4125 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4529 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4126 born = born.AddSeconds(account.Created); 4530 born = born.AddSeconds(account.Created);
4127 reply = born.ToString("yyyy-MM-dd"); 4531 reply = born.ToString("yyyy-MM-dd");
4128 break; 4532 break;
4129 case 4: // DATA_RATING (0,0,0,0,0,0) 4533 case 4: // DATA_RATING (0,0,0,0,0,0)
4130 reply = "0,0,0,0,0,0"; 4534 reply = "0,0,0,0,0,0";
4131 break; 4535 break;
4132 case 8: // DATA_PAYINFO (0|1|2|3) 4536 case 8: // DATA_PAYINFO (0|1|2|3)
4133 reply = "0"; 4537 reply = "0";
4134 break; 4538 break;
4135 default: 4539 default:
4136 return UUID.Zero.ToString(); // Raise no event 4540 return UUID.Zero.ToString(); // Raise no event
4137 } 4541 }
4138 4542
4139 UUID rq = UUID.Random(); 4543 UUID rq = UUID.Random();
4140 4544
4141 UUID tid = AsyncCommands. 4545 UUID tid = AsyncCommands.
4142 DataserverPlugin.RegisterRequest(m_localID, 4546 DataserverPlugin.RegisterRequest(m_localID,
4143 m_itemID, rq.ToString()); 4547 m_itemID, rq.ToString());
4144 4548
4145 AsyncCommands. 4549 AsyncCommands.
4146 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4550 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4147 4551
4148 ScriptSleep(100); 4552 ScriptSleep(100);
4149 return tid.ToString(); 4553 return tid.ToString();
4554 }
4555 else
4556 {
4557 ShoutError("Invalid UUID passed to llRequestAgentData.");
4558 }
4559 return "";
4150 } 4560 }
4151 4561
4152 public LSL_String llRequestInventoryData(string name) 4562 public LSL_String llRequestInventoryData(string name)
4153 { 4563 {
4154 m_host.AddScriptLPS(1); 4564 m_host.AddScriptLPS(1);
4155 4565
4566 //Clone is thread safe
4156 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4567 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4157 4568
4158 foreach (TaskInventoryItem item in itemDictionary.Values) 4569 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4206,6 +4617,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4206 ScenePresence presence = World.GetScenePresence(agentId); 4617 ScenePresence presence = World.GetScenePresence(agentId);
4207 if (presence != null) 4618 if (presence != null)
4208 { 4619 {
4620 // agent must not be a god
4621 if (presence.UserLevel >= 200) return;
4622
4209 // agent must be over the owners land 4623 // agent must be over the owners land
4210 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4624 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4211 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4625 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4228,7 +4642,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4228 UUID av = new UUID(); 4642 UUID av = new UUID();
4229 if (!UUID.TryParse(agent,out av)) 4643 if (!UUID.TryParse(agent,out av))
4230 { 4644 {
4231 LSLError("First parameter to llDialog needs to be a key"); 4645 //LSLError("First parameter to llDialog needs to be a key");
4232 return; 4646 return;
4233 } 4647 }
4234 4648
@@ -4265,17 +4679,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4265 UUID soundId = UUID.Zero; 4679 UUID soundId = UUID.Zero;
4266 if (!UUID.TryParse(impact_sound, out soundId)) 4680 if (!UUID.TryParse(impact_sound, out soundId))
4267 { 4681 {
4268 lock (m_host.TaskInventory) 4682 m_host.TaskInventory.LockItemsForRead(true);
4683 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4269 { 4684 {
4270 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4685 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4271 { 4686 {
4272 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4687 soundId = item.AssetID;
4273 { 4688 break;
4274 soundId = item.AssetID;
4275 break;
4276 }
4277 } 4689 }
4278 } 4690 }
4691 m_host.TaskInventory.LockItemsForRead(false);
4279 } 4692 }
4280 m_host.CollisionSound = soundId; 4693 m_host.CollisionSound = soundId;
4281 m_host.CollisionSoundVolume = (float)impact_volume; 4694 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4315,6 +4728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4315 UUID partItemID; 4728 UUID partItemID;
4316 foreach (SceneObjectPart part in parts) 4729 foreach (SceneObjectPart part in parts)
4317 { 4730 {
4731 //Clone is thread safe
4318 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4732 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4319 4733
4320 foreach (TaskInventoryItem item in itemsDictionary.Values) 4734 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4529,17 +4943,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4529 4943
4530 m_host.AddScriptLPS(1); 4944 m_host.AddScriptLPS(1);
4531 4945
4532 lock (m_host.TaskInventory) 4946 m_host.TaskInventory.LockItemsForRead(true);
4947 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4533 { 4948 {
4534 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4949 if (item.Type == 10 && item.ItemID == m_itemID)
4535 { 4950 {
4536 if (item.Type == 10 && item.ItemID == m_itemID) 4951 result = item.Name!=null?item.Name:String.Empty;
4537 { 4952 break;
4538 result = item.Name != null ? item.Name : String.Empty;
4539 break;
4540 }
4541 } 4953 }
4542 } 4954 }
4955 m_host.TaskInventory.LockItemsForRead(false);
4543 4956
4544 return result; 4957 return result;
4545 } 4958 }
@@ -4708,23 +5121,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4708 { 5121 {
4709 m_host.AddScriptLPS(1); 5122 m_host.AddScriptLPS(1);
4710 5123
4711 lock (m_host.TaskInventory) 5124 m_host.TaskInventory.LockItemsForRead(true);
5125 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4712 { 5126 {
4713 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5127 if (inv.Value.Name == name)
4714 { 5128 {
4715 if (inv.Value.Name == name) 5129 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4716 { 5130 {
4717 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5131 m_host.TaskInventory.LockItemsForRead(false);
4718 { 5132 return inv.Value.AssetID.ToString();
4719 return inv.Value.AssetID.ToString(); 5133 }
4720 } 5134 else
4721 else 5135 {
4722 { 5136 m_host.TaskInventory.LockItemsForRead(false);
4723 return UUID.Zero.ToString(); 5137 return UUID.Zero.ToString();
4724 }
4725 } 5138 }
4726 } 5139 }
4727 } 5140 }
5141 m_host.TaskInventory.LockItemsForRead(false);
4728 5142
4729 return UUID.Zero.ToString(); 5143 return UUID.Zero.ToString();
4730 } 5144 }
@@ -4877,14 +5291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4877 { 5291 {
4878 m_host.AddScriptLPS(1); 5292 m_host.AddScriptLPS(1);
4879 5293
4880 if (src == null) 5294 return src.Length;
4881 {
4882 return 0;
4883 }
4884 else
4885 {
4886 return src.Length;
4887 }
4888 } 5295 }
4889 5296
4890 public LSL_Integer llList2Integer(LSL_List src, int index) 5297 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4930,7 +5337,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 else if (src.Data[index] is LSL_Float) 5337 else if (src.Data[index] is LSL_Float)
4931 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5338 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4932 else if (src.Data[index] is LSL_String) 5339 else if (src.Data[index] is LSL_String)
4933 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5340 {
5341 string str = ((LSL_String) src.Data[index]).m_string;
5342 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5343 if (m != Match.Empty)
5344 {
5345 str = m.Value;
5346 double d = 0.0;
5347 if (!Double.TryParse(str, out d))
5348 return 0.0;
5349
5350 return d;
5351 }
5352 return 0.0;
5353 }
4934 return Convert.ToDouble(src.Data[index]); 5354 return Convert.ToDouble(src.Data[index]);
4935 } 5355 }
4936 catch (FormatException) 5356 catch (FormatException)
@@ -5203,7 +5623,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5203 } 5623 }
5204 } 5624 }
5205 } 5625 }
5206 else { 5626 else
5627 {
5207 object[] array = new object[src.Length]; 5628 object[] array = new object[src.Length];
5208 Array.Copy(src.Data, 0, array, 0, src.Length); 5629 Array.Copy(src.Data, 0, array, 0, src.Length);
5209 result = new LSL_List(array); 5630 result = new LSL_List(array);
@@ -5654,10 +6075,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5654 m_host.AddScriptLPS(1); 6075 m_host.AddScriptLPS(1);
5655 6076
5656 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6077 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5657 6078 if (parts.Count > 0)
5658 foreach (var part in parts)
5659 { 6079 {
5660 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6080 try
6081 {
6082 parts[0].ParentGroup.areUpdatesSuspended = true;
6083 foreach (var part in parts)
6084 {
6085 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6086 }
6087 }
6088 finally
6089 {
6090 parts[0].ParentGroup.areUpdatesSuspended = false;
6091 }
5661 } 6092 }
5662 } 6093 }
5663 6094
@@ -5711,6 +6142,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5711 ScriptSleep(5000); 6142 ScriptSleep(5000);
5712 } 6143 }
5713 6144
6145 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6146 {
6147 return ParseString2List(str, separators, in_spacers, false);
6148 }
6149
5714 public LSL_Integer llOverMyLand(string id) 6150 public LSL_Integer llOverMyLand(string id)
5715 { 6151 {
5716 m_host.AddScriptLPS(1); 6152 m_host.AddScriptLPS(1);
@@ -5911,7 +6347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5911 return m_host.ParentGroup.AttachmentPoint; 6347 return m_host.ParentGroup.AttachmentPoint;
5912 } 6348 }
5913 6349
5914 public LSL_Integer llGetFreeMemory() 6350 public virtual LSL_Integer llGetFreeMemory()
5915 { 6351 {
5916 m_host.AddScriptLPS(1); 6352 m_host.AddScriptLPS(1);
5917 // Make scripts designed for LSO happy 6353 // Make scripts designed for LSO happy
@@ -6028,7 +6464,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6028 SetParticleSystem(m_host, rules); 6464 SetParticleSystem(m_host, rules);
6029 } 6465 }
6030 6466
6031 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6467 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6468 {
6032 6469
6033 6470
6034 if (rules.Length == 0) 6471 if (rules.Length == 0)
@@ -6222,14 +6659,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6222 6659
6223 protected UUID GetTaskInventoryItem(string name) 6660 protected UUID GetTaskInventoryItem(string name)
6224 { 6661 {
6225 lock (m_host.TaskInventory) 6662 m_host.TaskInventory.LockItemsForRead(true);
6663 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6226 { 6664 {
6227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6665 if (inv.Value.Name == name)
6228 { 6666 {
6229 if (inv.Value.Name == name) 6667 m_host.TaskInventory.LockItemsForRead(false);
6230 return inv.Key; 6668 return inv.Key;
6231 } 6669 }
6232 } 6670 }
6671 m_host.TaskInventory.LockItemsForRead(false);
6233 6672
6234 return UUID.Zero; 6673 return UUID.Zero;
6235 } 6674 }
@@ -6479,13 +6918,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6479 UUID av = new UUID(); 6918 UUID av = new UUID();
6480 if (!UUID.TryParse(avatar,out av)) 6919 if (!UUID.TryParse(avatar,out av))
6481 { 6920 {
6482 LSLError("First parameter to llDialog needs to be a key"); 6921 //LSLError("First parameter to llDialog needs to be a key");
6483 return; 6922 return;
6484 } 6923 }
6485 if (buttons.Length < 1) 6924 if (buttons.Length < 1)
6486 { 6925 {
6487 LSLError("No less than 1 button can be shown"); 6926 buttons.Add("OK");
6488 return;
6489 } 6927 }
6490 if (buttons.Length > 12) 6928 if (buttons.Length > 12)
6491 { 6929 {
@@ -6502,7 +6940,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6502 } 6940 }
6503 if (buttons.Data[i].ToString().Length > 24) 6941 if (buttons.Data[i].ToString().Length > 24)
6504 { 6942 {
6505 LSLError("button label cannot be longer than 24 characters"); 6943 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6506 return; 6944 return;
6507 } 6945 }
6508 buts[i] = buttons.Data[i].ToString(); 6946 buts[i] = buttons.Data[i].ToString();
@@ -6561,22 +6999,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6561 } 6999 }
6562 7000
6563 // copy the first script found with this inventory name 7001 // copy the first script found with this inventory name
6564 lock (m_host.TaskInventory) 7002 TaskInventoryItem scriptItem = null;
7003 m_host.TaskInventory.LockItemsForRead(true);
7004 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6565 { 7005 {
6566 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7006 if (inv.Value.Name == name)
6567 { 7007 {
6568 if (inv.Value.Name == name) 7008 // make sure the object is a script
7009 if (10 == inv.Value.Type)
6569 { 7010 {
6570 // make sure the object is a script 7011 found = true;
6571 if (10 == inv.Value.Type) 7012 srcId = inv.Key;
6572 { 7013 scriptItem = inv.Value;
6573 found = true; 7014 break;
6574 srcId = inv.Key;
6575 break;
6576 }
6577 } 7015 }
6578 } 7016 }
6579 } 7017 }
7018 m_host.TaskInventory.LockItemsForRead(false);
6580 7019
6581 if (!found) 7020 if (!found)
6582 { 7021 {
@@ -6584,8 +7023,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6584 return; 7023 return;
6585 } 7024 }
6586 7025
6587 // the rest of the permission checks are done in RezScript, so check the pin there as well 7026 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6588 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7027 if (dest != null)
7028 {
7029 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7030 {
7031 // the rest of the permission checks are done in RezScript, so check the pin there as well
7032 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7033
7034 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7035 m_host.Inventory.RemoveInventoryItem(srcId);
7036 }
7037 }
6589 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7038 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6590 ScriptSleep(3000); 7039 ScriptSleep(3000);
6591 } 7040 }
@@ -6648,19 +7097,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6648 public LSL_String llMD5String(string src, int nonce) 7097 public LSL_String llMD5String(string src, int nonce)
6649 { 7098 {
6650 m_host.AddScriptLPS(1); 7099 m_host.AddScriptLPS(1);
6651 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7100 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6652 } 7101 }
6653 7102
6654 public LSL_String llSHA1String(string src) 7103 public LSL_String llSHA1String(string src)
6655 { 7104 {
6656 m_host.AddScriptLPS(1); 7105 m_host.AddScriptLPS(1);
6657 return Util.SHA1Hash(src).ToLower(); 7106 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6658 } 7107 }
6659 7108
6660 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7109 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6661 { 7110 {
6662 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7111 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6663 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7112 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7113 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7114 return shapeBlock;
6664 7115
6665 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7116 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6666 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7117 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6765,6 +7216,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6765 // Prim type box, cylinder and prism. 7216 // Prim type box, cylinder and prism.
6766 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7217 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6767 { 7218 {
7219 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7220 return;
7221
6768 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7222 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6769 ObjectShapePacket.ObjectDataBlock shapeBlock; 7223 ObjectShapePacket.ObjectDataBlock shapeBlock;
6770 7224
@@ -6818,6 +7272,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6818 // Prim type sphere. 7272 // Prim type sphere.
6819 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7273 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6820 { 7274 {
7275 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7276 return;
7277
6821 ObjectShapePacket.ObjectDataBlock shapeBlock; 7278 ObjectShapePacket.ObjectDataBlock shapeBlock;
6822 7279
6823 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7280 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6859,6 +7316,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6859 // Prim type torus, tube and ring. 7316 // Prim type torus, tube and ring.
6860 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7317 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
6861 { 7318 {
7319 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7320 return;
7321
6862 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7322 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6863 ObjectShapePacket.ObjectDataBlock shapeBlock; 7323 ObjectShapePacket.ObjectDataBlock shapeBlock;
6864 7324
@@ -6994,6 +7454,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6994 // Prim type sculpt. 7454 // Prim type sculpt.
6995 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7455 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6996 { 7456 {
7457 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7458 return;
7459
6997 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7460 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6998 UUID sculptId; 7461 UUID sculptId;
6999 7462
@@ -7010,13 +7473,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7010 shapeBlock.PathScaleX = 100; 7473 shapeBlock.PathScaleX = 100;
7011 shapeBlock.PathScaleY = 150; 7474 shapeBlock.PathScaleY = 150;
7012 7475
7013 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7476 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7014 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7477 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7015 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7478 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7016 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7479 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7017 { 7480 {
7018 // default 7481 // default
7019 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7482 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7020 } 7483 }
7021 7484
7022 part.Shape.SetSculptProperties((byte)type, sculptId); 7485 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7032,32 +7495,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7032 ScriptSleep(200); 7495 ScriptSleep(200);
7033 } 7496 }
7034 7497
7035 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7498 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7036 { 7499 {
7037 m_host.AddScriptLPS(1); 7500 m_host.AddScriptLPS(1);
7038 7501
7039 setLinkPrimParams(linknumber, rules); 7502 setLinkPrimParams(linknumber, rules);
7040
7041 ScriptSleep(200);
7042 } 7503 }
7043 7504
7044 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7505 private void setLinkPrimParams(int linknumber, LSL_List rules)
7045 { 7506 {
7046 m_host.AddScriptLPS(1); 7507 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7508 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7509 if (parts.Count>0)
7510 {
7511 try
7512 {
7513 parts[0].ParentGroup.areUpdatesSuspended = true;
7514 foreach (SceneObjectPart part in parts)
7515 SetPrimParams(part, rules);
7516 }
7517 finally
7518 {
7519 parts[0].ParentGroup.areUpdatesSuspended = false;
7520 }
7521 }
7522 if (avatars.Count > 0)
7523 {
7524 foreach (ScenePresence avatar in avatars)
7525 SetPrimParams(avatar, rules);
7526 }
7527 }
7047 7528
7048 setLinkPrimParams(linknumber, rules); 7529 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7530 {
7531 llSetLinkPrimitiveParamsFast(linknumber, rules);
7532 ScriptSleep(200);
7049 } 7533 }
7050 7534
7051 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7535 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7052 { 7536 {
7053 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7537 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7538 //We only support PRIM_POSITION and PRIM_ROTATION
7054 7539
7055 foreach (SceneObjectPart part in parts) 7540 int idx = 0;
7056 SetPrimParams(part, rules); 7541
7542 while (idx < rules.Length)
7543 {
7544 int code = rules.GetLSLIntegerItem(idx++);
7545
7546 int remain = rules.Length - idx;
7547
7548
7549
7550 switch (code)
7551 {
7552 case (int)ScriptBaseClass.PRIM_POSITION:
7553 if (remain < 1)
7554 return;
7555 LSL_Vector v;
7556 v = rules.GetVector3Item(idx++);
7557 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7558 av.SendAvatarDataToAllAgents();
7559
7560 break;
7561
7562 case (int)ScriptBaseClass.PRIM_ROTATION:
7563 if (remain < 1)
7564 return;
7565 LSL_Rotation r;
7566 r = rules.GetQuaternionItem(idx++);
7567 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7568 av.SendAvatarDataToAllAgents();
7569 break;
7570 }
7571 }
7057 } 7572 }
7058 7573
7059 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7574 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7060 { 7575 {
7576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7577 return;
7578
7061 int idx = 0; 7579 int idx = 0;
7062 7580
7063 bool positionChanged = false; 7581 bool positionChanged = false;
@@ -7462,6 +7980,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7462 } 7980 }
7463 } 7981 }
7464 } 7982 }
7983
7984 if (positionChanged)
7985 {
7986 if (part.ParentGroup.RootPart == part)
7987 {
7988 SceneObjectGroup parent = part.ParentGroup;
7989 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7990 }
7991 else
7992 {
7993 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7994 SceneObjectGroup parent = part.ParentGroup;
7995 parent.HasGroupChanged = true;
7996 parent.ScheduleGroupForTerseUpdate();
7997 }
7998 }
7465 } 7999 }
7466 8000
7467 public LSL_String llStringToBase64(string str) 8001 public LSL_String llStringToBase64(string str)
@@ -7610,13 +8144,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7610 public LSL_Integer llGetNumberOfPrims() 8144 public LSL_Integer llGetNumberOfPrims()
7611 { 8145 {
7612 m_host.AddScriptLPS(1); 8146 m_host.AddScriptLPS(1);
7613 int avatarCount = 0; 8147 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7614 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8148
7615 {
7616 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7617 avatarCount++;
7618 });
7619
7620 return m_host.ParentGroup.PrimCount + avatarCount; 8149 return m_host.ParentGroup.PrimCount + avatarCount;
7621 } 8150 }
7622 8151
@@ -7632,55 +8161,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7632 m_host.AddScriptLPS(1); 8161 m_host.AddScriptLPS(1);
7633 UUID objID = UUID.Zero; 8162 UUID objID = UUID.Zero;
7634 LSL_List result = new LSL_List(); 8163 LSL_List result = new LSL_List();
8164
8165 // If the ID is not valid, return null result
7635 if (!UUID.TryParse(obj, out objID)) 8166 if (!UUID.TryParse(obj, out objID))
7636 { 8167 {
7637 result.Add(new LSL_Vector()); 8168 result.Add(new LSL_Vector());
7638 result.Add(new LSL_Vector()); 8169 result.Add(new LSL_Vector());
7639 return result; 8170 return result;
7640 } 8171 }
8172
8173 // Check if this is an attached prim. If so, replace
8174 // the UUID with the avatar UUID and report it's bounding box
8175 SceneObjectPart part = World.GetSceneObjectPart(objID);
8176 if (part != null && part.ParentGroup.IsAttachment)
8177 objID = part.ParentGroup.AttachedAvatar;
8178
8179 // Find out if this is an avatar ID. If so, return it's box
7641 ScenePresence presence = World.GetScenePresence(objID); 8180 ScenePresence presence = World.GetScenePresence(objID);
7642 if (presence != null) 8181 if (presence != null)
7643 { 8182 {
7644 if (presence.ParentID == 0) // not sat on an object 8183 // As per LSL Wiki, there is no difference between sitting
8184 // and standing avatar since server 1.36
8185 LSL_Vector lower;
8186 LSL_Vector upper;
8187 if (presence.Animator.Animations.DefaultAnimation.AnimID
8188 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7645 { 8189 {
7646 LSL_Vector lower; 8190 // This is for ground sitting avatars
7647 LSL_Vector upper; 8191 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7648 if (presence.Animator.Animations.DefaultAnimation.AnimID 8192 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7649 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8193 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7650 {
7651 // This is for ground sitting avatars
7652 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7653 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7654 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7655 }
7656 else
7657 {
7658 // This is for standing/flying avatars
7659 float height = presence.Appearance.AvatarHeight / 2.0f;
7660 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7661 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7662 }
7663 result.Add(lower);
7664 result.Add(upper);
7665 return result;
7666 } 8194 }
7667 else 8195 else
7668 { 8196 {
7669 // sitting on an object so we need the bounding box of that 8197 // This is for standing/flying avatars
7670 // which should include the avatar so set the UUID to the 8198 float height = presence.Appearance.AvatarHeight / 2.0f;
7671 // UUID of the object the avatar is sat on and allow it to fall through 8199 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7672 // to processing an object 8200 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7673 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7674 objID = p.UUID;
7675 } 8201 }
8202
8203 // Adjust to the documented error offsets (see LSL Wiki)
8204 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8205 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8206
8207 if (lower.x > upper.x)
8208 lower.x = upper.x;
8209 if (lower.y > upper.y)
8210 lower.y = upper.y;
8211 if (lower.z > upper.z)
8212 lower.z = upper.z;
8213
8214 result.Add(lower);
8215 result.Add(upper);
8216 return result;
7676 } 8217 }
7677 SceneObjectPart part = World.GetSceneObjectPart(objID); 8218
8219 part = World.GetSceneObjectPart(objID);
7678 // Currently only works for single prims without a sitting avatar 8220 // Currently only works for single prims without a sitting avatar
7679 if (part != null) 8221 if (part != null)
7680 { 8222 {
7681 Vector3 halfSize = part.Scale / 2.0f; 8223 float minX;
7682 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8224 float maxX;
7683 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8225 float minY;
8226 float maxY;
8227 float minZ;
8228 float maxZ;
8229
8230 // This BBox is in sim coordinates, with the offset being
8231 // a contained point.
8232 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8233 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8234
8235 minX -= offsets[0].X;
8236 maxX -= offsets[0].X;
8237 minY -= offsets[0].Y;
8238 maxY -= offsets[0].Y;
8239 minZ -= offsets[0].Z;
8240 maxZ -= offsets[0].Z;
8241
8242 LSL_Vector lower;
8243 LSL_Vector upper;
8244
8245 // Adjust to the documented error offsets (see LSL Wiki)
8246 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8247 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8248
8249 if (lower.x > upper.x)
8250 lower.x = upper.x;
8251 if (lower.y > upper.y)
8252 lower.y = upper.y;
8253 if (lower.z > upper.z)
8254 lower.z = upper.z;
8255
7684 result.Add(lower); 8256 result.Add(lower);
7685 result.Add(upper); 8257 result.Add(upper);
7686 return result; 8258 return result;
@@ -7760,13 +8332,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7760 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8332 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7761 part.AbsolutePosition.Y, 8333 part.AbsolutePosition.Y,
7762 part.AbsolutePosition.Z); 8334 part.AbsolutePosition.Z);
7763 // For some reason, the part.AbsolutePosition.* values do not change if the
7764 // linkset is rotated; they always reflect the child prim's world position
7765 // as though the linkset is unrotated. This is incompatible behavior with SL's
7766 // implementation, so will break scripts imported from there (not to mention it
7767 // makes it more difficult to determine a child prim's actual inworld position).
7768 if (part.ParentID != 0)
7769 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7770 res.Add(v); 8335 res.Add(v);
7771 break; 8336 break;
7772 8337
@@ -7937,56 +8502,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7937 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8502 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7938 if (remain < 1) 8503 if (remain < 1)
7939 return res; 8504 return res;
7940 8505 face = (int)rules.GetLSLIntegerItem(idx++);
7941 face=(int)rules.GetLSLIntegerItem(idx++);
7942 8506
7943 tex = part.Shape.Textures; 8507 tex = part.Shape.Textures;
8508 int shiny;
7944 if (face == ScriptBaseClass.ALL_SIDES) 8509 if (face == ScriptBaseClass.ALL_SIDES)
7945 { 8510 {
7946 for (face = 0; face < GetNumberOfSides(part); face++) 8511 for (face = 0; face < GetNumberOfSides(part); face++)
7947 { 8512 {
7948 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8513 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7949 // Convert Shininess to PRIM_SHINY_* 8514 if (shinyness == Shininess.High)
7950 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8515 {
7951 // PRIM_BUMP_* 8516 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7952 res.Add(new LSL_Integer((int)texface.Bump)); 8517 }
8518 else if (shinyness == Shininess.Medium)
8519 {
8520 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8521 }
8522 else if (shinyness == Shininess.Low)
8523 {
8524 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8525 }
8526 else
8527 {
8528 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8529 }
8530 res.Add(new LSL_Integer(shiny));
8531 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7953 } 8532 }
7954 } 8533 }
7955 else 8534 else
7956 { 8535 {
7957 if (face >= 0 && face < GetNumberOfSides(part)) 8536 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8537 if (shinyness == Shininess.High)
7958 { 8538 {
7959 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8539 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7960 // Convert Shininess to PRIM_SHINY_* 8540 }
7961 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8541 else if (shinyness == Shininess.Medium)
7962 // PRIM_BUMP_* 8542 {
7963 res.Add(new LSL_Integer((int)texface.Bump)); 8543 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8544 }
8545 else if (shinyness == Shininess.Low)
8546 {
8547 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8548 }
8549 else
8550 {
8551 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7964 } 8552 }
8553 res.Add(new LSL_Integer(shiny));
8554 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7965 } 8555 }
7966 break; 8556 break;
7967 8557
7968 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8558 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7969 if (remain < 1) 8559 if (remain < 1)
7970 return res; 8560 return res;
7971 8561 face = (int)rules.GetLSLIntegerItem(idx++);
7972 face=(int)rules.GetLSLIntegerItem(idx++);
7973 8562
7974 tex = part.Shape.Textures; 8563 tex = part.Shape.Textures;
8564 int fullbright;
7975 if (face == ScriptBaseClass.ALL_SIDES) 8565 if (face == ScriptBaseClass.ALL_SIDES)
7976 { 8566 {
7977 for (face = 0; face < GetNumberOfSides(part); face++) 8567 for (face = 0; face < GetNumberOfSides(part); face++)
7978 { 8568 {
7979 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8569 if (tex.GetFace((uint)face).Fullbright == true)
7980 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8570 {
8571 fullbright = ScriptBaseClass.TRUE;
8572 }
8573 else
8574 {
8575 fullbright = ScriptBaseClass.FALSE;
8576 }
8577 res.Add(new LSL_Integer(fullbright));
7981 } 8578 }
7982 } 8579 }
7983 else 8580 else
7984 { 8581 {
7985 if (face >= 0 && face < GetNumberOfSides(part)) 8582 if (tex.GetFace((uint)face).Fullbright == true)
7986 { 8583 {
7987 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8584 fullbright = ScriptBaseClass.TRUE;
7988 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8585 }
8586 else
8587 {
8588 fullbright = ScriptBaseClass.FALSE;
7989 } 8589 }
8590 res.Add(new LSL_Integer(fullbright));
7990 } 8591 }
7991 break; 8592 break;
7992 8593
@@ -8008,27 +8609,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 break; 8609 break;
8009 8610
8010 case (int)ScriptBaseClass.PRIM_TEXGEN: 8611 case (int)ScriptBaseClass.PRIM_TEXGEN:
8612 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8011 if (remain < 1) 8613 if (remain < 1)
8012 return res; 8614 return res;
8013 8615 face = (int)rules.GetLSLIntegerItem(idx++);
8014 face=(int)rules.GetLSLIntegerItem(idx++);
8015 8616
8016 tex = part.Shape.Textures; 8617 tex = part.Shape.Textures;
8017 if (face == ScriptBaseClass.ALL_SIDES) 8618 if (face == ScriptBaseClass.ALL_SIDES)
8018 { 8619 {
8019 for (face = 0; face < GetNumberOfSides(part); face++) 8620 for (face = 0; face < GetNumberOfSides(part); face++)
8020 { 8621 {
8021 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8622 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8022 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8623 {
8023 res.Add(new LSL_Integer((uint)texgen >> 1)); 8624 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8625 }
8626 else
8627 {
8628 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8629 }
8024 } 8630 }
8025 } 8631 }
8026 else 8632 else
8027 { 8633 {
8028 if (face >= 0 && face < GetNumberOfSides(part)) 8634 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8635 {
8636 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8637 }
8638 else
8029 { 8639 {
8030 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8640 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8031 res.Add(new LSL_Integer((uint)texgen >> 1));
8032 } 8641 }
8033 } 8642 }
8034 break; 8643 break;
@@ -8051,28 +8660,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8051 case (int)ScriptBaseClass.PRIM_GLOW: 8660 case (int)ScriptBaseClass.PRIM_GLOW:
8052 if (remain < 1) 8661 if (remain < 1)
8053 return res; 8662 return res;
8054 8663 face = (int)rules.GetLSLIntegerItem(idx++);
8055 face=(int)rules.GetLSLIntegerItem(idx++);
8056 8664
8057 tex = part.Shape.Textures; 8665 tex = part.Shape.Textures;
8666 float primglow;
8058 if (face == ScriptBaseClass.ALL_SIDES) 8667 if (face == ScriptBaseClass.ALL_SIDES)
8059 { 8668 {
8060 for (face = 0; face < GetNumberOfSides(part); face++) 8669 for (face = 0; face < GetNumberOfSides(part); face++)
8061 { 8670 {
8062 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8671 primglow = tex.GetFace((uint)face).Glow;
8063 res.Add(new LSL_Float(texface.Glow)); 8672 res.Add(new LSL_Float(primglow));
8064 } 8673 }
8065 } 8674 }
8066 else 8675 else
8067 { 8676 {
8068 if (face >= 0 && face < GetNumberOfSides(part)) 8677 primglow = tex.GetFace((uint)face).Glow;
8069 { 8678 res.Add(new LSL_Float(primglow));
8070 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8071 res.Add(new LSL_Float(texface.Glow));
8072 }
8073 } 8679 }
8074 break; 8680 break;
8075
8076 case (int)ScriptBaseClass.PRIM_TEXT: 8681 case (int)ScriptBaseClass.PRIM_TEXT:
8077 Color4 textColor = part.GetTextColor(); 8682 Color4 textColor = part.GetTextColor();
8078 res.Add(new LSL_String(part.Text)); 8683 res.Add(new LSL_String(part.Text));
@@ -8621,8 +9226,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8621 // The function returns an ordered list 9226 // The function returns an ordered list
8622 // representing the tokens found in the supplied 9227 // representing the tokens found in the supplied
8623 // sources string. If two successive tokenizers 9228 // sources string. If two successive tokenizers
8624 // are encountered, then a NULL entry is added 9229 // are encountered, then a null-string entry is
8625 // to the list. 9230 // added to the list.
8626 // 9231 //
8627 // It is a precondition that the source and 9232 // It is a precondition that the source and
8628 // toekizer lisst are non-null. If they are null, 9233 // toekizer lisst are non-null. If they are null,
@@ -8630,7 +9235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8630 // while their lengths are being determined. 9235 // while their lengths are being determined.
8631 // 9236 //
8632 // A small amount of working memoryis required 9237 // A small amount of working memoryis required
8633 // of approximately 8*#tokenizers. 9238 // of approximately 8*#tokenizers + 8*srcstrlen.
8634 // 9239 //
8635 // There are many ways in which this function 9240 // There are many ways in which this function
8636 // can be implemented, this implementation is 9241 // can be implemented, this implementation is
@@ -8646,155 +9251,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8646 // and eliminates redundant tokenizers as soon 9251 // and eliminates redundant tokenizers as soon
8647 // as is possible. 9252 // as is possible.
8648 // 9253 //
8649 // The implementation tries to avoid any copying 9254 // The implementation tries to minimize temporary
8650 // of arrays or other objects. 9255 // garbage generation.
8651 // </remarks> 9256 // </remarks>
8652 9257
8653 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9258 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8654 { 9259 {
8655 int beginning = 0; 9260 return ParseString2List(src, separators, spacers, true);
8656 int srclen = src.Length; 9261 }
8657 int seplen = separators.Length;
8658 object[] separray = separators.Data;
8659 int spclen = spacers.Length;
8660 object[] spcarray = spacers.Data;
8661 int mlen = seplen+spclen;
8662
8663 int[] offset = new int[mlen+1];
8664 bool[] active = new bool[mlen];
8665
8666 int best;
8667 int j;
8668
8669 // Initial capacity reduces resize cost
8670 9262
8671 LSL_List tokens = new LSL_List(); 9263 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9264 {
9265 int srclen = src.Length;
9266 int seplen = separators.Length;
9267 object[] separray = separators.Data;
9268 int spclen = spacers.Length;
9269 object[] spcarray = spacers.Data;
9270 int dellen = 0;
9271 string[] delarray = new string[seplen+spclen];
8672 9272
8673 // All entries are initially valid 9273 int outlen = 0;
9274 string[] outarray = new string[srclen*2+1];
8674 9275
8675 for (int i = 0; i < mlen; i++) 9276 int i, j;
8676 active[i] = true; 9277 string d;
8677 9278
8678 offset[mlen] = srclen; 9279 m_host.AddScriptLPS(1);
8679 9280
8680 while (beginning < srclen) 9281 /*
9282 * Convert separator and spacer lists to C# strings.
9283 * Also filter out null strings so we don't hang.
9284 */
9285 for (i = 0; i < seplen; i ++)
8681 { 9286 {
9287 d = separray[i].ToString();
9288 if (d.Length > 0)
9289 {
9290 delarray[dellen++] = d;
9291 }
9292 }
9293 seplen = dellen;
8682 9294
8683 best = mlen; // as bad as it gets 9295 for (i = 0; i < spclen; i ++)
9296 {
9297 d = spcarray[i].ToString();
9298 if (d.Length > 0)
9299 {
9300 delarray[dellen++] = d;
9301 }
9302 }
8684 9303
8685 // Scan for separators 9304 /*
9305 * Scan through source string from beginning to end.
9306 */
9307 for (i = 0;;)
9308 {
8686 9309
8687 for (j = 0; j < seplen; j++) 9310 /*
9311 * Find earliest delimeter in src starting at i (if any).
9312 */
9313 int earliestDel = -1;
9314 int earliestSrc = srclen;
9315 string earliestStr = null;
9316 for (j = 0; j < dellen; j ++)
8688 { 9317 {
8689 if (separray[j].ToString() == String.Empty) 9318 d = delarray[j];
8690 active[j] = false; 9319 if (d != null)
8691
8692 if (active[j])
8693 { 9320 {
8694 // scan all of the markers 9321 int index = src.IndexOf(d, i);
8695 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9322 if (index < 0)
8696 { 9323 {
8697 // not present at all 9324 delarray[j] = null; // delim nowhere in src, don't check it anymore
8698 active[j] = false;
8699 } 9325 }
8700 else 9326 else if (index < earliestSrc)
8701 { 9327 {
8702 // present and correct 9328 earliestSrc = index; // where delimeter starts in source string
8703 if (offset[j] < offset[best]) 9329 earliestDel = j; // where delimeter is in delarray[]
8704 { 9330 earliestStr = d; // the delimeter string from delarray[]
8705 // closest so far 9331 if (index == i) break; // can't do any better than found at beg of string
8706 best = j;
8707 if (offset[best] == beginning)
8708 break;
8709 }
8710 } 9332 }
8711 } 9333 }
8712 } 9334 }
8713 9335
8714 // Scan for spacers 9336 /*
8715 9337 * Output source string starting at i through start of earliest delimeter.
8716 if (offset[best] != beginning) 9338 */
9339 if (keepNulls || (earliestSrc > i))
8717 { 9340 {
8718 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9341 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8719 {
8720 if (spcarray[j-seplen].ToString() == String.Empty)
8721 active[j] = false;
8722
8723 if (active[j])
8724 {
8725 // scan all of the markers
8726 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8727 {
8728 // not present at all
8729 active[j] = false;
8730 }
8731 else
8732 {
8733 // present and correct
8734 if (offset[j] < offset[best])
8735 {
8736 // closest so far
8737 best = j;
8738 }
8739 }
8740 }
8741 }
8742 } 9342 }
8743 9343
8744 // This is the normal exit from the scanning loop 9344 /*
9345 * If no delimeter found at or after i, we're done scanning.
9346 */
9347 if (earliestDel < 0) break;
8745 9348
8746 if (best == mlen) 9349 /*
9350 * If delimeter was a spacer, output the spacer.
9351 */
9352 if (earliestDel >= seplen)
8747 { 9353 {
8748 // no markers were found on this pass 9354 outarray[outlen++] = earliestStr;
8749 // so we're pretty much done
8750 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8751 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8752 break;
8753 } 9355 }
8754 9356
8755 // Otherwise we just add the newly delimited token 9357 /*
8756 // and recalculate where the search should continue. 9358 * Look at rest of src string following delimeter.
8757 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9359 */
8758 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9360 i = earliestSrc + earliestStr.Length;
8759
8760 if (best < seplen)
8761 {
8762 beginning = offset[best] + (separray[best].ToString()).Length;
8763 }
8764 else
8765 {
8766 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8767 string str = spcarray[best - seplen].ToString();
8768 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8769 tokens.Add(new LSL_String(str));
8770 }
8771 } 9361 }
8772 9362
8773 // This an awkward an not very intuitive boundary case. If the 9363 /*
8774 // last substring is a tokenizer, then there is an implied trailing 9364 * Make up an exact-sized output array suitable for an LSL_List object.
8775 // null list entry. Hopefully the single comparison will not be too 9365 */
8776 // arduous. Alternatively the 'break' could be replced with a return 9366 object[] outlist = new object[outlen];
8777 // but that's shabby programming. 9367 for (i = 0; i < outlen; i ++)
8778
8779 if ((beginning == srclen) && (keepNulls))
8780 { 9368 {
8781 if (srclen != 0) 9369 outlist[i] = new LSL_String(outarray[i]);
8782 tokens.Add(new LSL_String(""));
8783 } 9370 }
8784 9371 return new LSL_List(outlist);
8785 return tokens;
8786 }
8787
8788 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8789 {
8790 m_host.AddScriptLPS(1);
8791 return this.ParseString(src, separators, spacers, false);
8792 }
8793
8794 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8795 {
8796 m_host.AddScriptLPS(1);
8797 return this.ParseString(src, separators, spacers, true);
8798 } 9372 }
8799 9373
8800 public LSL_Integer llGetObjectPermMask(int mask) 9374 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8871,28 +9445,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8871 { 9445 {
8872 m_host.AddScriptLPS(1); 9446 m_host.AddScriptLPS(1);
8873 9447
8874 lock (m_host.TaskInventory) 9448 m_host.TaskInventory.LockItemsForRead(true);
9449 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8875 { 9450 {
8876 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9451 if (inv.Value.Name == item)
8877 { 9452 {
8878 if (inv.Value.Name == item) 9453 m_host.TaskInventory.LockItemsForRead(false);
9454 switch (mask)
8879 { 9455 {
8880 switch (mask) 9456 case 0:
8881 { 9457 return (int)inv.Value.BasePermissions;
8882 case 0: 9458 case 1:
8883 return (int)inv.Value.BasePermissions; 9459 return (int)inv.Value.CurrentPermissions;
8884 case 1: 9460 case 2:
8885 return (int)inv.Value.CurrentPermissions; 9461 return (int)inv.Value.GroupPermissions;
8886 case 2: 9462 case 3:
8887 return (int)inv.Value.GroupPermissions; 9463 return (int)inv.Value.EveryonePermissions;
8888 case 3: 9464 case 4:
8889 return (int)inv.Value.EveryonePermissions; 9465 return (int)inv.Value.NextPermissions;
8890 case 4:
8891 return (int)inv.Value.NextPermissions;
8892 }
8893 } 9466 }
8894 } 9467 }
8895 } 9468 }
9469 m_host.TaskInventory.LockItemsForRead(false);
8896 9470
8897 return -1; 9471 return -1;
8898 } 9472 }
@@ -8939,16 +9513,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8939 { 9513 {
8940 m_host.AddScriptLPS(1); 9514 m_host.AddScriptLPS(1);
8941 9515
8942 lock (m_host.TaskInventory) 9516 m_host.TaskInventory.LockItemsForRead(true);
9517 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8943 { 9518 {
8944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9519 if (inv.Value.Name == item)
8945 { 9520 {
8946 if (inv.Value.Name == item) 9521 m_host.TaskInventory.LockItemsForRead(false);
8947 { 9522 return inv.Value.CreatorID.ToString();
8948 return inv.Value.CreatorID.ToString();
8949 }
8950 } 9523 }
8951 } 9524 }
9525 m_host.TaskInventory.LockItemsForRead(false);
8952 9526
8953 llSay(0, "No item name '" + item + "'"); 9527 llSay(0, "No item name '" + item + "'");
8954 9528
@@ -9096,7 +9670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9096 } 9670 }
9097 9671
9098 /// <summary> 9672 /// <summary>
9099 /// illListReplaceList removes the sub-list defined by the inclusive indices 9673 /// llListReplaceList removes the sub-list defined by the inclusive indices
9100 /// start and end and inserts the src list in its place. The inclusive 9674 /// start and end and inserts the src list in its place. The inclusive
9101 /// nature of the indices means that at least one element must be deleted 9675 /// nature of the indices means that at least one element must be deleted
9102 /// if the indices are within the bounds of the existing list. I.e. 2,2 9676 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9153,16 +9727,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9153 // based upon end. Note that if end exceeds the upper 9727 // based upon end. Note that if end exceeds the upper
9154 // bound in this case, the entire destination list 9728 // bound in this case, the entire destination list
9155 // is removed. 9729 // is removed.
9156 else 9730 else if (start == 0)
9157 { 9731 {
9158 if (end + 1 < dest.Length) 9732 if (end + 1 < dest.Length)
9159 {
9160 return src + dest.GetSublist(end + 1, -1); 9733 return src + dest.GetSublist(end + 1, -1);
9161 }
9162 else 9734 else
9163 {
9164 return src; 9735 return src;
9165 } 9736 }
9737 else // Start < 0
9738 {
9739 if (end + 1 < dest.Length)
9740 return dest.GetSublist(end + 1, -1);
9741 else
9742 return new LSL_List();
9166 } 9743 }
9167 } 9744 }
9168 // Finally, if start > end, we strip away a prefix and 9745 // Finally, if start > end, we strip away a prefix and
@@ -9213,17 +9790,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9213 int width = 0; 9790 int width = 0;
9214 int height = 0; 9791 int height = 0;
9215 9792
9216 ParcelMediaCommandEnum? commandToSend = null; 9793 uint commandToSend = 0;
9217 float time = 0.0f; // default is from start 9794 float time = 0.0f; // default is from start
9218 9795
9219 ScenePresence presence = null; 9796 ScenePresence presence = null;
9220 9797
9221 for (int i = 0; i < commandList.Data.Length; i++) 9798 for (int i = 0; i < commandList.Data.Length; i++)
9222 { 9799 {
9223 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9800 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9224 switch (command) 9801 switch (command)
9225 { 9802 {
9226 case ParcelMediaCommandEnum.Agent: 9803 case (uint)ParcelMediaCommandEnum.Agent:
9227 // we send only to one agent 9804 // we send only to one agent
9228 if ((i + 1) < commandList.Length) 9805 if ((i + 1) < commandList.Length)
9229 { 9806 {
@@ -9240,25 +9817,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9240 } 9817 }
9241 break; 9818 break;
9242 9819
9243 case ParcelMediaCommandEnum.Loop: 9820 case (uint)ParcelMediaCommandEnum.Loop:
9244 loop = 1; 9821 loop = 1;
9245 commandToSend = command; 9822 commandToSend = command;
9246 update = true; //need to send the media update packet to set looping 9823 update = true; //need to send the media update packet to set looping
9247 break; 9824 break;
9248 9825
9249 case ParcelMediaCommandEnum.Play: 9826 case (uint)ParcelMediaCommandEnum.Play:
9250 loop = 0; 9827 loop = 0;
9251 commandToSend = command; 9828 commandToSend = command;
9252 update = true; //need to send the media update packet to make sure it doesn't loop 9829 update = true; //need to send the media update packet to make sure it doesn't loop
9253 break; 9830 break;
9254 9831
9255 case ParcelMediaCommandEnum.Pause: 9832 case (uint)ParcelMediaCommandEnum.Pause:
9256 case ParcelMediaCommandEnum.Stop: 9833 case (uint)ParcelMediaCommandEnum.Stop:
9257 case ParcelMediaCommandEnum.Unload: 9834 case (uint)ParcelMediaCommandEnum.Unload:
9258 commandToSend = command; 9835 commandToSend = command;
9259 break; 9836 break;
9260 9837
9261 case ParcelMediaCommandEnum.Url: 9838 case (uint)ParcelMediaCommandEnum.Url:
9262 if ((i + 1) < commandList.Length) 9839 if ((i + 1) < commandList.Length)
9263 { 9840 {
9264 if (commandList.Data[i + 1] is LSL_String) 9841 if (commandList.Data[i + 1] is LSL_String)
@@ -9271,7 +9848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9271 } 9848 }
9272 break; 9849 break;
9273 9850
9274 case ParcelMediaCommandEnum.Texture: 9851 case (uint)ParcelMediaCommandEnum.Texture:
9275 if ((i + 1) < commandList.Length) 9852 if ((i + 1) < commandList.Length)
9276 { 9853 {
9277 if (commandList.Data[i + 1] is LSL_String) 9854 if (commandList.Data[i + 1] is LSL_String)
@@ -9284,7 +9861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9284 } 9861 }
9285 break; 9862 break;
9286 9863
9287 case ParcelMediaCommandEnum.Time: 9864 case (uint)ParcelMediaCommandEnum.Time:
9288 if ((i + 1) < commandList.Length) 9865 if ((i + 1) < commandList.Length)
9289 { 9866 {
9290 if (commandList.Data[i + 1] is LSL_Float) 9867 if (commandList.Data[i + 1] is LSL_Float)
@@ -9296,7 +9873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9296 } 9873 }
9297 break; 9874 break;
9298 9875
9299 case ParcelMediaCommandEnum.AutoAlign: 9876 case (uint)ParcelMediaCommandEnum.AutoAlign:
9300 if ((i + 1) < commandList.Length) 9877 if ((i + 1) < commandList.Length)
9301 { 9878 {
9302 if (commandList.Data[i + 1] is LSL_Integer) 9879 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9310,7 +9887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9310 } 9887 }
9311 break; 9888 break;
9312 9889
9313 case ParcelMediaCommandEnum.Type: 9890 case (uint)ParcelMediaCommandEnum.Type:
9314 if ((i + 1) < commandList.Length) 9891 if ((i + 1) < commandList.Length)
9315 { 9892 {
9316 if (commandList.Data[i + 1] is LSL_String) 9893 if (commandList.Data[i + 1] is LSL_String)
@@ -9323,7 +9900,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 } 9900 }
9324 break; 9901 break;
9325 9902
9326 case ParcelMediaCommandEnum.Desc: 9903 case (uint)ParcelMediaCommandEnum.Desc:
9327 if ((i + 1) < commandList.Length) 9904 if ((i + 1) < commandList.Length)
9328 { 9905 {
9329 if (commandList.Data[i + 1] is LSL_String) 9906 if (commandList.Data[i + 1] is LSL_String)
@@ -9336,7 +9913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9336 } 9913 }
9337 break; 9914 break;
9338 9915
9339 case ParcelMediaCommandEnum.Size: 9916 case (uint)ParcelMediaCommandEnum.Size:
9340 if ((i + 2) < commandList.Length) 9917 if ((i + 2) < commandList.Length)
9341 { 9918 {
9342 if (commandList.Data[i + 1] is LSL_Integer) 9919 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9406,7 +9983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9406 } 9983 }
9407 } 9984 }
9408 9985
9409 if (commandToSend != null) 9986 if (commandToSend != 0)
9410 { 9987 {
9411 // the commandList contained a start/stop/... command, too 9988 // the commandList contained a start/stop/... command, too
9412 if (presence == null) 9989 if (presence == null)
@@ -9443,7 +10020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9443 10020
9444 if (aList.Data[i] != null) 10021 if (aList.Data[i] != null)
9445 { 10022 {
9446 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10023 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9447 { 10024 {
9448 case ParcelMediaCommandEnum.Url: 10025 case ParcelMediaCommandEnum.Url:
9449 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10026 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9486,16 +10063,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9486 { 10063 {
9487 m_host.AddScriptLPS(1); 10064 m_host.AddScriptLPS(1);
9488 10065
9489 lock (m_host.TaskInventory) 10066 m_host.TaskInventory.LockItemsForRead(true);
10067 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9490 { 10068 {
9491 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10069 if (inv.Value.Name == name)
9492 { 10070 {
9493 if (inv.Value.Name == name) 10071 m_host.TaskInventory.LockItemsForRead(false);
9494 { 10072 return inv.Value.Type;
9495 return inv.Value.Type;
9496 }
9497 } 10073 }
9498 } 10074 }
10075 m_host.TaskInventory.LockItemsForRead(false);
9499 10076
9500 return -1; 10077 return -1;
9501 } 10078 }
@@ -9506,15 +10083,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 10083
9507 if (quick_pay_buttons.Data.Length < 4) 10084 if (quick_pay_buttons.Data.Length < 4)
9508 { 10085 {
9509 LSLError("List must have at least 4 elements"); 10086 int x;
9510 return; 10087 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10088 {
10089 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10090 }
9511 } 10091 }
9512 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10092 int[] nPrice = new int[5];
9513 10093 nPrice[0] = price;
9514 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10094 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9515 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10095 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9516 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10096 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9517 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10097 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10098 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9518 m_host.ParentGroup.HasGroupChanged = true; 10099 m_host.ParentGroup.HasGroupChanged = true;
9519 } 10100 }
9520 10101
@@ -9526,17 +10107,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9526 if (invItemID == UUID.Zero) 10107 if (invItemID == UUID.Zero)
9527 return new LSL_Vector(); 10108 return new LSL_Vector();
9528 10109
9529 lock (m_host.TaskInventory) 10110 m_host.TaskInventory.LockItemsForRead(true);
10111 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9530 { 10112 {
9531 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10113 m_host.TaskInventory.LockItemsForRead(false);
9532 return new LSL_Vector(); 10114 return new LSL_Vector();
10115 }
9533 10116
9534 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10117 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9535 { 10118 {
9536 ShoutError("No permissions to track the camera"); 10119 ShoutError("No permissions to track the camera");
9537 return new LSL_Vector(); 10120 m_host.TaskInventory.LockItemsForRead(false);
9538 } 10121 return new LSL_Vector();
9539 } 10122 }
10123 m_host.TaskInventory.LockItemsForRead(false);
9540 10124
9541 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10125 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9542 if (presence != null) 10126 if (presence != null)
@@ -9554,17 +10138,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9554 if (invItemID == UUID.Zero) 10138 if (invItemID == UUID.Zero)
9555 return new LSL_Rotation(); 10139 return new LSL_Rotation();
9556 10140
9557 lock (m_host.TaskInventory) 10141 m_host.TaskInventory.LockItemsForRead(true);
10142 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9558 { 10143 {
9559 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10144 m_host.TaskInventory.LockItemsForRead(false);
9560 return new LSL_Rotation(); 10145 return new LSL_Rotation();
9561
9562 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9563 {
9564 ShoutError("No permissions to track the camera");
9565 return new LSL_Rotation();
9566 }
9567 } 10146 }
10147 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10148 {
10149 ShoutError("No permissions to track the camera");
10150 m_host.TaskInventory.LockItemsForRead(false);
10151 return new LSL_Rotation();
10152 }
10153 m_host.TaskInventory.LockItemsForRead(false);
9568 10154
9569 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10155 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9570 if (presence != null) 10156 if (presence != null)
@@ -9626,8 +10212,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9626 { 10212 {
9627 m_host.AddScriptLPS(1); 10213 m_host.AddScriptLPS(1);
9628 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10214 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9629 if (detectedParams == null) return; // only works on the first detected avatar 10215 if (detectedParams == null)
9630 10216 {
10217 if (m_host.ParentGroup.IsAttachment == true)
10218 {
10219 detectedParams = new DetectParams();
10220 detectedParams.Key = m_host.OwnerID;
10221 }
10222 else
10223 {
10224 return;
10225 }
10226 }
10227
9631 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10228 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9632 if (avatar != null) 10229 if (avatar != null)
9633 { 10230 {
@@ -9635,6 +10232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9635 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10232 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9636 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10233 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9637 } 10234 }
10235
9638 ScriptSleep(1000); 10236 ScriptSleep(1000);
9639 } 10237 }
9640 10238
@@ -9727,14 +10325,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9727 if (objectID == UUID.Zero) return; 10325 if (objectID == UUID.Zero) return;
9728 10326
9729 UUID agentID; 10327 UUID agentID;
9730 lock (m_host.TaskInventory) 10328 m_host.TaskInventory.LockItemsForRead(true);
9731 { 10329 // we need the permission first, to know which avatar we want to set the camera for
9732 // we need the permission first, to know which avatar we want to set the camera for 10330 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9733 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9734 10331
9735 if (agentID == UUID.Zero) return; 10332 if (agentID == UUID.Zero)
9736 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10333 {
10334 m_host.TaskInventory.LockItemsForRead(false);
10335 return;
10336 }
10337 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10338 {
10339 m_host.TaskInventory.LockItemsForRead(false);
10340 return;
9737 } 10341 }
10342 m_host.TaskInventory.LockItemsForRead(false);
9738 10343
9739 ScenePresence presence = World.GetScenePresence(agentID); 10344 ScenePresence presence = World.GetScenePresence(agentID);
9740 10345
@@ -9743,12 +10348,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9743 10348
9744 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10349 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9745 object[] data = rules.Data; 10350 object[] data = rules.Data;
9746 for (int i = 0; i < data.Length; ++i) { 10351 for (int i = 0; i < data.Length; ++i)
10352 {
9747 int type = Convert.ToInt32(data[i++].ToString()); 10353 int type = Convert.ToInt32(data[i++].ToString());
9748 if (i >= data.Length) break; // odd number of entries => ignore the last 10354 if (i >= data.Length) break; // odd number of entries => ignore the last
9749 10355
9750 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10356 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9751 switch (type) { 10357 switch (type)
10358 {
9752 case ScriptBaseClass.CAMERA_FOCUS: 10359 case ScriptBaseClass.CAMERA_FOCUS:
9753 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10360 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9754 case ScriptBaseClass.CAMERA_POSITION: 10361 case ScriptBaseClass.CAMERA_POSITION:
@@ -9784,12 +10391,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9784 10391
9785 // we need the permission first, to know which avatar we want to clear the camera for 10392 // we need the permission first, to know which avatar we want to clear the camera for
9786 UUID agentID; 10393 UUID agentID;
9787 lock (m_host.TaskInventory) 10394 m_host.TaskInventory.LockItemsForRead(true);
10395 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10396 if (agentID == UUID.Zero)
9788 { 10397 {
9789 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10398 m_host.TaskInventory.LockItemsForRead(false);
9790 if (agentID == UUID.Zero) return; 10399 return;
9791 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10400 }
10401 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10402 {
10403 m_host.TaskInventory.LockItemsForRead(false);
10404 return;
9792 } 10405 }
10406 m_host.TaskInventory.LockItemsForRead(false);
9793 10407
9794 ScenePresence presence = World.GetScenePresence(agentID); 10408 ScenePresence presence = World.GetScenePresence(agentID);
9795 10409
@@ -9856,19 +10470,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9856 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10470 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9857 { 10471 {
9858 m_host.AddScriptLPS(1); 10472 m_host.AddScriptLPS(1);
9859 string ret = String.Empty; 10473
9860 string src1 = llBase64ToString(str1); 10474 if (str1 == String.Empty)
9861 string src2 = llBase64ToString(str2); 10475 return String.Empty;
9862 int c = 0; 10476 if (str2 == String.Empty)
9863 for (int i = 0; i < src1.Length; i++) 10477 return str1;
10478
10479 int len = str2.Length;
10480 if ((len % 4) != 0) // LL is EVIL!!!!
9864 { 10481 {
9865 ret += (char) (src1[i] ^ src2[c]); 10482 while (str2.EndsWith("="))
10483 str2 = str2.Substring(0, str2.Length - 1);
10484
10485 len = str2.Length;
10486 int mod = len % 4;
10487
10488 if (mod == 1)
10489 str2 = str2.Substring(0, str2.Length - 1);
10490 else if (mod == 2)
10491 str2 += "==";
10492 else if (mod == 3)
10493 str2 += "=";
10494 }
9866 10495
9867 c++; 10496 byte[] data1;
9868 if (c >= src2.Length) 10497 byte[] data2;
9869 c = 0; 10498 try
10499 {
10500 data1 = Convert.FromBase64String(str1);
10501 data2 = Convert.FromBase64String(str2);
9870 } 10502 }
9871 return llStringToBase64(ret); 10503 catch (Exception)
10504 {
10505 return new LSL_String(String.Empty);
10506 }
10507
10508 byte[] d2 = new Byte[data1.Length];
10509 int pos = 0;
10510
10511 if (data1.Length <= data2.Length)
10512 {
10513 Array.Copy(data2, 0, d2, 0, data1.Length);
10514 }
10515 else
10516 {
10517 while (pos < data1.Length)
10518 {
10519 len = data1.Length - pos;
10520 if (len > data2.Length)
10521 len = data2.Length;
10522
10523 Array.Copy(data2, 0, d2, pos, len);
10524 pos += len;
10525 }
10526 }
10527
10528 for (pos = 0 ; pos < data1.Length ; pos++ )
10529 data1[pos] ^= d2[pos];
10530
10531 return Convert.ToBase64String(data1);
9872 } 10532 }
9873 10533
9874 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10534 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9925,12 +10585,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9925 Regex r = new Regex(authregex); 10585 Regex r = new Regex(authregex);
9926 int[] gnums = r.GetGroupNumbers(); 10586 int[] gnums = r.GetGroupNumbers();
9927 Match m = r.Match(url); 10587 Match m = r.Match(url);
9928 if (m.Success) { 10588 if (m.Success)
9929 for (int i = 1; i < gnums.Length; i++) { 10589 {
10590 for (int i = 1; i < gnums.Length; i++)
10591 {
9930 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10592 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9931 //CaptureCollection cc = g.Captures; 10593 //CaptureCollection cc = g.Captures;
9932 } 10594 }
9933 if (m.Groups.Count == 5) { 10595 if (m.Groups.Count == 5)
10596 {
9934 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10597 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9935 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10598 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9936 } 10599 }
@@ -10216,15 +10879,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10216 10879
10217 internal UUID ScriptByName(string name) 10880 internal UUID ScriptByName(string name)
10218 { 10881 {
10219 lock (m_host.TaskInventory) 10882 m_host.TaskInventory.LockItemsForRead(true);
10883
10884 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10220 { 10885 {
10221 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10886 if (item.Type == 10 && item.Name == name)
10222 { 10887 {
10223 if (item.Type == 10 && item.Name == name) 10888 m_host.TaskInventory.LockItemsForRead(false);
10224 return item.ItemID; 10889 return item.ItemID;
10225 } 10890 }
10226 } 10891 }
10227 10892
10893 m_host.TaskInventory.LockItemsForRead(false);
10894
10228 return UUID.Zero; 10895 return UUID.Zero;
10229 } 10896 }
10230 10897
@@ -10265,6 +10932,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10265 { 10932 {
10266 m_host.AddScriptLPS(1); 10933 m_host.AddScriptLPS(1);
10267 10934
10935 //Clone is thread safe
10268 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10936 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10269 10937
10270 UUID assetID = UUID.Zero; 10938 UUID assetID = UUID.Zero;
@@ -10327,6 +10995,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10327 { 10995 {
10328 m_host.AddScriptLPS(1); 10996 m_host.AddScriptLPS(1);
10329 10997
10998 //Clone is thread safe
10330 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10999 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10331 11000
10332 UUID assetID = UUID.Zero; 11001 UUID assetID = UUID.Zero;
@@ -10407,15 +11076,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10407 return GetLinkPrimitiveParams(obj, rules); 11076 return GetLinkPrimitiveParams(obj, rules);
10408 } 11077 }
10409 11078
10410 public void print(string str) 11079 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10411 { 11080 {
10412 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11081 List<SceneObjectPart> parts = GetLinkParts(link);
10413 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11082 if (parts.Count < 1)
10414 if (ossl != null) 11083 return 0;
10415 { 11084
10416 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11085 return GetNumberOfSides(parts[0]);
10417 m_log.Info("LSL print():" + str);
10418 }
10419 } 11086 }
10420 11087
10421 private string Name2Username(string name) 11088 private string Name2Username(string name)
@@ -10461,6 +11128,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10461 return rq.ToString(); 11128 return rq.ToString();
10462 } 11129 }
10463 11130
11131 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11132 {
11133 m_SayShoutCount = 0;
11134 }
10464 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11135 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10465 { 11136 {
10466 m_host.AddScriptLPS(1); 11137 m_host.AddScriptLPS(1);
@@ -10630,22 +11301,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10630 NotImplemented("llGetSPMaxMemory"); 11301 NotImplemented("llGetSPMaxMemory");
10631 } 11302 }
10632 11303
10633 public void llGetUsedMemory() 11304 public virtual LSL_Integer llGetUsedMemory()
10634 { 11305 {
10635 m_host.AddScriptLPS(1); 11306 m_host.AddScriptLPS(1);
10636 NotImplemented("llGetUsedMemory"); 11307 NotImplemented("llGetUsedMemory");
11308 return 0;
10637 } 11309 }
10638 11310
10639 public void llScriptProfiler(LSL_Integer flags) 11311 public void llScriptProfiler(LSL_Integer flags)
10640 { 11312 {
10641 m_host.AddScriptLPS(1); 11313 m_host.AddScriptLPS(1);
10642 NotImplemented("llScriptProfiler"); 11314 //NotImplemented("llScriptProfiler");
10643 } 11315 }
10644 11316
10645 public void llSetSoundQueueing(int queue) 11317 public void llSetSoundQueueing(int queue)
10646 { 11318 {
10647 m_host.AddScriptLPS(1); 11319 m_host.AddScriptLPS(1);
10648 NotImplemented("llSetSoundQueueing");
10649 } 11320 }
10650 11321
10651 public void llCollisionSprite(string impact_sprite) 11322 public void llCollisionSprite(string impact_sprite)
@@ -10657,7 +11328,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10657 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11328 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10658 { 11329 {
10659 m_host.AddScriptLPS(1); 11330 m_host.AddScriptLPS(1);
10660 NotImplemented("llGodLikeRezObject"); 11331
11332 if (!World.Permissions.IsGod(m_host.OwnerID))
11333 NotImplemented("llGodLikeRezObject");
11334
11335 AssetBase rezAsset = World.AssetService.Get(inventory);
11336 if (rezAsset == null)
11337 {
11338 llSay(0, "Asset not found");
11339 return;
11340 }
11341
11342 SceneObjectGroup group = null;
11343
11344 try
11345 {
11346 string xmlData = Utils.BytesToString(rezAsset.Data);
11347 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11348 }
11349 catch
11350 {
11351 llSay(0, "Asset not found");
11352 return;
11353 }
11354
11355 if (group == null)
11356 {
11357 llSay(0, "Asset not found");
11358 return;
11359 }
11360
11361 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11362 group.RootPart.AttachOffset = group.AbsolutePosition;
11363
11364 group.ResetIDs();
11365
11366 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11367 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11368 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11369 group.ScheduleGroupForFullUpdate();
11370
11371 // objects rezzed with this method are die_at_edge by default.
11372 group.RootPart.SetDieAtEdge(true);
11373
11374 group.ResumeScripts();
11375
11376 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11377 "object_rez", new Object[] {
11378 new LSL_String(
11379 group.RootPart.UUID.ToString()) },
11380 new DetectParams[0]));
10661 } 11381 }
10662 11382
10663 #endregion 11383 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index f3206ac..c0d2f38 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -203,7 +205,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
203 205
204 internal void OSSLError(string msg) 206 internal void OSSLError(string msg)
205 { 207 {
206 throw new Exception("OSSL Runtime Error: " + msg); 208 if (m_debuggerSafe)
209 {
210 OSSLShoutError(msg);
211 }
212 else
213 {
214 throw new Exception("OSSL Runtime Error: " + msg);
215 }
207 } 216 }
208 217
209 private void InitLSL() 218 private void InitLSL()
@@ -894,18 +903,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
894 if (target != null) 903 if (target != null)
895 { 904 {
896 UUID animID=UUID.Zero; 905 UUID animID=UUID.Zero;
897 lock (m_host.TaskInventory) 906 m_host.TaskInventory.LockItemsForRead(true);
907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
898 { 908 {
899 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 909 if (inv.Value.Name == animation)
900 { 910 {
901 if (inv.Value.Name == animation) 911 if (inv.Value.Type == (int)AssetType.Animation)
902 { 912 animID = inv.Value.AssetID;
903 if (inv.Value.Type == (int)AssetType.Animation) 913 continue;
904 animID = inv.Value.AssetID;
905 continue;
906 }
907 } 914 }
908 } 915 }
916 m_host.TaskInventory.LockItemsForRead(false);
909 if (animID == UUID.Zero) 917 if (animID == UUID.Zero)
910 target.Animator.AddAnimation(animation, m_host.UUID); 918 target.Animator.AddAnimation(animation, m_host.UUID);
911 else 919 else
@@ -927,18 +935,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
927 if (target != null) 935 if (target != null)
928 { 936 {
929 UUID animID = UUID.Zero; 937 UUID animID = UUID.Zero;
930 lock (m_host.TaskInventory) 938 m_host.TaskInventory.LockItemsForRead(true);
939 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
931 { 940 {
932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 941 if (inv.Value.Name == animation)
933 { 942 {
934 if (inv.Value.Name == animation) 943 if (inv.Value.Type == (int)AssetType.Animation)
935 { 944 animID = inv.Value.AssetID;
936 if (inv.Value.Type == (int)AssetType.Animation) 945 continue;
937 animID = inv.Value.AssetID;
938 continue;
939 }
940 } 946 }
941 } 947 }
948 m_host.TaskInventory.LockItemsForRead(false);
942 949
943 if (animID == UUID.Zero) 950 if (animID == UUID.Zero)
944 target.Animator.RemoveAnimation(animation); 951 target.Animator.RemoveAnimation(animation);
@@ -1895,6 +1902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1895 1902
1896 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1903 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1897 { 1904 {
1905 m_host.TaskInventory.LockItemsForRead(true);
1898 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1899 { 1907 {
1900 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1908 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1902,6 +1910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1902 assetID = item.AssetID; 1910 assetID = item.AssetID;
1903 } 1911 }
1904 } 1912 }
1913 m_host.TaskInventory.LockItemsForRead(false);
1905 } 1914 }
1906 1915
1907 if (assetID == UUID.Zero) 1916 if (assetID == UUID.Zero)
@@ -2225,8 +2234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2225 UUID x = module.CreateNPC(firstname, 2234 UUID x = module.CreateNPC(firstname,
2226 lastname, 2235 lastname,
2227 new Vector3((float) position.x, (float) position.y, (float) position.z), 2236 new Vector3((float) position.x, (float) position.y, (float) position.z),
2228 World, 2237 World,appearance);
2229 appearance);
2230 2238
2231 return new LSL_Key(x.ToString()); 2239 return new LSL_Key(x.ToString());
2232 } 2240 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5527d14..ed5a2fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -429,6 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 435 q = avatar.Rotation;
433 } 436 }
434 437
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..4ad4123 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -405,7 +406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 406 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 407 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 408 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 409 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 410
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 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 3221833..a61d553 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 ce4661c..a1cf3df 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;
@@ -376,6 +377,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
376 public const int PRIM_SCULPT_TYPE_TORUS = 2; 377 public const int PRIM_SCULPT_TYPE_TORUS = 2;
377 public const int PRIM_SCULPT_TYPE_PLANE = 3; 378 public const int PRIM_SCULPT_TYPE_PLANE = 3;
378 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 379 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
380 public const int PRIM_SCULPT_FLAG_INVERT = 64;
381 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
379 382
380 public const int MASK_BASE = 0; 383 public const int MASK_BASE = 0;
381 public const int MASK_OWNER = 1; 384 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..a88a1f4 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;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -464,6 +466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 466 return m_LSL_Functions.llGetFreeMemory();
465 } 467 }
466 468
469 public LSL_Integer llGetUsedMemory()
470 {
471 return m_LSL_Functions.llGetUsedMemory();
472 }
473
467 public LSL_Integer llGetFreeURLs() 474 public LSL_Integer llGetFreeURLs()
468 { 475 {
469 return m_LSL_Functions.llGetFreeURLs(); 476 return m_LSL_Functions.llGetFreeURLs();
@@ -1878,9 +1885,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1885 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1886 }
1880 1887
1881 public void print(string str) 1888 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1889 {
1883 m_LSL_Functions.print(str); 1890 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1891 }
1885 } 1892 }
1886} 1893}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f9af9c1..9ff2e4d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -263,13 +264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
263 264
264 if (part != null) 265 if (part != null)
265 { 266 {
266 lock (part.TaskInventory) 267 part.TaskInventory.LockItemsForRead(true);
268 if (part.TaskInventory.ContainsKey(m_ItemID))
267 { 269 {
268 if (part.TaskInventory.ContainsKey(m_ItemID)) 270 m_thisScriptTask = part.TaskInventory[m_ItemID];
269 {
270 m_thisScriptTask = part.TaskInventory[m_ItemID];
271 }
272 } 271 }
272 part.TaskInventory.LockItemsForRead(false);
273 } 273 }
274 274
275 ApiManager am = new ApiManager(); 275 ApiManager am = new ApiManager();
@@ -296,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 297// lease.Register(this);
298 } 298 }
299 catch (Exception) 299 catch (Exception e)
300 { 300 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
302 } 303 }
303 304
304 try 305 try
@@ -459,14 +460,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
459 { 460 {
460 int permsMask; 461 int permsMask;
461 UUID permsGranter; 462 UUID permsGranter;
462 lock (part.TaskInventory) 463 part.TaskInventory.LockItemsForRead(true);
464 if (!part.TaskInventory.ContainsKey(m_ItemID))
463 { 465 {
464 if (!part.TaskInventory.ContainsKey(m_ItemID)) 466 part.TaskInventory.LockItemsForRead(false);
465 return; 467 return;
466
467 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
468 permsMask = part.TaskInventory[m_ItemID].PermsMask;
469 } 468 }
469 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
470 permsMask = part.TaskInventory[m_ItemID].PermsMask;
471 part.TaskInventory.LockItemsForRead(false);
470 472
471 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 473 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 { 474 {
@@ -575,6 +577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 return true; 577 return true;
576 } 578 }
577 579
580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
578 public void SetState(string state) 581 public void SetState(string state)
579 { 582 {
580 if (state == State) 583 if (state == State)
@@ -586,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
586 new DetectParams[0])); 589 new DetectParams[0]));
587 PostEvent(new EventParams("state_entry", new Object[0], 590 PostEvent(new EventParams("state_entry", new Object[0],
588 new DetectParams[0])); 591 new DetectParams[0]));
589 592
590 throw new EventAbortException(); 593 throw new EventAbortException();
591 } 594 }
592 595
@@ -669,41 +672,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
669 /// <returns></returns> 672 /// <returns></returns>
670 public object EventProcessor() 673 public object EventProcessor()
671 { 674 {
672 lock (m_Script) 675 EventParams data = null;
673 {
674// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
675 676
676 if (Suspended) 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
677 return 0;
678 678
679 EventParams data = null; 679 if (Suspended)
680 return 0;
680 681
681 lock (m_EventQueue) 682 lock (m_EventQueue)
683 {
684 data = (EventParams) m_EventQueue.Dequeue();
685 if (data == null) // Shouldn't happen
682 { 686 {
683 data = (EventParams) m_EventQueue.Dequeue(); 687 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
684 if (data == null) // Shouldn't happen
685 { 688 {
686 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 689 m_CurrentResult = m_Engine.QueueEventHandler(this);
687 {
688 m_CurrentResult = m_Engine.QueueEventHandler(this);
689 }
690 else
691 {
692 m_CurrentResult = null;
693 }
694 return 0;
695 } 690 }
696 691 else
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 { 692 {
701 if (m_ControlEventsInQueue > 0) 693 m_CurrentResult = null;
702 m_ControlEventsInQueue--;
703 } 694 }
704 if (data.EventName == "collision") 695 return 0;
705 m_CollisionInQueue = false; 696 }
697
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 {
702 if (m_ControlEventsInQueue > 0)
703 m_ControlEventsInQueue--;
706 } 704 }
705 if (data.EventName == "collision")
706 m_CollisionInQueue = false;
707 }
708
709 lock(m_Script)
710 {
707 711
708// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 713
@@ -860,6 +864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 864 new Object[0], new DetectParams[0]));
861 } 865 }
862 866
867 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 868 public void ApiResetScript()
864 { 869 {
865 // bool running = Running; 870 // bool running = Running;
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 1c16c87..402377d 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;
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
103 private Dictionary<UUID, IScriptInstance> m_Scripts = 104 private Dictionary<UUID, IScriptInstance> m_Scripts =
104 new Dictionary<UUID, IScriptInstance>(); 105 new Dictionary<UUID, IScriptInstance>();
105 106
107 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
108
106 // Maps the asset ID to the assembly 109 // Maps the asset ID to the assembly
107 110
108 private Dictionary<UUID, string> m_Assemblies = 111 private Dictionary<UUID, string> m_Assemblies =
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
125 IWorkItemResult m_CurrentCompile = null; 128 IWorkItemResult m_CurrentCompile = null;
126 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 129 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
127 130
131 private void lockScriptsForRead(bool locked)
132 {
133 if (locked)
134 {
135 if (m_scriptsLock.RecursiveReadCount > 0)
136 {
137 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.");
138 m_scriptsLock.ExitReadLock();
139 }
140 if (m_scriptsLock.RecursiveWriteCount > 0)
141 {
142 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
143 m_scriptsLock.ExitWriteLock();
144 }
145
146 while (!m_scriptsLock.TryEnterReadLock(60000))
147 {
148 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.");
149 if (m_scriptsLock.IsWriteLockHeld)
150 {
151 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152 }
153 }
154 }
155 else
156 {
157 if (m_scriptsLock.RecursiveReadCount > 0)
158 {
159 m_scriptsLock.ExitReadLock();
160 }
161 }
162 }
163 private void lockScriptsForWrite(bool locked)
164 {
165 if (locked)
166 {
167 if (m_scriptsLock.RecursiveReadCount > 0)
168 {
169 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.");
170 m_scriptsLock.ExitReadLock();
171 }
172 if (m_scriptsLock.RecursiveWriteCount > 0)
173 {
174 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
175 m_scriptsLock.ExitWriteLock();
176 }
177
178 while (!m_scriptsLock.TryEnterWriteLock(60000))
179 {
180 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.");
181 if (m_scriptsLock.IsWriteLockHeld)
182 {
183 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
184 }
185 }
186 }
187 else
188 {
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_scriptsLock.ExitWriteLock();
192 }
193 }
194 }
195
128 public string ScriptEngineName 196 public string ScriptEngineName
129 { 197 {
130 get { return "XEngine"; } 198 get { return "XEngine"; }
@@ -445,47 +513,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
445 { 513 {
446 if (!m_Enabled) 514 if (!m_Enabled)
447 return; 515 return;
448 516 lockScriptsForRead(true);
449 lock (m_Scripts) 517 foreach (IScriptInstance instance in m_Scripts.Values)
450 { 518 {
451 m_log.InfoFormat( 519 // Force a final state save
452 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 520 //
453 521 if (m_Assemblies.ContainsKey(instance.AssetID))
454 foreach (IScriptInstance instance in m_Scripts.Values)
455 { 522 {
456 // Force a final state save 523 string assembly = m_Assemblies[instance.AssetID];
457 // 524 instance.SaveState(assembly);
458 if (m_Assemblies.ContainsKey(instance.AssetID)) 525 }
459 {
460 string assembly = m_Assemblies[instance.AssetID];
461 instance.SaveState(assembly);
462 }
463 526
464 // Clear the event queue and abort the instance thread 527 // Clear the event queue and abort the instance thread
465 // 528 //
466 instance.ClearQueue(); 529 instance.ClearQueue();
467 instance.Stop(0); 530 instance.Stop(0);
468 531
469 // Release events, timer, etc 532 // Release events, timer, etc
470 // 533 //
471 instance.DestroyScriptInstance(); 534 instance.DestroyScriptInstance();
472 535
473 // Unload scripts and app domains 536 // Unload scripts and app domains
474 // Must be done explicitly because they have infinite 537 // Must be done explicitly because they have infinite
475 // lifetime 538 // lifetime
476 // 539 //
477 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 540 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
478 if (m_DomainScripts[instance.AppDomain].Count == 0) 541 if (m_DomainScripts[instance.AppDomain].Count == 0)
479 { 542 {
480 m_DomainScripts.Remove(instance.AppDomain); 543 m_DomainScripts.Remove(instance.AppDomain);
481 UnloadAppDomain(instance.AppDomain); 544 UnloadAppDomain(instance.AppDomain);
482 }
483 } 545 }
484 m_Scripts.Clear();
485 m_PrimObjects.Clear();
486 m_Assemblies.Clear();
487 m_DomainScripts.Clear();
488 } 546 }
547 lockScriptsForRead(false);
548 lockScriptsForWrite(true);
549 m_Scripts.Clear();
550 lockScriptsForWrite(false);
551 m_PrimObjects.Clear();
552 m_Assemblies.Clear();
553 m_DomainScripts.Clear();
554
489 lock (m_ScriptEngines) 555 lock (m_ScriptEngines)
490 { 556 {
491 m_ScriptEngines.Remove(this); 557 m_ScriptEngines.Remove(this);
@@ -550,22 +616,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
550 616
551 List<IScriptInstance> instances = new List<IScriptInstance>(); 617 List<IScriptInstance> instances = new List<IScriptInstance>();
552 618
553 lock (m_Scripts) 619 lockScriptsForRead(true);
554 { 620 foreach (IScriptInstance instance in m_Scripts.Values)
555 foreach (IScriptInstance instance in m_Scripts.Values)
556 instances.Add(instance); 621 instances.Add(instance);
557 } 622 lockScriptsForRead(false);
558 623
559 foreach (IScriptInstance i in instances) 624 foreach (IScriptInstance i in instances)
560 { 625 {
561 string assembly = String.Empty; 626 string assembly = String.Empty;
562 627
563 lock (m_Scripts) 628
564 {
565 if (!m_Assemblies.ContainsKey(i.AssetID)) 629 if (!m_Assemblies.ContainsKey(i.AssetID))
566 continue; 630 continue;
567 assembly = m_Assemblies[i.AssetID]; 631 assembly = m_Assemblies[i.AssetID];
568 } 632
569 633
570 i.SaveState(assembly); 634 i.SaveState(assembly);
571 } 635 }
@@ -899,92 +963,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
899 } 963 }
900 964
901 ScriptInstance instance = null; 965 ScriptInstance instance = null;
902 lock (m_Scripts) 966 // Create the object record
967 lockScriptsForRead(true);
968 if ((!m_Scripts.ContainsKey(itemID)) ||
969 (m_Scripts[itemID].AssetID != assetID))
903 { 970 {
904 // Create the object record 971 lockScriptsForRead(false);
905 972
906 if ((!m_Scripts.ContainsKey(itemID)) || 973 UUID appDomain = assetID;
907 (m_Scripts[itemID].AssetID != assetID))
908 {
909 UUID appDomain = assetID;
910 974
911 if (part.ParentGroup.IsAttachment) 975 if (part.ParentGroup.IsAttachment)
912 appDomain = part.ParentGroup.RootPart.UUID; 976 appDomain = part.ParentGroup.RootPart.UUID;
913 977
914 if (!m_AppDomains.ContainsKey(appDomain)) 978 if (!m_AppDomains.ContainsKey(appDomain))
979 {
980 try
915 { 981 {
916 try 982 AppDomainSetup appSetup = new AppDomainSetup();
917 { 983 appSetup.PrivateBinPath = Path.Combine(
918 AppDomainSetup appSetup = new AppDomainSetup(); 984 m_ScriptEnginesPath,
919 appSetup.PrivateBinPath = Path.Combine( 985 m_Scene.RegionInfo.RegionID.ToString());
920 m_ScriptEnginesPath, 986
921 m_Scene.RegionInfo.RegionID.ToString()); 987 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
922 988 Evidence evidence = new Evidence(baseEvidence);
923 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 989
924 Evidence evidence = new Evidence(baseEvidence); 990 AppDomain sandbox;
925 991 if (m_AppDomainLoading)
926 AppDomain sandbox; 992 sandbox = AppDomain.CreateDomain(
927 if (m_AppDomainLoading) 993 m_Scene.RegionInfo.RegionID.ToString(),
928 sandbox = AppDomain.CreateDomain( 994 evidence, appSetup);
929 m_Scene.RegionInfo.RegionID.ToString(), 995 else
930 evidence, appSetup); 996 sandbox = AppDomain.CurrentDomain;
931 else 997
932 sandbox = AppDomain.CurrentDomain; 998 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
933 999 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
934 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1000 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
935 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1001 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
936 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 1002 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
937 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 1003 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
938 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 1004 //sandbox.SetAppDomainPolicy(sandboxPolicy);
939 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 1005
940 //sandbox.SetAppDomainPolicy(sandboxPolicy); 1006 m_AppDomains[appDomain] = sandbox;
941 1007
942 m_AppDomains[appDomain] = sandbox; 1008 m_AppDomains[appDomain].AssemblyResolve +=
943 1009 new ResolveEventHandler(
944 m_AppDomains[appDomain].AssemblyResolve += 1010 AssemblyResolver.OnAssemblyResolve);
945 new ResolveEventHandler( 1011 m_DomainScripts[appDomain] = new List<UUID>();
946 AssemblyResolver.OnAssemblyResolve); 1012 }
947 m_DomainScripts[appDomain] = new List<UUID>(); 1013 catch (Exception e)
948 } 1014 {
949 catch (Exception e) 1015 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1016 m_ScriptErrorMessage += "Exception creating app domain:\n";
1017 m_ScriptFailCount++;
1018 lock (m_AddingAssemblies)
950 { 1019 {
951 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1020 m_AddingAssemblies[assembly]--;
952 m_ScriptErrorMessage += "Exception creating app domain:\n";
953 m_ScriptFailCount++;
954 lock (m_AddingAssemblies)
955 {
956 m_AddingAssemblies[assembly]--;
957 }
958 return false;
959 } 1021 }
1022 return false;
960 } 1023 }
961 m_DomainScripts[appDomain].Add(itemID); 1024 }
962 1025 m_DomainScripts[appDomain].Add(itemID);
963 instance = new ScriptInstance(this, part, 1026
964 itemID, assetID, assembly, 1027 instance = new ScriptInstance(this, part,
965 m_AppDomains[appDomain], 1028 itemID, assetID, assembly,
966 part.ParentGroup.RootPart.Name, 1029 m_AppDomains[appDomain],
967 item.Name, startParam, postOnRez, 1030 part.ParentGroup.RootPart.Name,
968 stateSource, m_MaxScriptQueue); 1031 item.Name, startParam, postOnRez,
969 1032 stateSource, m_MaxScriptQueue);
970 m_log.DebugFormat( 1033
971 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1034 m_log.DebugFormat(
972 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1035 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1036 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
973 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1037 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
974 1038
975 if (presence != null) 1039 if (presence != null)
976 { 1040 {
977 ShowScriptSaveResponse(item.OwnerID, 1041 ShowScriptSaveResponse(item.OwnerID,
978 assetID, "Compile successful", true); 1042 assetID, "Compile successful", true);
979 }
980
981 instance.AppDomain = appDomain;
982 instance.LineMap = linemap;
983
984 m_Scripts[itemID] = instance;
985 } 1043 }
986 }
987 1044
1045 instance.AppDomain = appDomain;
1046 instance.LineMap = linemap;
1047 lockScriptsForWrite(true);
1048 m_Scripts[itemID] = instance;
1049 lockScriptsForWrite(false);
1050 }
1051 else
1052 {
1053 lockScriptsForRead(false);
1054 }
988 lock (m_PrimObjects) 1055 lock (m_PrimObjects)
989 { 1056 {
990 if (!m_PrimObjects.ContainsKey(localID)) 1057 if (!m_PrimObjects.ContainsKey(localID))
@@ -1003,9 +1070,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1003 m_AddingAssemblies[assembly]--; 1070 m_AddingAssemblies[assembly]--;
1004 } 1071 }
1005 1072
1006 if (instance != null) 1073 if (instance!=null)
1007 instance.Init(); 1074 instance.Init();
1008 1075
1009 return true; 1076 return true;
1010 } 1077 }
1011 1078
@@ -1018,20 +1085,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1018 m_CompileDict.Remove(itemID); 1085 m_CompileDict.Remove(itemID);
1019 } 1086 }
1020 1087
1021 IScriptInstance instance = null; 1088 lockScriptsForRead(true);
1022 1089 // Do we even have it?
1023 lock (m_Scripts) 1090 if (!m_Scripts.ContainsKey(itemID))
1024 { 1091 {
1025 // Do we even have it? 1092 // Do we even have it?
1026 if (!m_Scripts.ContainsKey(itemID)) 1093 if (!m_Scripts.ContainsKey(itemID))
1027 return; 1094 return;
1028 1095
1029 instance = m_Scripts[itemID]; 1096 lockScriptsForRead(false);
1097 lockScriptsForWrite(true);
1030 m_Scripts.Remove(itemID); 1098 m_Scripts.Remove(itemID);
1099 lockScriptsForWrite(false);
1100
1101 return;
1031 } 1102 }
1103
1032 1104
1105 IScriptInstance instance=m_Scripts[itemID];
1106 lockScriptsForRead(false);
1107 lockScriptsForWrite(true);
1108 m_Scripts.Remove(itemID);
1109 lockScriptsForWrite(false);
1033 instance.ClearQueue(); 1110 instance.ClearQueue();
1034 instance.Stop(0); 1111 instance.Stop(0);
1112
1035// bool objectRemoved = false; 1113// bool objectRemoved = false;
1036 1114
1037 lock (m_PrimObjects) 1115 lock (m_PrimObjects)
@@ -1067,11 +1145,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1067 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1145 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1068 if (handlerObjectRemoved != null) 1146 if (handlerObjectRemoved != null)
1069 { 1147 {
1070 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1148 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1071 handlerObjectRemoved(part.UUID); 1149 handlerObjectRemoved(part.UUID);
1072 } 1150 }
1073 1151
1074 1152 CleanAssemblies();
1153
1075 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1154 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1076 if (handlerScriptRemoved != null) 1155 if (handlerScriptRemoved != null)
1077 handlerScriptRemoved(itemID); 1156 handlerScriptRemoved(itemID);
@@ -1213,7 +1292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return false; 1292 return false;
1214 1293
1215 uuids = m_PrimObjects[localID]; 1294 uuids = m_PrimObjects[localID];
1216 } 1295
1217 1296
1218 foreach (UUID itemID in uuids) 1297 foreach (UUID itemID in uuids)
1219 { 1298 {
@@ -1231,6 +1310,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1231 result = true; 1310 result = true;
1232 } 1311 }
1233 } 1312 }
1313 }
1234 1314
1235 return result; 1315 return result;
1236 } 1316 }
@@ -1330,12 +1410,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1330 private IScriptInstance GetInstance(UUID itemID) 1410 private IScriptInstance GetInstance(UUID itemID)
1331 { 1411 {
1332 IScriptInstance instance; 1412 IScriptInstance instance;
1333 lock (m_Scripts) 1413 lockScriptsForRead(true);
1414 if (!m_Scripts.ContainsKey(itemID))
1334 { 1415 {
1335 if (!m_Scripts.ContainsKey(itemID)) 1416 lockScriptsForRead(false);
1336 return null; 1417 return null;
1337 instance = m_Scripts[itemID];
1338 } 1418 }
1419 instance = m_Scripts[itemID];
1420 lockScriptsForRead(false);
1339 return instance; 1421 return instance;
1340 } 1422 }
1341 1423
@@ -1359,6 +1441,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1359 return false; 1441 return false;
1360 } 1442 }
1361 1443
1444 [DebuggerNonUserCode]
1362 public void ApiResetScript(UUID itemID) 1445 public void ApiResetScript(UUID itemID)
1363 { 1446 {
1364 IScriptInstance instance = GetInstance(itemID); 1447 IScriptInstance instance = GetInstance(itemID);
@@ -1410,6 +1493,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1410 return UUID.Zero; 1493 return UUID.Zero;
1411 } 1494 }
1412 1495
1496 [DebuggerNonUserCode]
1413 public void SetState(UUID itemID, string newState) 1497 public void SetState(UUID itemID, string newState)
1414 { 1498 {
1415 IScriptInstance instance = GetInstance(itemID); 1499 IScriptInstance instance = GetInstance(itemID);
@@ -1430,11 +1514,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1430 { 1514 {
1431 List<IScriptInstance> instances = new List<IScriptInstance>(); 1515 List<IScriptInstance> instances = new List<IScriptInstance>();
1432 1516
1433 lock (m_Scripts) 1517 lockScriptsForRead(true);
1434 { 1518 foreach (IScriptInstance instance in m_Scripts.Values)
1435 foreach (IScriptInstance instance in m_Scripts.Values)
1436 instances.Add(instance); 1519 instances.Add(instance);
1437 } 1520 lockScriptsForRead(false);
1438 1521
1439 foreach (IScriptInstance i in instances) 1522 foreach (IScriptInstance i in instances)
1440 { 1523 {
@@ -1811,5 +1894,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1811 if (instance != null) 1894 if (instance != null)
1812 instance.Resume(); 1895 instance.Resume();
1813 } 1896 }
1897
1898 public bool HasScript(UUID itemID, out bool running)
1899 {
1900 running = true;
1901
1902 IScriptInstance instance = GetInstance(itemID);
1903 if (instance == null)
1904 return false;
1905
1906 running = instance.Running;
1907 return true;
1908 }
1814 } 1909 }
1815} \ No newline at end of file 1910} \ No newline at end of file