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 0750579..45a5f9a 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)
@@ -1673,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1673 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1674 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1675 { 1858 {
1676 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return; 1860 return;
1678 1861
1679 if (light) 1862 if (light)
@@ -1750,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1751 1934
1752 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1753 1936 if (parts.Count > 0)
1754 foreach (SceneObjectPart part in parts) 1937 {
1755 SetTexture(part, texture, face); 1938 try
1756 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1757 ScriptSleep(200); 1949 ScriptSleep(200);
1758 } 1950 }
1759 1951
1760 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1761 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1762 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1763 1958
1764 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1803,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1998
1804 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1805 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1806 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1807 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1808 { 2006 {
@@ -1839,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1839 2037
1840 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1841 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1842 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1843 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1844 { 2045 {
@@ -1875,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 2076
1876 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1877 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1878 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1879 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1880 { 2084 {
@@ -1981,24 +2185,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1981 2185
1982 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2186 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1983 { 2187 {
1984 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2188 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1985 LSL_Vector currentPos = GetPartLocalPos(part); 2189 return;
1986 2190
1987 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2191 LSL_Vector currentPos = GetPartLocalPos(part);
1988 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2192 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1989 2193
1990 if (part.ParentGroup.RootPart == part) 2194 if (part.ParentGroup.RootPart == part)
1991 { 2195 {
1992 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1993 targetPos.z = ground;
1994 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
1995 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2197 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1996 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1997 } 2198 }
1998 else 2199 else
1999 { 2200 {
2000 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2201 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2001 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2002 SceneObjectGroup parent = part.ParentGroup; 2202 SceneObjectGroup parent = part.ParentGroup;
2003 parent.HasGroupChanged = true; 2203 parent.HasGroupChanged = true;
2004 parent.ScheduleGroupForTerseUpdate(); 2204 parent.ScheduleGroupForTerseUpdate();
@@ -2049,9 +2249,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2049 m_host.AddScriptLPS(1); 2249 m_host.AddScriptLPS(1);
2050 2250
2051 // try to let this work as in SL... 2251 // try to let this work as in SL...
2052 if (m_host.ParentID == 0) 2252 if (m_host.LinkNum < 2)
2053 { 2253 {
2054 // special case: If we are root, rotate complete SOG to new rotation 2254 // Special case: If we are root, rotate complete SOG to new
2255 // rotation.
2256 // We are root if the link number is 0 (single prim) or 1
2257 // (root prim). ParentID may be nonzero in attachments and
2258 // using it would cause attachments and HUDs to rotate
2259 // to the wrong positions.
2055 SetRot(m_host, Rot2Quaternion(rot)); 2260 SetRot(m_host, Rot2Quaternion(rot));
2056 } 2261 }
2057 else 2262 else
@@ -2076,6 +2281,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2076 2281
2077 protected void SetRot(SceneObjectPart part, Quaternion rot) 2282 protected void SetRot(SceneObjectPart part, Quaternion rot)
2078 { 2283 {
2284 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2285 return;
2286
2079 part.UpdateRotation(rot); 2287 part.UpdateRotation(rot);
2080 // Update rotation does not move the object in the physics scene if it's a linkset. 2288 // Update rotation does not move the object in the physics scene if it's a linkset.
2081 2289
@@ -2699,12 +2907,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2699 2907
2700 m_host.AddScriptLPS(1); 2908 m_host.AddScriptLPS(1);
2701 2909
2910 m_host.TaskInventory.LockItemsForRead(true);
2702 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2911 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2703 2912 m_host.TaskInventory.LockItemsForRead(false);
2704 lock (m_host.TaskInventory)
2705 {
2706 item = m_host.TaskInventory[invItemID];
2707 }
2708 2913
2709 if (item.PermsGranter == UUID.Zero) 2914 if (item.PermsGranter == UUID.Zero)
2710 return 0; 2915 return 0;
@@ -2779,6 +2984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2779 if (dist > m_ScriptDistanceFactor * 10.0f) 2984 if (dist > m_ScriptDistanceFactor * 10.0f)
2780 return; 2985 return;
2781 2986
2987 //Clone is thread-safe
2782 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2988 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2783 2989
2784 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2990 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2839,6 +3045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 3045
2840 public void llLookAt(LSL_Vector target, double strength, double damping) 3046 public void llLookAt(LSL_Vector target, double strength, double damping)
2841 { 3047 {
3048 /*
2842 m_host.AddScriptLPS(1); 3049 m_host.AddScriptLPS(1);
2843 // Determine where we are looking from 3050 // Determine where we are looking from
2844 LSL_Vector from = llGetPos(); 3051 LSL_Vector from = llGetPos();
@@ -2858,10 +3065,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 // the angles of rotation in radians into rotation value 3065 // the angles of rotation in radians into rotation value
2859 3066
2860 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3067 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2861 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3068
2862 m_host.startLookAt(rotation, (float)damping, (float)strength); 3069 // This would only work if your physics system contains an APID controller:
3070 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3071 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3072
2863 // Orient the object to the angle calculated 3073 // Orient the object to the angle calculated
2864 //llSetRot(rot); 3074 llSetRot(rot);
3075 */
3076
3077 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3078 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3079 // http://bugs.meta7.com/view.php?id=28
3080 // - Tom
3081
3082 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3083 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3084 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3085 */
3086 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3087 {
3088 // Part is non-phys, convert this to a llSetRot()
3089 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3090 Vector3 dir = tgt - m_host.GroupPosition;
3091 dir.Normalize();
3092 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3093 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3094 float terot = (float)Math.Atan2(-dir.Z, txy);
3095 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3096 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3097 LSL_Types.Quaternion spin = llEuler2Rot(az);
3098 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3099 llSetRot(rot);
3100 }
3101 else
3102 {
3103 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3104 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3105 m_host.RotLookAt(q, (float)strength, (float)damping);
3106 }
3107
3108 }
3109
3110 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3111 {
3112 m_host.AddScriptLPS(1);
3113// NotImplemented("llRotLookAt");
3114 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3115
2865 } 3116 }
2866 3117
2867 public void llStopLookAt() 3118 public void llStopLookAt()
@@ -2910,13 +3161,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2910 { 3161 {
2911 TaskInventoryItem item; 3162 TaskInventoryItem item;
2912 3163
2913 lock (m_host.TaskInventory) 3164 m_host.TaskInventory.LockItemsForRead(true);
3165 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2914 { 3166 {
2915 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3167 m_host.TaskInventory.LockItemsForRead(false);
2916 return; 3168 return;
2917 else
2918 item = m_host.TaskInventory[InventorySelf()];
2919 } 3169 }
3170 else
3171 {
3172 item = m_host.TaskInventory[InventorySelf()];
3173 }
3174 m_host.TaskInventory.LockItemsForRead(false);
2920 3175
2921 if (item.PermsGranter != UUID.Zero) 3176 if (item.PermsGranter != UUID.Zero)
2922 { 3177 {
@@ -2938,13 +3193,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 { 3193 {
2939 TaskInventoryItem item; 3194 TaskInventoryItem item;
2940 3195
3196 m_host.TaskInventory.LockItemsForRead(true);
2941 lock (m_host.TaskInventory) 3197 lock (m_host.TaskInventory)
2942 { 3198 {
3199
2943 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3200 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3201 {
3202 m_host.TaskInventory.LockItemsForRead(false);
2944 return; 3203 return;
3204 }
2945 else 3205 else
3206 {
2946 item = m_host.TaskInventory[InventorySelf()]; 3207 item = m_host.TaskInventory[InventorySelf()];
3208 }
2947 } 3209 }
3210 m_host.TaskInventory.LockItemsForRead(false);
2948 3211
2949 m_host.AddScriptLPS(1); 3212 m_host.AddScriptLPS(1);
2950 3213
@@ -2976,18 +3239,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 { 3239 {
2977 m_host.AddScriptLPS(1); 3240 m_host.AddScriptLPS(1);
2978 3241
2979// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2980// return;
2981
2982 TaskInventoryItem item; 3242 TaskInventoryItem item;
2983 3243
2984 lock (m_host.TaskInventory) 3244 m_host.TaskInventory.LockItemsForRead(true);
3245
3246 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2985 { 3247 {
2986 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3248 m_host.TaskInventory.LockItemsForRead(false);
2987 return; 3249 return;
2988 else
2989 item = m_host.TaskInventory[InventorySelf()];
2990 } 3250 }
3251 else
3252 {
3253 item = m_host.TaskInventory[InventorySelf()];
3254 }
3255
3256 m_host.TaskInventory.LockItemsForRead(false);
2991 3257
2992 if (item.PermsGranter != m_host.OwnerID) 3258 if (item.PermsGranter != m_host.OwnerID)
2993 return; 3259 return;
@@ -3013,13 +3279,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 3279
3014 TaskInventoryItem item; 3280 TaskInventoryItem item;
3015 3281
3016 lock (m_host.TaskInventory) 3282 m_host.TaskInventory.LockItemsForRead(true);
3283
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3017 { 3285 {
3018 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3286 m_host.TaskInventory.LockItemsForRead(false);
3019 return; 3287 return;
3020 else
3021 item = m_host.TaskInventory[InventorySelf()];
3022 } 3288 }
3289 else
3290 {
3291 item = m_host.TaskInventory[InventorySelf()];
3292 }
3293 m_host.TaskInventory.LockItemsForRead(false);
3294
3023 3295
3024 if (item.PermsGranter != m_host.OwnerID) 3296 if (item.PermsGranter != m_host.OwnerID)
3025 return; 3297 return;
@@ -3066,6 +3338,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3066 3338
3067 public void llInstantMessage(string user, string message) 3339 public void llInstantMessage(string user, string message)
3068 { 3340 {
3341 UUID result;
3342 if (!UUID.TryParse(user, out result))
3343 {
3344 ShoutError("An invalid key was passed to llInstantMessage");
3345 ScriptSleep(2000);
3346 return;
3347 }
3348
3349
3069 m_host.AddScriptLPS(1); 3350 m_host.AddScriptLPS(1);
3070 3351
3071 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3352 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3080,14 +3361,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3080 UUID friendTransactionID = UUID.Random(); 3361 UUID friendTransactionID = UUID.Random();
3081 3362
3082 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3363 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3083 3364
3084 GridInstantMessage msg = new GridInstantMessage(); 3365 GridInstantMessage msg = new GridInstantMessage();
3085 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3366 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3086 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3367 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3087 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3368 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3088// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3369// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3089// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3370// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3090 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3371// DateTime dt = DateTime.UtcNow;
3372//
3373// // Ticks from UtcNow, but make it look like local. Evil, huh?
3374// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3375//
3376// try
3377// {
3378// // Convert that to the PST timezone
3379// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3380// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3381// }
3382// catch
3383// {
3384// // No logging here, as it could be VERY spammy
3385// }
3386//
3387// // And make it look local again to fool the unix time util
3388// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3389
3390 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3391
3091 //if (client != null) 3392 //if (client != null)
3092 //{ 3393 //{
3093 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3394 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3101,12 +3402,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 msg.message = message.Substring(0, 1024); 3402 msg.message = message.Substring(0, 1024);
3102 else 3403 else
3103 msg.message = message; 3404 msg.message = message;
3104 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3405 msg.dialog = (byte)19; // MessageFromObject
3105 msg.fromGroup = false;// fromGroup; 3406 msg.fromGroup = false;// fromGroup;
3106 msg.offline = (byte)0; //offline; 3407 msg.offline = (byte)0; //offline;
3107 msg.ParentEstateID = 0; //ParentEstateID; 3408 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3108 msg.Position = new Vector3(m_host.AbsolutePosition); 3409 msg.Position = new Vector3(m_host.AbsolutePosition);
3109 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3410 msg.RegionID = World.RegionInfo.RegionID.Guid;
3110 msg.binaryBucket 3411 msg.binaryBucket
3111 = Util.StringToBytes256( 3412 = Util.StringToBytes256(
3112 "{0}/{1}/{2}/{3}", 3413 "{0}/{1}/{2}/{3}",
@@ -3134,7 +3435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 } 3435 }
3135 3436
3136 emailModule.SendEmail(m_host.UUID, address, subject, message); 3437 emailModule.SendEmail(m_host.UUID, address, subject, message);
3137 ScriptSleep(20000); 3438 ScriptSleep(15000);
3138 } 3439 }
3139 3440
3140 public void llGetNextEmail(string address, string subject) 3441 public void llGetNextEmail(string address, string subject)
@@ -3234,13 +3535,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3234 m_host.AddScriptLPS(1); 3535 m_host.AddScriptLPS(1);
3235 } 3536 }
3236 3537
3237 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3238 {
3239 m_host.AddScriptLPS(1);
3240 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3241 m_host.RotLookAt(rot, (float)strength, (float)damping);
3242 }
3243
3244 public LSL_Integer llStringLength(string str) 3538 public LSL_Integer llStringLength(string str)
3245 { 3539 {
3246 m_host.AddScriptLPS(1); 3540 m_host.AddScriptLPS(1);
@@ -3264,14 +3558,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3264 3558
3265 TaskInventoryItem item; 3559 TaskInventoryItem item;
3266 3560
3267 lock (m_host.TaskInventory) 3561 m_host.TaskInventory.LockItemsForRead(true);
3562 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3268 { 3563 {
3269 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3564 m_host.TaskInventory.LockItemsForRead(false);
3270 return; 3565 return;
3271 else
3272 item = m_host.TaskInventory[InventorySelf()];
3273 } 3566 }
3274 3567 else
3568 {
3569 item = m_host.TaskInventory[InventorySelf()];
3570 }
3571 m_host.TaskInventory.LockItemsForRead(false);
3275 if (item.PermsGranter == UUID.Zero) 3572 if (item.PermsGranter == UUID.Zero)
3276 return; 3573 return;
3277 3574
@@ -3301,13 +3598,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3301 3598
3302 TaskInventoryItem item; 3599 TaskInventoryItem item;
3303 3600
3304 lock (m_host.TaskInventory) 3601 m_host.TaskInventory.LockItemsForRead(true);
3602 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3305 { 3603 {
3306 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3604 m_host.TaskInventory.LockItemsForRead(false);
3307 return; 3605 return;
3308 else
3309 item = m_host.TaskInventory[InventorySelf()];
3310 } 3606 }
3607 else
3608 {
3609 item = m_host.TaskInventory[InventorySelf()];
3610 }
3611 m_host.TaskInventory.LockItemsForRead(false);
3612
3311 3613
3312 if (item.PermsGranter == UUID.Zero) 3614 if (item.PermsGranter == UUID.Zero)
3313 return; 3615 return;
@@ -3374,10 +3676,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3374 3676
3375 TaskInventoryItem item; 3677 TaskInventoryItem item;
3376 3678
3377 lock (m_host.TaskInventory) 3679
3680 m_host.TaskInventory.LockItemsForRead(true);
3681 if (!m_host.TaskInventory.ContainsKey(invItemID))
3682 {
3683 m_host.TaskInventory.LockItemsForRead(false);
3684 return;
3685 }
3686 else
3378 { 3687 {
3379 item = m_host.TaskInventory[invItemID]; 3688 item = m_host.TaskInventory[invItemID];
3380 } 3689 }
3690 m_host.TaskInventory.LockItemsForRead(false);
3381 3691
3382 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3692 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3383 { 3693 {
@@ -3405,15 +3715,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3405 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3715 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3406 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3716 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3407 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3717 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3718 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3408 ScriptBaseClass.PERMISSION_ATTACH; 3719 ScriptBaseClass.PERMISSION_ATTACH;
3409 3720
3410 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3721 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3411 { 3722 {
3412 lock (m_host.TaskInventory) 3723 m_host.TaskInventory.LockItemsForWrite(true);
3413 { 3724 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3414 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3725 m_host.TaskInventory[invItemID].PermsMask = perm;
3415 m_host.TaskInventory[invItemID].PermsMask = perm; 3726 m_host.TaskInventory.LockItemsForWrite(false);
3416 }
3417 3727
3418 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3728 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3419 "run_time_permissions", new Object[] { 3729 "run_time_permissions", new Object[] {
@@ -3423,28 +3733,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3423 return; 3733 return;
3424 } 3734 }
3425 } 3735 }
3426 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3736 else
3427 { 3737 {
3428 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3738 bool sitting = false;
3429 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3739 if (m_host.SitTargetAvatar == agentID)
3430 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3740 {
3431 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3741 sitting = true;
3432 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3742 }
3743 else
3744 {
3745 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3746 {
3747 if (p.SitTargetAvatar == agentID)
3748 sitting = true;
3749 }
3750 }
3433 3751
3434 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3752 if (sitting)
3435 { 3753 {
3436 lock (m_host.TaskInventory) 3754 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3755 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3756 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3757 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3758 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3759
3760 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3437 { 3761 {
3762 m_host.TaskInventory.LockItemsForWrite(true);
3438 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3763 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3439 m_host.TaskInventory[invItemID].PermsMask = perm; 3764 m_host.TaskInventory[invItemID].PermsMask = perm;
3440 } 3765 m_host.TaskInventory.LockItemsForWrite(false);
3441 3766
3442 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3767 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3443 "run_time_permissions", new Object[] { 3768 "run_time_permissions", new Object[] {
3444 new LSL_Integer(perm) }, 3769 new LSL_Integer(perm) },
3445 new DetectParams[0])); 3770 new DetectParams[0]));
3446 3771
3447 return; 3772 return;
3773 }
3448 } 3774 }
3449 } 3775 }
3450 3776
@@ -3458,11 +3784,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3458 3784
3459 if (!m_waitingForScriptAnswer) 3785 if (!m_waitingForScriptAnswer)
3460 { 3786 {
3461 lock (m_host.TaskInventory) 3787 m_host.TaskInventory.LockItemsForWrite(true);
3462 { 3788 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3463 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3789 m_host.TaskInventory[invItemID].PermsMask = 0;
3464 m_host.TaskInventory[invItemID].PermsMask = 0; 3790 m_host.TaskInventory.LockItemsForWrite(false);
3465 }
3466 3791
3467 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3792 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3468 m_waitingForScriptAnswer=true; 3793 m_waitingForScriptAnswer=true;
@@ -3497,10 +3822,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3497 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3822 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3498 llReleaseControls(); 3823 llReleaseControls();
3499 3824
3500 lock (m_host.TaskInventory) 3825
3501 { 3826 m_host.TaskInventory.LockItemsForWrite(true);
3502 m_host.TaskInventory[invItemID].PermsMask = answer; 3827 m_host.TaskInventory[invItemID].PermsMask = answer;
3503 } 3828 m_host.TaskInventory.LockItemsForWrite(false);
3829
3504 3830
3505 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3831 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3506 "run_time_permissions", new Object[] { 3832 "run_time_permissions", new Object[] {
@@ -3512,16 +3838,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 { 3838 {
3513 m_host.AddScriptLPS(1); 3839 m_host.AddScriptLPS(1);
3514 3840
3515 lock (m_host.TaskInventory) 3841 m_host.TaskInventory.LockItemsForRead(true);
3842
3843 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3516 { 3844 {
3517 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3845 if (item.Type == 10 && item.ItemID == m_itemID)
3518 { 3846 {
3519 if (item.Type == 10 && item.ItemID == m_itemID) 3847 m_host.TaskInventory.LockItemsForRead(false);
3520 { 3848 return item.PermsGranter.ToString();
3521 return item.PermsGranter.ToString();
3522 }
3523 } 3849 }
3524 } 3850 }
3851 m_host.TaskInventory.LockItemsForRead(false);
3525 3852
3526 return UUID.Zero.ToString(); 3853 return UUID.Zero.ToString();
3527 } 3854 }
@@ -3530,19 +3857,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3530 { 3857 {
3531 m_host.AddScriptLPS(1); 3858 m_host.AddScriptLPS(1);
3532 3859
3533 lock (m_host.TaskInventory) 3860 m_host.TaskInventory.LockItemsForRead(true);
3861
3862 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3534 { 3863 {
3535 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3864 if (item.Type == 10 && item.ItemID == m_itemID)
3536 { 3865 {
3537 if (item.Type == 10 && item.ItemID == m_itemID) 3866 int perms = item.PermsMask;
3538 { 3867 if (m_automaticLinkPermission)
3539 int perms = item.PermsMask; 3868 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3540 if (m_automaticLinkPermission) 3869 m_host.TaskInventory.LockItemsForRead(false);
3541 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3870 return perms;
3542 return perms;
3543 }
3544 } 3871 }
3545 } 3872 }
3873 m_host.TaskInventory.LockItemsForRead(false);
3546 3874
3547 return 0; 3875 return 0;
3548 } 3876 }
@@ -3564,9 +3892,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3564 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3892 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3565 { 3893 {
3566 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3894 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3567 3895 if (parts.Count > 0)
3568 foreach (SceneObjectPart part in parts) 3896 {
3569 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3897 try
3898 {
3899 parts[0].ParentGroup.areUpdatesSuspended = true;
3900 foreach (SceneObjectPart part in parts)
3901 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3902 }
3903 finally
3904 {
3905 parts[0].ParentGroup.areUpdatesSuspended = false;
3906 }
3907 }
3570 } 3908 }
3571 3909
3572 public void llCreateLink(string target, int parent) 3910 public void llCreateLink(string target, int parent)
@@ -3579,11 +3917,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 return; 3917 return;
3580 3918
3581 TaskInventoryItem item; 3919 TaskInventoryItem item;
3582 lock (m_host.TaskInventory) 3920 m_host.TaskInventory.LockItemsForRead(true);
3583 { 3921 item = m_host.TaskInventory[invItemID];
3584 item = m_host.TaskInventory[invItemID]; 3922 m_host.TaskInventory.LockItemsForRead(false);
3585 } 3923
3586
3587 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3924 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3588 && !m_automaticLinkPermission) 3925 && !m_automaticLinkPermission)
3589 { 3926 {
@@ -3600,11 +3937,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3600 3937
3601 if (targetPart.ParentGroup.AttachmentPoint != 0) 3938 if (targetPart.ParentGroup.AttachmentPoint != 0)
3602 return; // Fail silently if attached 3939 return; // Fail silently if attached
3940
3941 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3942 return;
3943
3603 SceneObjectGroup parentPrim = null, childPrim = null; 3944 SceneObjectGroup parentPrim = null, childPrim = null;
3604 3945
3605 if (targetPart != null) 3946 if (targetPart != null)
3606 { 3947 {
3607 if (parent != 0) { 3948 if (parent != 0)
3949 {
3608 parentPrim = m_host.ParentGroup; 3950 parentPrim = m_host.ParentGroup;
3609 childPrim = targetPart.ParentGroup; 3951 childPrim = targetPart.ParentGroup;
3610 } 3952 }
@@ -3635,16 +3977,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3635 m_host.AddScriptLPS(1); 3977 m_host.AddScriptLPS(1);
3636 UUID invItemID = InventorySelf(); 3978 UUID invItemID = InventorySelf();
3637 3979
3638 lock (m_host.TaskInventory) 3980 m_host.TaskInventory.LockItemsForRead(true);
3639 {
3640 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3981 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3641 && !m_automaticLinkPermission) 3982 && !m_automaticLinkPermission)
3642 { 3983 {
3643 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3984 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3985 m_host.TaskInventory.LockItemsForRead(false);
3644 return; 3986 return;
3645 } 3987 }
3646 } 3988 m_host.TaskInventory.LockItemsForRead(false);
3647 3989
3648 if (linknum < ScriptBaseClass.LINK_THIS) 3990 if (linknum < ScriptBaseClass.LINK_THIS)
3649 return; 3991 return;
3650 3992
@@ -3683,10 +4025,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3683 // Restructuring Multiple Prims. 4025 // Restructuring Multiple Prims.
3684 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4026 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3685 parts.Remove(parentPrim.RootPart); 4027 parts.Remove(parentPrim.RootPart);
3686 foreach (SceneObjectPart part in parts) 4028 if (parts.Count > 0)
3687 { 4029 {
3688 parentPrim.DelinkFromGroup(part.LocalId, true); 4030 try
4031 {
4032 parts[0].ParentGroup.areUpdatesSuspended = true;
4033 foreach (SceneObjectPart part in parts)
4034 {
4035 parentPrim.DelinkFromGroup(part.LocalId, true);
4036 }
4037 }
4038 finally
4039 {
4040 parts[0].ParentGroup.areUpdatesSuspended = false;
4041 }
3689 } 4042 }
4043
3690 parentPrim.HasGroupChanged = true; 4044 parentPrim.HasGroupChanged = true;
3691 parentPrim.ScheduleGroupForFullUpdate(); 4045 parentPrim.ScheduleGroupForFullUpdate();
3692 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4046 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3695,12 +4049,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3695 { 4049 {
3696 SceneObjectPart newRoot = parts[0]; 4050 SceneObjectPart newRoot = parts[0];
3697 parts.Remove(newRoot); 4051 parts.Remove(newRoot);
3698 foreach (SceneObjectPart part in parts) 4052
4053 try
3699 { 4054 {
3700 // Required for linking 4055 parts[0].ParentGroup.areUpdatesSuspended = true;
3701 part.ClearUpdateSchedule(); 4056 foreach (SceneObjectPart part in parts)
3702 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4057 {
4058 part.ClearUpdateSchedule();
4059 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4060 }
3703 } 4061 }
4062 finally
4063 {
4064 parts[0].ParentGroup.areUpdatesSuspended = false;
4065 }
4066
4067
3704 newRoot.ParentGroup.HasGroupChanged = true; 4068 newRoot.ParentGroup.HasGroupChanged = true;
3705 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4069 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3706 } 4070 }
@@ -3720,6 +4084,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3720 public void llBreakAllLinks() 4084 public void llBreakAllLinks()
3721 { 4085 {
3722 m_host.AddScriptLPS(1); 4086 m_host.AddScriptLPS(1);
4087
4088 UUID invItemID = InventorySelf();
4089
4090 TaskInventoryItem item;
4091 m_host.TaskInventory.LockItemsForRead(true);
4092 item = m_host.TaskInventory[invItemID];
4093 m_host.TaskInventory.LockItemsForRead(false);
4094
4095 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4096 && !m_automaticLinkPermission)
4097 {
4098 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4099 return;
4100 }
4101
3723 SceneObjectGroup parentPrim = m_host.ParentGroup; 4102 SceneObjectGroup parentPrim = m_host.ParentGroup;
3724 if (parentPrim.AttachmentPoint != 0) 4103 if (parentPrim.AttachmentPoint != 0)
3725 return; // Fail silently if attached 4104 return; // Fail silently if attached
@@ -3765,6 +4144,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3765 } 4144 }
3766 else 4145 else
3767 { 4146 {
4147 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4148 {
4149 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4150
4151 if (linknum < 0)
4152 return UUID.Zero.ToString();
4153
4154 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4155 if (avatars.Count > linknum)
4156 {
4157 return avatars[linknum].UUID.ToString();
4158 }
4159 }
3768 return UUID.Zero.ToString(); 4160 return UUID.Zero.ToString();
3769 } 4161 }
3770 } 4162 }
@@ -3863,17 +4255,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3863 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3864 int count = 0; 4256 int count = 0;
3865 4257
3866 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3867 { 4260 {
3868 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3869 { 4262 {
3870 if (inv.Value.Type == type || type == -1) 4263 count = count + 1;
3871 {
3872 count = count + 1;
3873 }
3874 } 4264 }
3875 } 4265 }
3876 4266
4267 m_host.TaskInventory.LockItemsForRead(false);
3877 return count; 4268 return count;
3878 } 4269 }
3879 4270
@@ -3882,16 +4273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3882 m_host.AddScriptLPS(1); 4273 m_host.AddScriptLPS(1);
3883 ArrayList keys = new ArrayList(); 4274 ArrayList keys = new ArrayList();
3884 4275
3885 lock (m_host.TaskInventory) 4276 m_host.TaskInventory.LockItemsForRead(true);
4277 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3886 { 4278 {
3887 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4279 if (inv.Value.Type == type || type == -1)
3888 { 4280 {
3889 if (inv.Value.Type == type || type == -1) 4281 keys.Add(inv.Value.Name);
3890 {
3891 keys.Add(inv.Value.Name);
3892 }
3893 } 4282 }
3894 } 4283 }
4284 m_host.TaskInventory.LockItemsForRead(false);
3895 4285
3896 if (keys.Count == 0) 4286 if (keys.Count == 0)
3897 { 4287 {
@@ -3928,25 +4318,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3928 } 4318 }
3929 4319
3930 // move the first object found with this inventory name 4320 // move the first object found with this inventory name
3931 lock (m_host.TaskInventory) 4321 m_host.TaskInventory.LockItemsForRead(true);
4322 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3932 { 4323 {
3933 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4324 if (inv.Value.Name == inventory)
3934 { 4325 {
3935 if (inv.Value.Name == inventory) 4326 found = true;
3936 { 4327 objId = inv.Key;
3937 found = true; 4328 assetType = inv.Value.Type;
3938 objId = inv.Key; 4329 objName = inv.Value.Name;
3939 assetType = inv.Value.Type; 4330 break;
3940 objName = inv.Value.Name;
3941 break;
3942 }
3943 } 4331 }
3944 } 4332 }
4333 m_host.TaskInventory.LockItemsForRead(false);
3945 4334
3946 if (!found) 4335 if (!found)
3947 { 4336 {
3948 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4337 llSay(0, String.Format("Could not find object '{0}'", inventory));
3949 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4338 return;
4339// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3950 } 4340 }
3951 4341
3952 // check if destination is an object 4342 // check if destination is an object
@@ -3972,6 +4362,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 return; 4362 return;
3973 } 4363 }
3974 } 4364 }
4365
3975 // destination is an avatar 4366 // destination is an avatar
3976 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4367 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3977 4368
@@ -3994,26 +4385,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3994 bucket); 4385 bucket);
3995 if (m_TransferModule != null) 4386 if (m_TransferModule != null)
3996 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4387 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4388
4389 //This delay should only occur when giving inventory to avatars.
3997 ScriptSleep(3000); 4390 ScriptSleep(3000);
3998 } 4391 }
3999 } 4392 }
4000 4393
4394 [DebuggerNonUserCode]
4001 public void llRemoveInventory(string name) 4395 public void llRemoveInventory(string name)
4002 { 4396 {
4003 m_host.AddScriptLPS(1); 4397 m_host.AddScriptLPS(1);
4004 4398
4005 lock (m_host.TaskInventory) 4399 List<TaskInventoryItem> inv;
4400 try
4006 { 4401 {
4007 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4402 m_host.TaskInventory.LockItemsForRead(true);
4403 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4404 }
4405 finally
4406 {
4407 m_host.TaskInventory.LockItemsForRead(false);
4408 }
4409 foreach (TaskInventoryItem item in inv)
4410 {
4411 if (item.Name == name)
4008 { 4412 {
4009 if (item.Name == name) 4413 if (item.ItemID == m_itemID)
4010 { 4414 throw new ScriptDeleteException();
4011 if (item.ItemID == m_itemID) 4415 else
4012 throw new ScriptDeleteException(); 4416 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4013 else 4417 return;
4014 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4015 return;
4016 }
4017 } 4418 }
4018 } 4419 }
4019 } 4420 }
@@ -4048,112 +4449,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4048 { 4449 {
4049 m_host.AddScriptLPS(1); 4450 m_host.AddScriptLPS(1);
4050 4451
4051 UUID uuid = (UUID)id; 4452 UUID uuid;
4052 PresenceInfo pinfo = null; 4453 if (UUID.TryParse(id, out uuid))
4053 UserAccount account;
4054
4055 UserInfoCacheEntry ce;
4056 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4057 { 4454 {
4058 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4455 PresenceInfo pinfo = null;
4059 if (account == null) 4456 UserAccount account;
4457
4458 UserInfoCacheEntry ce;
4459 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4060 { 4460 {
4061 m_userInfoCache[uuid] = null; // Cache negative 4461 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4062 return UUID.Zero.ToString(); 4462 if (account == null)
4063 } 4463 {
4464 m_userInfoCache[uuid] = null; // Cache negative
4465 return UUID.Zero.ToString();
4466 }
4064 4467
4065 4468
4066 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4469 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4067 if (pinfos != null && pinfos.Length > 0) 4470 if (pinfos != null && pinfos.Length > 0)
4068 {
4069 foreach (PresenceInfo p in pinfos)
4070 { 4471 {
4071 if (p.RegionID != UUID.Zero) 4472 foreach (PresenceInfo p in pinfos)
4072 { 4473 {
4073 pinfo = p; 4474 if (p.RegionID != UUID.Zero)
4475 {
4476 pinfo = p;
4477 }
4074 } 4478 }
4075 } 4479 }
4076 }
4077 4480
4078 ce = new UserInfoCacheEntry(); 4481 ce = new UserInfoCacheEntry();
4079 ce.time = Util.EnvironmentTickCount(); 4482 ce.time = Util.EnvironmentTickCount();
4080 ce.account = account; 4483 ce.account = account;
4081 ce.pinfo = pinfo; 4484 ce.pinfo = pinfo;
4082 } 4485 m_userInfoCache[uuid] = ce;
4083 else 4486 }
4084 { 4487 else
4085 if (ce == null) 4488 {
4086 return UUID.Zero.ToString(); 4489 if (ce == null)
4490 return UUID.Zero.ToString();
4087 4491
4088 account = ce.account; 4492 account = ce.account;
4089 pinfo = ce.pinfo; 4493 pinfo = ce.pinfo;
4090 } 4494 }
4091 4495
4092 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4496 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4093 {
4094 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4095 if (pinfos != null && pinfos.Length > 0)
4096 { 4497 {
4097 foreach (PresenceInfo p in pinfos) 4498 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4499 if (pinfos != null && pinfos.Length > 0)
4098 { 4500 {
4099 if (p.RegionID != UUID.Zero) 4501 foreach (PresenceInfo p in pinfos)
4100 { 4502 {
4101 pinfo = p; 4503 if (p.RegionID != UUID.Zero)
4504 {
4505 pinfo = p;
4506 }
4102 } 4507 }
4103 } 4508 }
4104 } 4509 else
4105 else 4510 pinfo = null;
4106 pinfo = null;
4107 4511
4108 ce.time = Util.EnvironmentTickCount(); 4512 ce.time = Util.EnvironmentTickCount();
4109 ce.pinfo = pinfo; 4513 ce.pinfo = pinfo;
4110 } 4514 }
4111 4515
4112 string reply = String.Empty; 4516 string reply = String.Empty;
4113 4517
4114 switch (data) 4518 switch (data)
4115 { 4519 {
4116 case 1: // DATA_ONLINE (0|1) 4520 case 1: // DATA_ONLINE (0|1)
4117 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4521 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4118 reply = "1"; 4522 reply = "1";
4119 else 4523 else
4120 reply = "0"; 4524 reply = "0";
4121 break; 4525 break;
4122 case 2: // DATA_NAME (First Last) 4526 case 2: // DATA_NAME (First Last)
4123 reply = account.FirstName + " " + account.LastName; 4527 reply = account.FirstName + " " + account.LastName;
4124 break; 4528 break;
4125 case 3: // DATA_BORN (YYYY-MM-DD) 4529 case 3: // DATA_BORN (YYYY-MM-DD)
4126 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4530 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4127 born = born.AddSeconds(account.Created); 4531 born = born.AddSeconds(account.Created);
4128 reply = born.ToString("yyyy-MM-dd"); 4532 reply = born.ToString("yyyy-MM-dd");
4129 break; 4533 break;
4130 case 4: // DATA_RATING (0,0,0,0,0,0) 4534 case 4: // DATA_RATING (0,0,0,0,0,0)
4131 reply = "0,0,0,0,0,0"; 4535 reply = "0,0,0,0,0,0";
4132 break; 4536 break;
4133 case 8: // DATA_PAYINFO (0|1|2|3) 4537 case 8: // DATA_PAYINFO (0|1|2|3)
4134 reply = "0"; 4538 reply = "0";
4135 break; 4539 break;
4136 default: 4540 default:
4137 return UUID.Zero.ToString(); // Raise no event 4541 return UUID.Zero.ToString(); // Raise no event
4138 } 4542 }
4139 4543
4140 UUID rq = UUID.Random(); 4544 UUID rq = UUID.Random();
4141 4545
4142 UUID tid = AsyncCommands. 4546 UUID tid = AsyncCommands.
4143 DataserverPlugin.RegisterRequest(m_localID, 4547 DataserverPlugin.RegisterRequest(m_localID,
4144 m_itemID, rq.ToString()); 4548 m_itemID, rq.ToString());
4145 4549
4146 AsyncCommands. 4550 AsyncCommands.
4147 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4551 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4148 4552
4149 ScriptSleep(100); 4553 ScriptSleep(100);
4150 return tid.ToString(); 4554 return tid.ToString();
4555 }
4556 else
4557 {
4558 ShoutError("Invalid UUID passed to llRequestAgentData.");
4559 }
4560 return "";
4151 } 4561 }
4152 4562
4153 public LSL_String llRequestInventoryData(string name) 4563 public LSL_String llRequestInventoryData(string name)
4154 { 4564 {
4155 m_host.AddScriptLPS(1); 4565 m_host.AddScriptLPS(1);
4156 4566
4567 //Clone is thread safe
4157 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4568 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4158 4569
4159 foreach (TaskInventoryItem item in itemDictionary.Values) 4570 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4207,6 +4618,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4207 ScenePresence presence = World.GetScenePresence(agentId); 4618 ScenePresence presence = World.GetScenePresence(agentId);
4208 if (presence != null) 4619 if (presence != null)
4209 { 4620 {
4621 // agent must not be a god
4622 if (presence.UserLevel >= 200) return;
4623
4210 // agent must be over the owners land 4624 // agent must be over the owners land
4211 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4625 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4212 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4626 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4229,7 +4643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 UUID av = new UUID(); 4643 UUID av = new UUID();
4230 if (!UUID.TryParse(agent,out av)) 4644 if (!UUID.TryParse(agent,out av))
4231 { 4645 {
4232 LSLError("First parameter to llDialog needs to be a key"); 4646 //LSLError("First parameter to llDialog needs to be a key");
4233 return; 4647 return;
4234 } 4648 }
4235 4649
@@ -4266,17 +4680,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4266 UUID soundId = UUID.Zero; 4680 UUID soundId = UUID.Zero;
4267 if (!UUID.TryParse(impact_sound, out soundId)) 4681 if (!UUID.TryParse(impact_sound, out soundId))
4268 { 4682 {
4269 lock (m_host.TaskInventory) 4683 m_host.TaskInventory.LockItemsForRead(true);
4684 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4270 { 4685 {
4271 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4686 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4272 { 4687 {
4273 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4688 soundId = item.AssetID;
4274 { 4689 break;
4275 soundId = item.AssetID;
4276 break;
4277 }
4278 } 4690 }
4279 } 4691 }
4692 m_host.TaskInventory.LockItemsForRead(false);
4280 } 4693 }
4281 m_host.CollisionSound = soundId; 4694 m_host.CollisionSound = soundId;
4282 m_host.CollisionSoundVolume = (float)impact_volume; 4695 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4316,6 +4729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4316 UUID partItemID; 4729 UUID partItemID;
4317 foreach (SceneObjectPart part in parts) 4730 foreach (SceneObjectPart part in parts)
4318 { 4731 {
4732 //Clone is thread safe
4319 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4733 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4320 4734
4321 foreach (TaskInventoryItem item in itemsDictionary.Values) 4735 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4530,17 +4944,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4530 4944
4531 m_host.AddScriptLPS(1); 4945 m_host.AddScriptLPS(1);
4532 4946
4533 lock (m_host.TaskInventory) 4947 m_host.TaskInventory.LockItemsForRead(true);
4948 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4534 { 4949 {
4535 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4950 if (item.Type == 10 && item.ItemID == m_itemID)
4536 { 4951 {
4537 if (item.Type == 10 && item.ItemID == m_itemID) 4952 result = item.Name!=null?item.Name:String.Empty;
4538 { 4953 break;
4539 result = item.Name != null ? item.Name : String.Empty;
4540 break;
4541 }
4542 } 4954 }
4543 } 4955 }
4956 m_host.TaskInventory.LockItemsForRead(false);
4544 4957
4545 return result; 4958 return result;
4546 } 4959 }
@@ -4709,23 +5122,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4709 { 5122 {
4710 m_host.AddScriptLPS(1); 5123 m_host.AddScriptLPS(1);
4711 5124
4712 lock (m_host.TaskInventory) 5125 m_host.TaskInventory.LockItemsForRead(true);
5126 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4713 { 5127 {
4714 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5128 if (inv.Value.Name == name)
4715 { 5129 {
4716 if (inv.Value.Name == name) 5130 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4717 { 5131 {
4718 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5132 m_host.TaskInventory.LockItemsForRead(false);
4719 { 5133 return inv.Value.AssetID.ToString();
4720 return inv.Value.AssetID.ToString(); 5134 }
4721 } 5135 else
4722 else 5136 {
4723 { 5137 m_host.TaskInventory.LockItemsForRead(false);
4724 return UUID.Zero.ToString(); 5138 return UUID.Zero.ToString();
4725 }
4726 } 5139 }
4727 } 5140 }
4728 } 5141 }
5142 m_host.TaskInventory.LockItemsForRead(false);
4729 5143
4730 return UUID.Zero.ToString(); 5144 return UUID.Zero.ToString();
4731 } 5145 }
@@ -4878,14 +5292,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4878 { 5292 {
4879 m_host.AddScriptLPS(1); 5293 m_host.AddScriptLPS(1);
4880 5294
4881 if (src == null) 5295 return src.Length;
4882 {
4883 return 0;
4884 }
4885 else
4886 {
4887 return src.Length;
4888 }
4889 } 5296 }
4890 5297
4891 public LSL_Integer llList2Integer(LSL_List src, int index) 5298 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4931,7 +5338,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4931 else if (src.Data[index] is LSL_Float) 5338 else if (src.Data[index] is LSL_Float)
4932 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5339 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4933 else if (src.Data[index] is LSL_String) 5340 else if (src.Data[index] is LSL_String)
4934 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5341 {
5342 string str = ((LSL_String) src.Data[index]).m_string;
5343 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5344 if (m != Match.Empty)
5345 {
5346 str = m.Value;
5347 double d = 0.0;
5348 if (!Double.TryParse(str, out d))
5349 return 0.0;
5350
5351 return d;
5352 }
5353 return 0.0;
5354 }
4935 return Convert.ToDouble(src.Data[index]); 5355 return Convert.ToDouble(src.Data[index]);
4936 } 5356 }
4937 catch (FormatException) 5357 catch (FormatException)
@@ -5204,7 +5624,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5204 } 5624 }
5205 } 5625 }
5206 } 5626 }
5207 else { 5627 else
5628 {
5208 object[] array = new object[src.Length]; 5629 object[] array = new object[src.Length];
5209 Array.Copy(src.Data, 0, array, 0, src.Length); 5630 Array.Copy(src.Data, 0, array, 0, src.Length);
5210 result = new LSL_List(array); 5631 result = new LSL_List(array);
@@ -5655,10 +6076,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5655 m_host.AddScriptLPS(1); 6076 m_host.AddScriptLPS(1);
5656 6077
5657 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6078 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5658 6079 if (parts.Count > 0)
5659 foreach (var part in parts)
5660 { 6080 {
5661 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6081 try
6082 {
6083 parts[0].ParentGroup.areUpdatesSuspended = true;
6084 foreach (var part in parts)
6085 {
6086 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6087 }
6088 }
6089 finally
6090 {
6091 parts[0].ParentGroup.areUpdatesSuspended = false;
6092 }
5662 } 6093 }
5663 } 6094 }
5664 6095
@@ -5712,6 +6143,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5712 ScriptSleep(5000); 6143 ScriptSleep(5000);
5713 } 6144 }
5714 6145
6146 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6147 {
6148 return ParseString2List(str, separators, in_spacers, false);
6149 }
6150
5715 public LSL_Integer llOverMyLand(string id) 6151 public LSL_Integer llOverMyLand(string id)
5716 { 6152 {
5717 m_host.AddScriptLPS(1); 6153 m_host.AddScriptLPS(1);
@@ -5912,7 +6348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5912 return m_host.ParentGroup.AttachmentPoint; 6348 return m_host.ParentGroup.AttachmentPoint;
5913 } 6349 }
5914 6350
5915 public LSL_Integer llGetFreeMemory() 6351 public virtual LSL_Integer llGetFreeMemory()
5916 { 6352 {
5917 m_host.AddScriptLPS(1); 6353 m_host.AddScriptLPS(1);
5918 // Make scripts designed for LSO happy 6354 // Make scripts designed for LSO happy
@@ -6029,7 +6465,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6029 SetParticleSystem(m_host, rules); 6465 SetParticleSystem(m_host, rules);
6030 } 6466 }
6031 6467
6032 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6468 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6469 {
6033 6470
6034 6471
6035 if (rules.Length == 0) 6472 if (rules.Length == 0)
@@ -6223,14 +6660,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6223 6660
6224 protected UUID GetTaskInventoryItem(string name) 6661 protected UUID GetTaskInventoryItem(string name)
6225 { 6662 {
6226 lock (m_host.TaskInventory) 6663 m_host.TaskInventory.LockItemsForRead(true);
6664 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6227 { 6665 {
6228 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6666 if (inv.Value.Name == name)
6229 { 6667 {
6230 if (inv.Value.Name == name) 6668 m_host.TaskInventory.LockItemsForRead(false);
6231 return inv.Key; 6669 return inv.Key;
6232 } 6670 }
6233 } 6671 }
6672 m_host.TaskInventory.LockItemsForRead(false);
6234 6673
6235 return UUID.Zero; 6674 return UUID.Zero;
6236 } 6675 }
@@ -6480,13 +6919,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6480 UUID av = new UUID(); 6919 UUID av = new UUID();
6481 if (!UUID.TryParse(avatar,out av)) 6920 if (!UUID.TryParse(avatar,out av))
6482 { 6921 {
6483 LSLError("First parameter to llDialog needs to be a key"); 6922 //LSLError("First parameter to llDialog needs to be a key");
6484 return; 6923 return;
6485 } 6924 }
6486 if (buttons.Length < 1) 6925 if (buttons.Length < 1)
6487 { 6926 {
6488 LSLError("No less than 1 button can be shown"); 6927 buttons.Add("OK");
6489 return;
6490 } 6928 }
6491 if (buttons.Length > 12) 6929 if (buttons.Length > 12)
6492 { 6930 {
@@ -6503,7 +6941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6503 } 6941 }
6504 if (buttons.Data[i].ToString().Length > 24) 6942 if (buttons.Data[i].ToString().Length > 24)
6505 { 6943 {
6506 LSLError("button label cannot be longer than 24 characters"); 6944 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6507 return; 6945 return;
6508 } 6946 }
6509 buts[i] = buttons.Data[i].ToString(); 6947 buts[i] = buttons.Data[i].ToString();
@@ -6562,22 +7000,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6562 } 7000 }
6563 7001
6564 // copy the first script found with this inventory name 7002 // copy the first script found with this inventory name
6565 lock (m_host.TaskInventory) 7003 TaskInventoryItem scriptItem = null;
7004 m_host.TaskInventory.LockItemsForRead(true);
7005 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6566 { 7006 {
6567 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7007 if (inv.Value.Name == name)
6568 { 7008 {
6569 if (inv.Value.Name == name) 7009 // make sure the object is a script
7010 if (10 == inv.Value.Type)
6570 { 7011 {
6571 // make sure the object is a script 7012 found = true;
6572 if (10 == inv.Value.Type) 7013 srcId = inv.Key;
6573 { 7014 scriptItem = inv.Value;
6574 found = true; 7015 break;
6575 srcId = inv.Key;
6576 break;
6577 }
6578 } 7016 }
6579 } 7017 }
6580 } 7018 }
7019 m_host.TaskInventory.LockItemsForRead(false);
6581 7020
6582 if (!found) 7021 if (!found)
6583 { 7022 {
@@ -6585,8 +7024,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6585 return; 7024 return;
6586 } 7025 }
6587 7026
6588 // the rest of the permission checks are done in RezScript, so check the pin there as well 7027 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6589 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7028 if (dest != null)
7029 {
7030 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7031 {
7032 // the rest of the permission checks are done in RezScript, so check the pin there as well
7033 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7034
7035 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7036 m_host.Inventory.RemoveInventoryItem(srcId);
7037 }
7038 }
6590 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7039 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6591 ScriptSleep(3000); 7040 ScriptSleep(3000);
6592 } 7041 }
@@ -6649,19 +7098,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6649 public LSL_String llMD5String(string src, int nonce) 7098 public LSL_String llMD5String(string src, int nonce)
6650 { 7099 {
6651 m_host.AddScriptLPS(1); 7100 m_host.AddScriptLPS(1);
6652 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7101 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6653 } 7102 }
6654 7103
6655 public LSL_String llSHA1String(string src) 7104 public LSL_String llSHA1String(string src)
6656 { 7105 {
6657 m_host.AddScriptLPS(1); 7106 m_host.AddScriptLPS(1);
6658 return Util.SHA1Hash(src).ToLower(); 7107 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6659 } 7108 }
6660 7109
6661 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7110 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6662 { 7111 {
6663 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7112 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6664 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7113 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7114 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7115 return shapeBlock;
6665 7116
6666 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7117 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6667 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7118 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6766,6 +7217,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6766 // Prim type box, cylinder and prism. 7217 // Prim type box, cylinder and prism.
6767 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) 7218 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)
6768 { 7219 {
7220 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7221 return;
7222
6769 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7223 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6770 ObjectShapePacket.ObjectDataBlock shapeBlock; 7224 ObjectShapePacket.ObjectDataBlock shapeBlock;
6771 7225
@@ -6819,6 +7273,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6819 // Prim type sphere. 7273 // Prim type sphere.
6820 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7274 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6821 { 7275 {
7276 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7277 return;
7278
6822 ObjectShapePacket.ObjectDataBlock shapeBlock; 7279 ObjectShapePacket.ObjectDataBlock shapeBlock;
6823 7280
6824 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7281 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6860,6 +7317,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6860 // Prim type torus, tube and ring. 7317 // Prim type torus, tube and ring.
6861 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) 7318 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)
6862 { 7319 {
7320 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7321 return;
7322
6863 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7323 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6864 ObjectShapePacket.ObjectDataBlock shapeBlock; 7324 ObjectShapePacket.ObjectDataBlock shapeBlock;
6865 7325
@@ -6995,6 +7455,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6995 // Prim type sculpt. 7455 // Prim type sculpt.
6996 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7456 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6997 { 7457 {
7458 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7459 return;
7460
6998 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7461 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6999 UUID sculptId; 7462 UUID sculptId;
7000 7463
@@ -7011,13 +7474,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7011 shapeBlock.PathScaleX = 100; 7474 shapeBlock.PathScaleX = 100;
7012 shapeBlock.PathScaleY = 150; 7475 shapeBlock.PathScaleY = 150;
7013 7476
7014 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7477 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7015 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7478 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7016 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7479 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7017 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7480 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7018 { 7481 {
7019 // default 7482 // default
7020 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7483 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7021 } 7484 }
7022 7485
7023 part.Shape.SetSculptProperties((byte)type, sculptId); 7486 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7033,32 +7496,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7033 ScriptSleep(200); 7496 ScriptSleep(200);
7034 } 7497 }
7035 7498
7036 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7499 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7037 { 7500 {
7038 m_host.AddScriptLPS(1); 7501 m_host.AddScriptLPS(1);
7039 7502
7040 setLinkPrimParams(linknumber, rules); 7503 setLinkPrimParams(linknumber, rules);
7041
7042 ScriptSleep(200);
7043 } 7504 }
7044 7505
7045 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7506 private void setLinkPrimParams(int linknumber, LSL_List rules)
7046 { 7507 {
7047 m_host.AddScriptLPS(1); 7508 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7509 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7510 if (parts.Count>0)
7511 {
7512 try
7513 {
7514 parts[0].ParentGroup.areUpdatesSuspended = true;
7515 foreach (SceneObjectPart part in parts)
7516 SetPrimParams(part, rules);
7517 }
7518 finally
7519 {
7520 parts[0].ParentGroup.areUpdatesSuspended = false;
7521 }
7522 }
7523 if (avatars.Count > 0)
7524 {
7525 foreach (ScenePresence avatar in avatars)
7526 SetPrimParams(avatar, rules);
7527 }
7528 }
7048 7529
7049 setLinkPrimParams(linknumber, rules); 7530 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7531 {
7532 llSetLinkPrimitiveParamsFast(linknumber, rules);
7533 ScriptSleep(200);
7050 } 7534 }
7051 7535
7052 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7536 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7053 { 7537 {
7054 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7538 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7539 //We only support PRIM_POSITION and PRIM_ROTATION
7055 7540
7056 foreach (SceneObjectPart part in parts) 7541 int idx = 0;
7057 SetPrimParams(part, rules); 7542
7543 while (idx < rules.Length)
7544 {
7545 int code = rules.GetLSLIntegerItem(idx++);
7546
7547 int remain = rules.Length - idx;
7548
7549
7550
7551 switch (code)
7552 {
7553 case (int)ScriptBaseClass.PRIM_POSITION:
7554 if (remain < 1)
7555 return;
7556 LSL_Vector v;
7557 v = rules.GetVector3Item(idx++);
7558 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7559 av.SendAvatarDataToAllAgents();
7560
7561 break;
7562
7563 case (int)ScriptBaseClass.PRIM_ROTATION:
7564 if (remain < 1)
7565 return;
7566 LSL_Rotation r;
7567 r = rules.GetQuaternionItem(idx++);
7568 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7569 av.SendAvatarDataToAllAgents();
7570 break;
7571 }
7572 }
7058 } 7573 }
7059 7574
7060 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7575 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7061 { 7576 {
7577 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7578 return;
7579
7062 int idx = 0; 7580 int idx = 0;
7063 7581
7064 bool positionChanged = false; 7582 bool positionChanged = false;
@@ -7463,6 +7981,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7463 } 7981 }
7464 } 7982 }
7465 } 7983 }
7984
7985 if (positionChanged)
7986 {
7987 if (part.ParentGroup.RootPart == part)
7988 {
7989 SceneObjectGroup parent = part.ParentGroup;
7990 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7991 }
7992 else
7993 {
7994 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7995 SceneObjectGroup parent = part.ParentGroup;
7996 parent.HasGroupChanged = true;
7997 parent.ScheduleGroupForTerseUpdate();
7998 }
7999 }
7466 } 8000 }
7467 8001
7468 public LSL_String llStringToBase64(string str) 8002 public LSL_String llStringToBase64(string str)
@@ -7611,13 +8145,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7611 public LSL_Integer llGetNumberOfPrims() 8145 public LSL_Integer llGetNumberOfPrims()
7612 { 8146 {
7613 m_host.AddScriptLPS(1); 8147 m_host.AddScriptLPS(1);
7614 int avatarCount = 0; 8148 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7615 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8149
7616 {
7617 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7618 avatarCount++;
7619 });
7620
7621 return m_host.ParentGroup.PrimCount + avatarCount; 8150 return m_host.ParentGroup.PrimCount + avatarCount;
7622 } 8151 }
7623 8152
@@ -7633,55 +8162,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7633 m_host.AddScriptLPS(1); 8162 m_host.AddScriptLPS(1);
7634 UUID objID = UUID.Zero; 8163 UUID objID = UUID.Zero;
7635 LSL_List result = new LSL_List(); 8164 LSL_List result = new LSL_List();
8165
8166 // If the ID is not valid, return null result
7636 if (!UUID.TryParse(obj, out objID)) 8167 if (!UUID.TryParse(obj, out objID))
7637 { 8168 {
7638 result.Add(new LSL_Vector()); 8169 result.Add(new LSL_Vector());
7639 result.Add(new LSL_Vector()); 8170 result.Add(new LSL_Vector());
7640 return result; 8171 return result;
7641 } 8172 }
8173
8174 // Check if this is an attached prim. If so, replace
8175 // the UUID with the avatar UUID and report it's bounding box
8176 SceneObjectPart part = World.GetSceneObjectPart(objID);
8177 if (part != null && part.ParentGroup.IsAttachment)
8178 objID = part.ParentGroup.AttachedAvatar;
8179
8180 // Find out if this is an avatar ID. If so, return it's box
7642 ScenePresence presence = World.GetScenePresence(objID); 8181 ScenePresence presence = World.GetScenePresence(objID);
7643 if (presence != null) 8182 if (presence != null)
7644 { 8183 {
7645 if (presence.ParentID == 0) // not sat on an object 8184 // As per LSL Wiki, there is no difference between sitting
8185 // and standing avatar since server 1.36
8186 LSL_Vector lower;
8187 LSL_Vector upper;
8188 if (presence.Animator.Animations.DefaultAnimation.AnimID
8189 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7646 { 8190 {
7647 LSL_Vector lower; 8191 // This is for ground sitting avatars
7648 LSL_Vector upper; 8192 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7649 if (presence.Animator.Animations.DefaultAnimation.AnimID 8193 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7650 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8194 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7651 {
7652 // This is for ground sitting avatars
7653 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7654 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7655 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7656 }
7657 else
7658 {
7659 // This is for standing/flying avatars
7660 float height = presence.Appearance.AvatarHeight / 2.0f;
7661 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7662 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7663 }
7664 result.Add(lower);
7665 result.Add(upper);
7666 return result;
7667 } 8195 }
7668 else 8196 else
7669 { 8197 {
7670 // sitting on an object so we need the bounding box of that 8198 // This is for standing/flying avatars
7671 // which should include the avatar so set the UUID to the 8199 float height = presence.Appearance.AvatarHeight / 2.0f;
7672 // UUID of the object the avatar is sat on and allow it to fall through 8200 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7673 // to processing an object 8201 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7674 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7675 objID = p.UUID;
7676 } 8202 }
8203
8204 // Adjust to the documented error offsets (see LSL Wiki)
8205 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8206 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8207
8208 if (lower.x > upper.x)
8209 lower.x = upper.x;
8210 if (lower.y > upper.y)
8211 lower.y = upper.y;
8212 if (lower.z > upper.z)
8213 lower.z = upper.z;
8214
8215 result.Add(lower);
8216 result.Add(upper);
8217 return result;
7677 } 8218 }
7678 SceneObjectPart part = World.GetSceneObjectPart(objID); 8219
8220 part = World.GetSceneObjectPart(objID);
7679 // Currently only works for single prims without a sitting avatar 8221 // Currently only works for single prims without a sitting avatar
7680 if (part != null) 8222 if (part != null)
7681 { 8223 {
7682 Vector3 halfSize = part.Scale / 2.0f; 8224 float minX;
7683 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8225 float maxX;
7684 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8226 float minY;
8227 float maxY;
8228 float minZ;
8229 float maxZ;
8230
8231 // This BBox is in sim coordinates, with the offset being
8232 // a contained point.
8233 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8234 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8235
8236 minX -= offsets[0].X;
8237 maxX -= offsets[0].X;
8238 minY -= offsets[0].Y;
8239 maxY -= offsets[0].Y;
8240 minZ -= offsets[0].Z;
8241 maxZ -= offsets[0].Z;
8242
8243 LSL_Vector lower;
8244 LSL_Vector upper;
8245
8246 // Adjust to the documented error offsets (see LSL Wiki)
8247 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8248 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8249
8250 if (lower.x > upper.x)
8251 lower.x = upper.x;
8252 if (lower.y > upper.y)
8253 lower.y = upper.y;
8254 if (lower.z > upper.z)
8255 lower.z = upper.z;
8256
7685 result.Add(lower); 8257 result.Add(lower);
7686 result.Add(upper); 8258 result.Add(upper);
7687 return result; 8259 return result;
@@ -7761,13 +8333,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7761 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8333 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7762 part.AbsolutePosition.Y, 8334 part.AbsolutePosition.Y,
7763 part.AbsolutePosition.Z); 8335 part.AbsolutePosition.Z);
7764 // For some reason, the part.AbsolutePosition.* values do not change if the
7765 // linkset is rotated; they always reflect the child prim's world position
7766 // as though the linkset is unrotated. This is incompatible behavior with SL's
7767 // implementation, so will break scripts imported from there (not to mention it
7768 // makes it more difficult to determine a child prim's actual inworld position).
7769 if (part.ParentID != 0)
7770 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7771 res.Add(v); 8336 res.Add(v);
7772 break; 8337 break;
7773 8338
@@ -7938,56 +8503,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7938 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8503 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7939 if (remain < 1) 8504 if (remain < 1)
7940 return res; 8505 return res;
7941 8506 face = (int)rules.GetLSLIntegerItem(idx++);
7942 face=(int)rules.GetLSLIntegerItem(idx++);
7943 8507
7944 tex = part.Shape.Textures; 8508 tex = part.Shape.Textures;
8509 int shiny;
7945 if (face == ScriptBaseClass.ALL_SIDES) 8510 if (face == ScriptBaseClass.ALL_SIDES)
7946 { 8511 {
7947 for (face = 0; face < GetNumberOfSides(part); face++) 8512 for (face = 0; face < GetNumberOfSides(part); face++)
7948 { 8513 {
7949 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8514 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7950 // Convert Shininess to PRIM_SHINY_* 8515 if (shinyness == Shininess.High)
7951 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8516 {
7952 // PRIM_BUMP_* 8517 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7953 res.Add(new LSL_Integer((int)texface.Bump)); 8518 }
8519 else if (shinyness == Shininess.Medium)
8520 {
8521 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8522 }
8523 else if (shinyness == Shininess.Low)
8524 {
8525 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8526 }
8527 else
8528 {
8529 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8530 }
8531 res.Add(new LSL_Integer(shiny));
8532 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7954 } 8533 }
7955 } 8534 }
7956 else 8535 else
7957 { 8536 {
7958 if (face >= 0 && face < GetNumberOfSides(part)) 8537 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8538 if (shinyness == Shininess.High)
7959 { 8539 {
7960 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8540 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7961 // Convert Shininess to PRIM_SHINY_* 8541 }
7962 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8542 else if (shinyness == Shininess.Medium)
7963 // PRIM_BUMP_* 8543 {
7964 res.Add(new LSL_Integer((int)texface.Bump)); 8544 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8545 }
8546 else if (shinyness == Shininess.Low)
8547 {
8548 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8549 }
8550 else
8551 {
8552 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7965 } 8553 }
8554 res.Add(new LSL_Integer(shiny));
8555 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7966 } 8556 }
7967 break; 8557 break;
7968 8558
7969 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8559 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7970 if (remain < 1) 8560 if (remain < 1)
7971 return res; 8561 return res;
7972 8562 face = (int)rules.GetLSLIntegerItem(idx++);
7973 face=(int)rules.GetLSLIntegerItem(idx++);
7974 8563
7975 tex = part.Shape.Textures; 8564 tex = part.Shape.Textures;
8565 int fullbright;
7976 if (face == ScriptBaseClass.ALL_SIDES) 8566 if (face == ScriptBaseClass.ALL_SIDES)
7977 { 8567 {
7978 for (face = 0; face < GetNumberOfSides(part); face++) 8568 for (face = 0; face < GetNumberOfSides(part); face++)
7979 { 8569 {
7980 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8570 if (tex.GetFace((uint)face).Fullbright == true)
7981 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8571 {
8572 fullbright = ScriptBaseClass.TRUE;
8573 }
8574 else
8575 {
8576 fullbright = ScriptBaseClass.FALSE;
8577 }
8578 res.Add(new LSL_Integer(fullbright));
7982 } 8579 }
7983 } 8580 }
7984 else 8581 else
7985 { 8582 {
7986 if (face >= 0 && face < GetNumberOfSides(part)) 8583 if (tex.GetFace((uint)face).Fullbright == true)
7987 { 8584 {
7988 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8585 fullbright = ScriptBaseClass.TRUE;
7989 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8586 }
8587 else
8588 {
8589 fullbright = ScriptBaseClass.FALSE;
7990 } 8590 }
8591 res.Add(new LSL_Integer(fullbright));
7991 } 8592 }
7992 break; 8593 break;
7993 8594
@@ -8009,27 +8610,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8009 break; 8610 break;
8010 8611
8011 case (int)ScriptBaseClass.PRIM_TEXGEN: 8612 case (int)ScriptBaseClass.PRIM_TEXGEN:
8613 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8012 if (remain < 1) 8614 if (remain < 1)
8013 return res; 8615 return res;
8014 8616 face = (int)rules.GetLSLIntegerItem(idx++);
8015 face=(int)rules.GetLSLIntegerItem(idx++);
8016 8617
8017 tex = part.Shape.Textures; 8618 tex = part.Shape.Textures;
8018 if (face == ScriptBaseClass.ALL_SIDES) 8619 if (face == ScriptBaseClass.ALL_SIDES)
8019 { 8620 {
8020 for (face = 0; face < GetNumberOfSides(part); face++) 8621 for (face = 0; face < GetNumberOfSides(part); face++)
8021 { 8622 {
8022 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8623 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8023 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8624 {
8024 res.Add(new LSL_Integer((uint)texgen >> 1)); 8625 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8626 }
8627 else
8628 {
8629 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8630 }
8025 } 8631 }
8026 } 8632 }
8027 else 8633 else
8028 { 8634 {
8029 if (face >= 0 && face < GetNumberOfSides(part)) 8635 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8636 {
8637 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8638 }
8639 else
8030 { 8640 {
8031 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8641 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8032 res.Add(new LSL_Integer((uint)texgen >> 1));
8033 } 8642 }
8034 } 8643 }
8035 break; 8644 break;
@@ -8052,28 +8661,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8052 case (int)ScriptBaseClass.PRIM_GLOW: 8661 case (int)ScriptBaseClass.PRIM_GLOW:
8053 if (remain < 1) 8662 if (remain < 1)
8054 return res; 8663 return res;
8055 8664 face = (int)rules.GetLSLIntegerItem(idx++);
8056 face=(int)rules.GetLSLIntegerItem(idx++);
8057 8665
8058 tex = part.Shape.Textures; 8666 tex = part.Shape.Textures;
8667 float primglow;
8059 if (face == ScriptBaseClass.ALL_SIDES) 8668 if (face == ScriptBaseClass.ALL_SIDES)
8060 { 8669 {
8061 for (face = 0; face < GetNumberOfSides(part); face++) 8670 for (face = 0; face < GetNumberOfSides(part); face++)
8062 { 8671 {
8063 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8672 primglow = tex.GetFace((uint)face).Glow;
8064 res.Add(new LSL_Float(texface.Glow)); 8673 res.Add(new LSL_Float(primglow));
8065 } 8674 }
8066 } 8675 }
8067 else 8676 else
8068 { 8677 {
8069 if (face >= 0 && face < GetNumberOfSides(part)) 8678 primglow = tex.GetFace((uint)face).Glow;
8070 { 8679 res.Add(new LSL_Float(primglow));
8071 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8072 res.Add(new LSL_Float(texface.Glow));
8073 }
8074 } 8680 }
8075 break; 8681 break;
8076
8077 case (int)ScriptBaseClass.PRIM_TEXT: 8682 case (int)ScriptBaseClass.PRIM_TEXT:
8078 Color4 textColor = part.GetTextColor(); 8683 Color4 textColor = part.GetTextColor();
8079 res.Add(new LSL_String(part.Text)); 8684 res.Add(new LSL_String(part.Text));
@@ -8622,8 +9227,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8622 // The function returns an ordered list 9227 // The function returns an ordered list
8623 // representing the tokens found in the supplied 9228 // representing the tokens found in the supplied
8624 // sources string. If two successive tokenizers 9229 // sources string. If two successive tokenizers
8625 // are encountered, then a NULL entry is added 9230 // are encountered, then a null-string entry is
8626 // to the list. 9231 // added to the list.
8627 // 9232 //
8628 // It is a precondition that the source and 9233 // It is a precondition that the source and
8629 // toekizer lisst are non-null. If they are null, 9234 // toekizer lisst are non-null. If they are null,
@@ -8631,7 +9236,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8631 // while their lengths are being determined. 9236 // while their lengths are being determined.
8632 // 9237 //
8633 // A small amount of working memoryis required 9238 // A small amount of working memoryis required
8634 // of approximately 8*#tokenizers. 9239 // of approximately 8*#tokenizers + 8*srcstrlen.
8635 // 9240 //
8636 // There are many ways in which this function 9241 // There are many ways in which this function
8637 // can be implemented, this implementation is 9242 // can be implemented, this implementation is
@@ -8647,155 +9252,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8647 // and eliminates redundant tokenizers as soon 9252 // and eliminates redundant tokenizers as soon
8648 // as is possible. 9253 // as is possible.
8649 // 9254 //
8650 // The implementation tries to avoid any copying 9255 // The implementation tries to minimize temporary
8651 // of arrays or other objects. 9256 // garbage generation.
8652 // </remarks> 9257 // </remarks>
8653 9258
8654 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9259 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8655 { 9260 {
8656 int beginning = 0; 9261 return ParseString2List(src, separators, spacers, true);
8657 int srclen = src.Length; 9262 }
8658 int seplen = separators.Length;
8659 object[] separray = separators.Data;
8660 int spclen = spacers.Length;
8661 object[] spcarray = spacers.Data;
8662 int mlen = seplen+spclen;
8663
8664 int[] offset = new int[mlen+1];
8665 bool[] active = new bool[mlen];
8666
8667 int best;
8668 int j;
8669
8670 // Initial capacity reduces resize cost
8671 9263
8672 LSL_List tokens = new LSL_List(); 9264 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9265 {
9266 int srclen = src.Length;
9267 int seplen = separators.Length;
9268 object[] separray = separators.Data;
9269 int spclen = spacers.Length;
9270 object[] spcarray = spacers.Data;
9271 int dellen = 0;
9272 string[] delarray = new string[seplen+spclen];
8673 9273
8674 // All entries are initially valid 9274 int outlen = 0;
9275 string[] outarray = new string[srclen*2+1];
8675 9276
8676 for (int i = 0; i < mlen; i++) 9277 int i, j;
8677 active[i] = true; 9278 string d;
8678 9279
8679 offset[mlen] = srclen; 9280 m_host.AddScriptLPS(1);
8680 9281
8681 while (beginning < srclen) 9282 /*
9283 * Convert separator and spacer lists to C# strings.
9284 * Also filter out null strings so we don't hang.
9285 */
9286 for (i = 0; i < seplen; i ++)
8682 { 9287 {
9288 d = separray[i].ToString();
9289 if (d.Length > 0)
9290 {
9291 delarray[dellen++] = d;
9292 }
9293 }
9294 seplen = dellen;
8683 9295
8684 best = mlen; // as bad as it gets 9296 for (i = 0; i < spclen; i ++)
9297 {
9298 d = spcarray[i].ToString();
9299 if (d.Length > 0)
9300 {
9301 delarray[dellen++] = d;
9302 }
9303 }
8685 9304
8686 // Scan for separators 9305 /*
9306 * Scan through source string from beginning to end.
9307 */
9308 for (i = 0;;)
9309 {
8687 9310
8688 for (j = 0; j < seplen; j++) 9311 /*
9312 * Find earliest delimeter in src starting at i (if any).
9313 */
9314 int earliestDel = -1;
9315 int earliestSrc = srclen;
9316 string earliestStr = null;
9317 for (j = 0; j < dellen; j ++)
8689 { 9318 {
8690 if (separray[j].ToString() == String.Empty) 9319 d = delarray[j];
8691 active[j] = false; 9320 if (d != null)
8692
8693 if (active[j])
8694 { 9321 {
8695 // scan all of the markers 9322 int index = src.IndexOf(d, i);
8696 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9323 if (index < 0)
8697 { 9324 {
8698 // not present at all 9325 delarray[j] = null; // delim nowhere in src, don't check it anymore
8699 active[j] = false;
8700 } 9326 }
8701 else 9327 else if (index < earliestSrc)
8702 { 9328 {
8703 // present and correct 9329 earliestSrc = index; // where delimeter starts in source string
8704 if (offset[j] < offset[best]) 9330 earliestDel = j; // where delimeter is in delarray[]
8705 { 9331 earliestStr = d; // the delimeter string from delarray[]
8706 // closest so far 9332 if (index == i) break; // can't do any better than found at beg of string
8707 best = j;
8708 if (offset[best] == beginning)
8709 break;
8710 }
8711 } 9333 }
8712 } 9334 }
8713 } 9335 }
8714 9336
8715 // Scan for spacers 9337 /*
8716 9338 * Output source string starting at i through start of earliest delimeter.
8717 if (offset[best] != beginning) 9339 */
9340 if (keepNulls || (earliestSrc > i))
8718 { 9341 {
8719 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9342 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8720 {
8721 if (spcarray[j-seplen].ToString() == String.Empty)
8722 active[j] = false;
8723
8724 if (active[j])
8725 {
8726 // scan all of the markers
8727 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8728 {
8729 // not present at all
8730 active[j] = false;
8731 }
8732 else
8733 {
8734 // present and correct
8735 if (offset[j] < offset[best])
8736 {
8737 // closest so far
8738 best = j;
8739 }
8740 }
8741 }
8742 }
8743 } 9343 }
8744 9344
8745 // This is the normal exit from the scanning loop 9345 /*
9346 * If no delimeter found at or after i, we're done scanning.
9347 */
9348 if (earliestDel < 0) break;
8746 9349
8747 if (best == mlen) 9350 /*
9351 * If delimeter was a spacer, output the spacer.
9352 */
9353 if (earliestDel >= seplen)
8748 { 9354 {
8749 // no markers were found on this pass 9355 outarray[outlen++] = earliestStr;
8750 // so we're pretty much done
8751 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8752 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8753 break;
8754 } 9356 }
8755 9357
8756 // Otherwise we just add the newly delimited token 9358 /*
8757 // and recalculate where the search should continue. 9359 * Look at rest of src string following delimeter.
8758 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9360 */
8759 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9361 i = earliestSrc + earliestStr.Length;
8760
8761 if (best < seplen)
8762 {
8763 beginning = offset[best] + (separray[best].ToString()).Length;
8764 }
8765 else
8766 {
8767 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8768 string str = spcarray[best - seplen].ToString();
8769 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8770 tokens.Add(new LSL_String(str));
8771 }
8772 } 9362 }
8773 9363
8774 // This an awkward an not very intuitive boundary case. If the 9364 /*
8775 // last substring is a tokenizer, then there is an implied trailing 9365 * Make up an exact-sized output array suitable for an LSL_List object.
8776 // null list entry. Hopefully the single comparison will not be too 9366 */
8777 // arduous. Alternatively the 'break' could be replced with a return 9367 object[] outlist = new object[outlen];
8778 // but that's shabby programming. 9368 for (i = 0; i < outlen; i ++)
8779
8780 if ((beginning == srclen) && (keepNulls))
8781 { 9369 {
8782 if (srclen != 0) 9370 outlist[i] = new LSL_String(outarray[i]);
8783 tokens.Add(new LSL_String(""));
8784 } 9371 }
8785 9372 return new LSL_List(outlist);
8786 return tokens;
8787 }
8788
8789 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8790 {
8791 m_host.AddScriptLPS(1);
8792 return this.ParseString(src, separators, spacers, false);
8793 }
8794
8795 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8796 {
8797 m_host.AddScriptLPS(1);
8798 return this.ParseString(src, separators, spacers, true);
8799 } 9373 }
8800 9374
8801 public LSL_Integer llGetObjectPermMask(int mask) 9375 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8872,28 +9446,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8872 { 9446 {
8873 m_host.AddScriptLPS(1); 9447 m_host.AddScriptLPS(1);
8874 9448
8875 lock (m_host.TaskInventory) 9449 m_host.TaskInventory.LockItemsForRead(true);
9450 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8876 { 9451 {
8877 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9452 if (inv.Value.Name == item)
8878 { 9453 {
8879 if (inv.Value.Name == item) 9454 m_host.TaskInventory.LockItemsForRead(false);
9455 switch (mask)
8880 { 9456 {
8881 switch (mask) 9457 case 0:
8882 { 9458 return (int)inv.Value.BasePermissions;
8883 case 0: 9459 case 1:
8884 return (int)inv.Value.BasePermissions; 9460 return (int)inv.Value.CurrentPermissions;
8885 case 1: 9461 case 2:
8886 return (int)inv.Value.CurrentPermissions; 9462 return (int)inv.Value.GroupPermissions;
8887 case 2: 9463 case 3:
8888 return (int)inv.Value.GroupPermissions; 9464 return (int)inv.Value.EveryonePermissions;
8889 case 3: 9465 case 4:
8890 return (int)inv.Value.EveryonePermissions; 9466 return (int)inv.Value.NextPermissions;
8891 case 4:
8892 return (int)inv.Value.NextPermissions;
8893 }
8894 } 9467 }
8895 } 9468 }
8896 } 9469 }
9470 m_host.TaskInventory.LockItemsForRead(false);
8897 9471
8898 return -1; 9472 return -1;
8899 } 9473 }
@@ -8940,16 +9514,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8940 { 9514 {
8941 m_host.AddScriptLPS(1); 9515 m_host.AddScriptLPS(1);
8942 9516
8943 lock (m_host.TaskInventory) 9517 m_host.TaskInventory.LockItemsForRead(true);
9518 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8944 { 9519 {
8945 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9520 if (inv.Value.Name == item)
8946 { 9521 {
8947 if (inv.Value.Name == item) 9522 m_host.TaskInventory.LockItemsForRead(false);
8948 { 9523 return inv.Value.CreatorID.ToString();
8949 return inv.Value.CreatorID.ToString();
8950 }
8951 } 9524 }
8952 } 9525 }
9526 m_host.TaskInventory.LockItemsForRead(false);
8953 9527
8954 llSay(0, "No item name '" + item + "'"); 9528 llSay(0, "No item name '" + item + "'");
8955 9529
@@ -9097,7 +9671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9097 } 9671 }
9098 9672
9099 /// <summary> 9673 /// <summary>
9100 /// illListReplaceList removes the sub-list defined by the inclusive indices 9674 /// llListReplaceList removes the sub-list defined by the inclusive indices
9101 /// start and end and inserts the src list in its place. The inclusive 9675 /// start and end and inserts the src list in its place. The inclusive
9102 /// nature of the indices means that at least one element must be deleted 9676 /// nature of the indices means that at least one element must be deleted
9103 /// if the indices are within the bounds of the existing list. I.e. 2,2 9677 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9154,16 +9728,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9154 // based upon end. Note that if end exceeds the upper 9728 // based upon end. Note that if end exceeds the upper
9155 // bound in this case, the entire destination list 9729 // bound in this case, the entire destination list
9156 // is removed. 9730 // is removed.
9157 else 9731 else if (start == 0)
9158 { 9732 {
9159 if (end + 1 < dest.Length) 9733 if (end + 1 < dest.Length)
9160 {
9161 return src + dest.GetSublist(end + 1, -1); 9734 return src + dest.GetSublist(end + 1, -1);
9162 }
9163 else 9735 else
9164 {
9165 return src; 9736 return src;
9166 } 9737 }
9738 else // Start < 0
9739 {
9740 if (end + 1 < dest.Length)
9741 return dest.GetSublist(end + 1, -1);
9742 else
9743 return new LSL_List();
9167 } 9744 }
9168 } 9745 }
9169 // Finally, if start > end, we strip away a prefix and 9746 // Finally, if start > end, we strip away a prefix and
@@ -9214,17 +9791,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9214 int width = 0; 9791 int width = 0;
9215 int height = 0; 9792 int height = 0;
9216 9793
9217 ParcelMediaCommandEnum? commandToSend = null; 9794 uint commandToSend = 0;
9218 float time = 0.0f; // default is from start 9795 float time = 0.0f; // default is from start
9219 9796
9220 ScenePresence presence = null; 9797 ScenePresence presence = null;
9221 9798
9222 for (int i = 0; i < commandList.Data.Length; i++) 9799 for (int i = 0; i < commandList.Data.Length; i++)
9223 { 9800 {
9224 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9801 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9225 switch (command) 9802 switch (command)
9226 { 9803 {
9227 case ParcelMediaCommandEnum.Agent: 9804 case (uint)ParcelMediaCommandEnum.Agent:
9228 // we send only to one agent 9805 // we send only to one agent
9229 if ((i + 1) < commandList.Length) 9806 if ((i + 1) < commandList.Length)
9230 { 9807 {
@@ -9241,25 +9818,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9241 } 9818 }
9242 break; 9819 break;
9243 9820
9244 case ParcelMediaCommandEnum.Loop: 9821 case (uint)ParcelMediaCommandEnum.Loop:
9245 loop = 1; 9822 loop = 1;
9246 commandToSend = command; 9823 commandToSend = command;
9247 update = true; //need to send the media update packet to set looping 9824 update = true; //need to send the media update packet to set looping
9248 break; 9825 break;
9249 9826
9250 case ParcelMediaCommandEnum.Play: 9827 case (uint)ParcelMediaCommandEnum.Play:
9251 loop = 0; 9828 loop = 0;
9252 commandToSend = command; 9829 commandToSend = command;
9253 update = true; //need to send the media update packet to make sure it doesn't loop 9830 update = true; //need to send the media update packet to make sure it doesn't loop
9254 break; 9831 break;
9255 9832
9256 case ParcelMediaCommandEnum.Pause: 9833 case (uint)ParcelMediaCommandEnum.Pause:
9257 case ParcelMediaCommandEnum.Stop: 9834 case (uint)ParcelMediaCommandEnum.Stop:
9258 case ParcelMediaCommandEnum.Unload: 9835 case (uint)ParcelMediaCommandEnum.Unload:
9259 commandToSend = command; 9836 commandToSend = command;
9260 break; 9837 break;
9261 9838
9262 case ParcelMediaCommandEnum.Url: 9839 case (uint)ParcelMediaCommandEnum.Url:
9263 if ((i + 1) < commandList.Length) 9840 if ((i + 1) < commandList.Length)
9264 { 9841 {
9265 if (commandList.Data[i + 1] is LSL_String) 9842 if (commandList.Data[i + 1] is LSL_String)
@@ -9272,7 +9849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9272 } 9849 }
9273 break; 9850 break;
9274 9851
9275 case ParcelMediaCommandEnum.Texture: 9852 case (uint)ParcelMediaCommandEnum.Texture:
9276 if ((i + 1) < commandList.Length) 9853 if ((i + 1) < commandList.Length)
9277 { 9854 {
9278 if (commandList.Data[i + 1] is LSL_String) 9855 if (commandList.Data[i + 1] is LSL_String)
@@ -9285,7 +9862,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9285 } 9862 }
9286 break; 9863 break;
9287 9864
9288 case ParcelMediaCommandEnum.Time: 9865 case (uint)ParcelMediaCommandEnum.Time:
9289 if ((i + 1) < commandList.Length) 9866 if ((i + 1) < commandList.Length)
9290 { 9867 {
9291 if (commandList.Data[i + 1] is LSL_Float) 9868 if (commandList.Data[i + 1] is LSL_Float)
@@ -9297,7 +9874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9297 } 9874 }
9298 break; 9875 break;
9299 9876
9300 case ParcelMediaCommandEnum.AutoAlign: 9877 case (uint)ParcelMediaCommandEnum.AutoAlign:
9301 if ((i + 1) < commandList.Length) 9878 if ((i + 1) < commandList.Length)
9302 { 9879 {
9303 if (commandList.Data[i + 1] is LSL_Integer) 9880 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9311,7 +9888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9311 } 9888 }
9312 break; 9889 break;
9313 9890
9314 case ParcelMediaCommandEnum.Type: 9891 case (uint)ParcelMediaCommandEnum.Type:
9315 if ((i + 1) < commandList.Length) 9892 if ((i + 1) < commandList.Length)
9316 { 9893 {
9317 if (commandList.Data[i + 1] is LSL_String) 9894 if (commandList.Data[i + 1] is LSL_String)
@@ -9324,7 +9901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9324 } 9901 }
9325 break; 9902 break;
9326 9903
9327 case ParcelMediaCommandEnum.Desc: 9904 case (uint)ParcelMediaCommandEnum.Desc:
9328 if ((i + 1) < commandList.Length) 9905 if ((i + 1) < commandList.Length)
9329 { 9906 {
9330 if (commandList.Data[i + 1] is LSL_String) 9907 if (commandList.Data[i + 1] is LSL_String)
@@ -9337,7 +9914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9337 } 9914 }
9338 break; 9915 break;
9339 9916
9340 case ParcelMediaCommandEnum.Size: 9917 case (uint)ParcelMediaCommandEnum.Size:
9341 if ((i + 2) < commandList.Length) 9918 if ((i + 2) < commandList.Length)
9342 { 9919 {
9343 if (commandList.Data[i + 1] is LSL_Integer) 9920 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9407,7 +9984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9407 } 9984 }
9408 } 9985 }
9409 9986
9410 if (commandToSend != null) 9987 if (commandToSend != 0)
9411 { 9988 {
9412 // the commandList contained a start/stop/... command, too 9989 // the commandList contained a start/stop/... command, too
9413 if (presence == null) 9990 if (presence == null)
@@ -9444,7 +10021,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9444 10021
9445 if (aList.Data[i] != null) 10022 if (aList.Data[i] != null)
9446 { 10023 {
9447 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10024 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9448 { 10025 {
9449 case ParcelMediaCommandEnum.Url: 10026 case ParcelMediaCommandEnum.Url:
9450 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10027 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9487,16 +10064,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9487 { 10064 {
9488 m_host.AddScriptLPS(1); 10065 m_host.AddScriptLPS(1);
9489 10066
9490 lock (m_host.TaskInventory) 10067 m_host.TaskInventory.LockItemsForRead(true);
10068 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9491 { 10069 {
9492 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10070 if (inv.Value.Name == name)
9493 { 10071 {
9494 if (inv.Value.Name == name) 10072 m_host.TaskInventory.LockItemsForRead(false);
9495 { 10073 return inv.Value.Type;
9496 return inv.Value.Type;
9497 }
9498 } 10074 }
9499 } 10075 }
10076 m_host.TaskInventory.LockItemsForRead(false);
9500 10077
9501 return -1; 10078 return -1;
9502 } 10079 }
@@ -9507,15 +10084,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9507 10084
9508 if (quick_pay_buttons.Data.Length < 4) 10085 if (quick_pay_buttons.Data.Length < 4)
9509 { 10086 {
9510 LSLError("List must have at least 4 elements"); 10087 int x;
9511 return; 10088 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10089 {
10090 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10091 }
9512 } 10092 }
9513 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10093 int[] nPrice = new int[5];
9514 10094 nPrice[0] = price;
9515 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10095 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9516 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10096 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9517 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10097 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9518 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10098 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10099 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9519 m_host.ParentGroup.HasGroupChanged = true; 10100 m_host.ParentGroup.HasGroupChanged = true;
9520 } 10101 }
9521 10102
@@ -9527,17 +10108,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 if (invItemID == UUID.Zero) 10108 if (invItemID == UUID.Zero)
9528 return new LSL_Vector(); 10109 return new LSL_Vector();
9529 10110
9530 lock (m_host.TaskInventory) 10111 m_host.TaskInventory.LockItemsForRead(true);
10112 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9531 { 10113 {
9532 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10114 m_host.TaskInventory.LockItemsForRead(false);
9533 return new LSL_Vector(); 10115 return new LSL_Vector();
10116 }
9534 10117
9535 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10118 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9536 { 10119 {
9537 ShoutError("No permissions to track the camera"); 10120 ShoutError("No permissions to track the camera");
9538 return new LSL_Vector(); 10121 m_host.TaskInventory.LockItemsForRead(false);
9539 } 10122 return new LSL_Vector();
9540 } 10123 }
10124 m_host.TaskInventory.LockItemsForRead(false);
9541 10125
9542 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10126 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9543 if (presence != null) 10127 if (presence != null)
@@ -9555,17 +10139,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9555 if (invItemID == UUID.Zero) 10139 if (invItemID == UUID.Zero)
9556 return new LSL_Rotation(); 10140 return new LSL_Rotation();
9557 10141
9558 lock (m_host.TaskInventory) 10142 m_host.TaskInventory.LockItemsForRead(true);
10143 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9559 { 10144 {
9560 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10145 m_host.TaskInventory.LockItemsForRead(false);
9561 return new LSL_Rotation(); 10146 return new LSL_Rotation();
9562
9563 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9564 {
9565 ShoutError("No permissions to track the camera");
9566 return new LSL_Rotation();
9567 }
9568 } 10147 }
10148 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10149 {
10150 ShoutError("No permissions to track the camera");
10151 m_host.TaskInventory.LockItemsForRead(false);
10152 return new LSL_Rotation();
10153 }
10154 m_host.TaskInventory.LockItemsForRead(false);
9569 10155
9570 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10156 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9571 if (presence != null) 10157 if (presence != null)
@@ -9627,8 +10213,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 { 10213 {
9628 m_host.AddScriptLPS(1); 10214 m_host.AddScriptLPS(1);
9629 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10215 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9630 if (detectedParams == null) return; // only works on the first detected avatar 10216 if (detectedParams == null)
9631 10217 {
10218 if (m_host.ParentGroup.IsAttachment == true)
10219 {
10220 detectedParams = new DetectParams();
10221 detectedParams.Key = m_host.OwnerID;
10222 }
10223 else
10224 {
10225 return;
10226 }
10227 }
10228
9632 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10229 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9633 if (avatar != null) 10230 if (avatar != null)
9634 { 10231 {
@@ -9636,6 +10233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10233 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9637 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10234 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9638 } 10235 }
10236
9639 ScriptSleep(1000); 10237 ScriptSleep(1000);
9640 } 10238 }
9641 10239
@@ -9728,14 +10326,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9728 if (objectID == UUID.Zero) return; 10326 if (objectID == UUID.Zero) return;
9729 10327
9730 UUID agentID; 10328 UUID agentID;
9731 lock (m_host.TaskInventory) 10329 m_host.TaskInventory.LockItemsForRead(true);
9732 { 10330 // we need the permission first, to know which avatar we want to set the camera for
9733 // we need the permission first, to know which avatar we want to set the camera for 10331 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9734 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9735 10332
9736 if (agentID == UUID.Zero) return; 10333 if (agentID == UUID.Zero)
9737 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10334 {
10335 m_host.TaskInventory.LockItemsForRead(false);
10336 return;
10337 }
10338 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10339 {
10340 m_host.TaskInventory.LockItemsForRead(false);
10341 return;
9738 } 10342 }
10343 m_host.TaskInventory.LockItemsForRead(false);
9739 10344
9740 ScenePresence presence = World.GetScenePresence(agentID); 10345 ScenePresence presence = World.GetScenePresence(agentID);
9741 10346
@@ -9744,12 +10349,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9744 10349
9745 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10350 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9746 object[] data = rules.Data; 10351 object[] data = rules.Data;
9747 for (int i = 0; i < data.Length; ++i) { 10352 for (int i = 0; i < data.Length; ++i)
10353 {
9748 int type = Convert.ToInt32(data[i++].ToString()); 10354 int type = Convert.ToInt32(data[i++].ToString());
9749 if (i >= data.Length) break; // odd number of entries => ignore the last 10355 if (i >= data.Length) break; // odd number of entries => ignore the last
9750 10356
9751 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10357 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9752 switch (type) { 10358 switch (type)
10359 {
9753 case ScriptBaseClass.CAMERA_FOCUS: 10360 case ScriptBaseClass.CAMERA_FOCUS:
9754 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10361 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9755 case ScriptBaseClass.CAMERA_POSITION: 10362 case ScriptBaseClass.CAMERA_POSITION:
@@ -9785,12 +10392,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9785 10392
9786 // we need the permission first, to know which avatar we want to clear the camera for 10393 // we need the permission first, to know which avatar we want to clear the camera for
9787 UUID agentID; 10394 UUID agentID;
9788 lock (m_host.TaskInventory) 10395 m_host.TaskInventory.LockItemsForRead(true);
10396 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10397 if (agentID == UUID.Zero)
9789 { 10398 {
9790 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10399 m_host.TaskInventory.LockItemsForRead(false);
9791 if (agentID == UUID.Zero) return; 10400 return;
9792 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10401 }
10402 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10403 {
10404 m_host.TaskInventory.LockItemsForRead(false);
10405 return;
9793 } 10406 }
10407 m_host.TaskInventory.LockItemsForRead(false);
9794 10408
9795 ScenePresence presence = World.GetScenePresence(agentID); 10409 ScenePresence presence = World.GetScenePresence(agentID);
9796 10410
@@ -9857,19 +10471,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9857 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10471 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9858 { 10472 {
9859 m_host.AddScriptLPS(1); 10473 m_host.AddScriptLPS(1);
9860 string ret = String.Empty; 10474
9861 string src1 = llBase64ToString(str1); 10475 if (str1 == String.Empty)
9862 string src2 = llBase64ToString(str2); 10476 return String.Empty;
9863 int c = 0; 10477 if (str2 == String.Empty)
9864 for (int i = 0; i < src1.Length; i++) 10478 return str1;
10479
10480 int len = str2.Length;
10481 if ((len % 4) != 0) // LL is EVIL!!!!
9865 { 10482 {
9866 ret += (char) (src1[i] ^ src2[c]); 10483 while (str2.EndsWith("="))
10484 str2 = str2.Substring(0, str2.Length - 1);
10485
10486 len = str2.Length;
10487 int mod = len % 4;
10488
10489 if (mod == 1)
10490 str2 = str2.Substring(0, str2.Length - 1);
10491 else if (mod == 2)
10492 str2 += "==";
10493 else if (mod == 3)
10494 str2 += "=";
10495 }
9867 10496
9868 c++; 10497 byte[] data1;
9869 if (c >= src2.Length) 10498 byte[] data2;
9870 c = 0; 10499 try
10500 {
10501 data1 = Convert.FromBase64String(str1);
10502 data2 = Convert.FromBase64String(str2);
9871 } 10503 }
9872 return llStringToBase64(ret); 10504 catch (Exception)
10505 {
10506 return new LSL_String(String.Empty);
10507 }
10508
10509 byte[] d2 = new Byte[data1.Length];
10510 int pos = 0;
10511
10512 if (data1.Length <= data2.Length)
10513 {
10514 Array.Copy(data2, 0, d2, 0, data1.Length);
10515 }
10516 else
10517 {
10518 while (pos < data1.Length)
10519 {
10520 len = data1.Length - pos;
10521 if (len > data2.Length)
10522 len = data2.Length;
10523
10524 Array.Copy(data2, 0, d2, pos, len);
10525 pos += len;
10526 }
10527 }
10528
10529 for (pos = 0 ; pos < data1.Length ; pos++ )
10530 data1[pos] ^= d2[pos];
10531
10532 return Convert.ToBase64String(data1);
9873 } 10533 }
9874 10534
9875 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10535 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9926,12 +10586,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9926 Regex r = new Regex(authregex); 10586 Regex r = new Regex(authregex);
9927 int[] gnums = r.GetGroupNumbers(); 10587 int[] gnums = r.GetGroupNumbers();
9928 Match m = r.Match(url); 10588 Match m = r.Match(url);
9929 if (m.Success) { 10589 if (m.Success)
9930 for (int i = 1; i < gnums.Length; i++) { 10590 {
10591 for (int i = 1; i < gnums.Length; i++)
10592 {
9931 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10593 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9932 //CaptureCollection cc = g.Captures; 10594 //CaptureCollection cc = g.Captures;
9933 } 10595 }
9934 if (m.Groups.Count == 5) { 10596 if (m.Groups.Count == 5)
10597 {
9935 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10598 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9936 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10599 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9937 } 10600 }
@@ -10217,15 +10880,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10217 10880
10218 internal UUID ScriptByName(string name) 10881 internal UUID ScriptByName(string name)
10219 { 10882 {
10220 lock (m_host.TaskInventory) 10883 m_host.TaskInventory.LockItemsForRead(true);
10884
10885 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10221 { 10886 {
10222 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10887 if (item.Type == 10 && item.Name == name)
10223 { 10888 {
10224 if (item.Type == 10 && item.Name == name) 10889 m_host.TaskInventory.LockItemsForRead(false);
10225 return item.ItemID; 10890 return item.ItemID;
10226 } 10891 }
10227 } 10892 }
10228 10893
10894 m_host.TaskInventory.LockItemsForRead(false);
10895
10229 return UUID.Zero; 10896 return UUID.Zero;
10230 } 10897 }
10231 10898
@@ -10266,6 +10933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10266 { 10933 {
10267 m_host.AddScriptLPS(1); 10934 m_host.AddScriptLPS(1);
10268 10935
10936 //Clone is thread safe
10269 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10937 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10270 10938
10271 UUID assetID = UUID.Zero; 10939 UUID assetID = UUID.Zero;
@@ -10328,6 +10996,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10328 { 10996 {
10329 m_host.AddScriptLPS(1); 10997 m_host.AddScriptLPS(1);
10330 10998
10999 //Clone is thread safe
10331 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11000 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10332 11001
10333 UUID assetID = UUID.Zero; 11002 UUID assetID = UUID.Zero;
@@ -10408,15 +11077,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10408 return GetLinkPrimitiveParams(obj, rules); 11077 return GetLinkPrimitiveParams(obj, rules);
10409 } 11078 }
10410 11079
10411 public void print(string str) 11080 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10412 { 11081 {
10413 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11082 List<SceneObjectPart> parts = GetLinkParts(link);
10414 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11083 if (parts.Count < 1)
10415 if (ossl != null) 11084 return 0;
10416 { 11085
10417 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11086 return GetNumberOfSides(parts[0]);
10418 m_log.Info("LSL print():" + str);
10419 }
10420 } 11087 }
10421 11088
10422 private string Name2Username(string name) 11089 private string Name2Username(string name)
@@ -10462,6 +11129,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10462 return rq.ToString(); 11129 return rq.ToString();
10463 } 11130 }
10464 11131
11132 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11133 {
11134 m_SayShoutCount = 0;
11135 }
10465 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11136 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10466 { 11137 {
10467 m_host.AddScriptLPS(1); 11138 m_host.AddScriptLPS(1);
@@ -10631,22 +11302,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10631 NotImplemented("llGetSPMaxMemory"); 11302 NotImplemented("llGetSPMaxMemory");
10632 } 11303 }
10633 11304
10634 public void llGetUsedMemory() 11305 public virtual LSL_Integer llGetUsedMemory()
10635 { 11306 {
10636 m_host.AddScriptLPS(1); 11307 m_host.AddScriptLPS(1);
10637 NotImplemented("llGetUsedMemory"); 11308 NotImplemented("llGetUsedMemory");
11309 return 0;
10638 } 11310 }
10639 11311
10640 public void llScriptProfiler(LSL_Integer flags) 11312 public void llScriptProfiler(LSL_Integer flags)
10641 { 11313 {
10642 m_host.AddScriptLPS(1); 11314 m_host.AddScriptLPS(1);
10643 NotImplemented("llScriptProfiler"); 11315 //NotImplemented("llScriptProfiler");
10644 } 11316 }
10645 11317
10646 public void llSetSoundQueueing(int queue) 11318 public void llSetSoundQueueing(int queue)
10647 { 11319 {
10648 m_host.AddScriptLPS(1); 11320 m_host.AddScriptLPS(1);
10649 NotImplemented("llSetSoundQueueing");
10650 } 11321 }
10651 11322
10652 public void llCollisionSprite(string impact_sprite) 11323 public void llCollisionSprite(string impact_sprite)
@@ -10658,7 +11329,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10658 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11329 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10659 { 11330 {
10660 m_host.AddScriptLPS(1); 11331 m_host.AddScriptLPS(1);
10661 NotImplemented("llGodLikeRezObject"); 11332
11333 if (!World.Permissions.IsGod(m_host.OwnerID))
11334 NotImplemented("llGodLikeRezObject");
11335
11336 AssetBase rezAsset = World.AssetService.Get(inventory);
11337 if (rezAsset == null)
11338 {
11339 llSay(0, "Asset not found");
11340 return;
11341 }
11342
11343 SceneObjectGroup group = null;
11344
11345 try
11346 {
11347 string xmlData = Utils.BytesToString(rezAsset.Data);
11348 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11349 }
11350 catch
11351 {
11352 llSay(0, "Asset not found");
11353 return;
11354 }
11355
11356 if (group == null)
11357 {
11358 llSay(0, "Asset not found");
11359 return;
11360 }
11361
11362 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11363 group.RootPart.AttachOffset = group.AbsolutePosition;
11364
11365 group.ResetIDs();
11366
11367 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11368 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11369 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11370 group.ScheduleGroupForFullUpdate();
11371
11372 // objects rezzed with this method are die_at_edge by default.
11373 group.RootPart.SetDieAtEdge(true);
11374
11375 group.ResumeScripts();
11376
11377 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11378 "object_rez", new Object[] {
11379 new LSL_String(
11380 group.RootPart.UUID.ToString()) },
11381 new DetectParams[0]));
10662 } 11382 }
10663 11383
10664 #endregion 11384 #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 4ac7f8b..6de0773 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