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.cs2248
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs43
-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.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
19 files changed, 2108 insertions, 966 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 88e884d..bf791a9 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.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 {
@@ -1943,10 +2147,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1943 return end; 2147 return end;
1944 } 2148 }
1945 2149
1946 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2150 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1947 { 2151 {
2152 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2153 return fromPos;
2154
1948 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2155 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1949 LSL_Vector currentPos = GetPartLocalPos(part); 2156
1950 2157
1951 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2158 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1952 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2159 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1955,14 +2162,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1955 { 2162 {
1956 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2163 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1957 targetPos.z = ground; 2164 targetPos.z = ground;
2165 }
2166 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2167
2168 return real_vec;
2169 }
2170
2171 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2172 {
2173 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2174 return;
2175
2176 LSL_Vector currentPos = GetPartLocalPos(part);
2177 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2178
2179 if (part.ParentGroup.RootPart == part)
2180 {
1958 SceneObjectGroup parent = part.ParentGroup; 2181 SceneObjectGroup parent = part.ParentGroup;
1959 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2182 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1960 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1961 } 2183 }
1962 else 2184 else
1963 { 2185 {
1964 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2186 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1965 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1966 SceneObjectGroup parent = part.ParentGroup; 2187 SceneObjectGroup parent = part.ParentGroup;
1967 parent.HasGroupChanged = true; 2188 parent.HasGroupChanged = true;
1968 parent.ScheduleGroupForTerseUpdate(); 2189 parent.ScheduleGroupForTerseUpdate();
@@ -2013,9 +2234,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2013 m_host.AddScriptLPS(1); 2234 m_host.AddScriptLPS(1);
2014 2235
2015 // try to let this work as in SL... 2236 // try to let this work as in SL...
2016 if (m_host.ParentID == 0) 2237 if (m_host.LinkNum < 2)
2017 { 2238 {
2018 // special case: If we are root, rotate complete SOG to new rotation 2239 // Special case: If we are root, rotate complete SOG to new
2240 // rotation.
2241 // We are root if the link number is 0 (single prim) or 1
2242 // (root prim). ParentID may be nonzero in attachments and
2243 // using it would cause attachments and HUDs to rotate
2244 // to the wrong positions.
2019 SetRot(m_host, Rot2Quaternion(rot)); 2245 SetRot(m_host, Rot2Quaternion(rot));
2020 } 2246 }
2021 else 2247 else
@@ -2040,6 +2266,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2040 2266
2041 protected void SetRot(SceneObjectPart part, Quaternion rot) 2267 protected void SetRot(SceneObjectPart part, Quaternion rot)
2042 { 2268 {
2269 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2270 return;
2271
2043 part.UpdateRotation(rot); 2272 part.UpdateRotation(rot);
2044 // Update rotation does not move the object in the physics scene if it's a linkset. 2273 // Update rotation does not move the object in the physics scene if it's a linkset.
2045 2274
@@ -2665,12 +2894,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2665 2894
2666 m_host.AddScriptLPS(1); 2895 m_host.AddScriptLPS(1);
2667 2896
2897 m_host.TaskInventory.LockItemsForRead(true);
2668 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2898 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2669 2899 m_host.TaskInventory.LockItemsForRead(false);
2670 lock (m_host.TaskInventory)
2671 {
2672 item = m_host.TaskInventory[invItemID];
2673 }
2674 2900
2675 if (item.PermsGranter == UUID.Zero) 2901 if (item.PermsGranter == UUID.Zero)
2676 return 0; 2902 return 0;
@@ -2745,6 +2971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2745 if (dist > m_ScriptDistanceFactor * 10.0f) 2971 if (dist > m_ScriptDistanceFactor * 10.0f)
2746 return; 2972 return;
2747 2973
2974 //Clone is thread-safe
2748 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2975 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2749 2976
2750 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2977 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2805,6 +3032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2805 3032
2806 public void llLookAt(LSL_Vector target, double strength, double damping) 3033 public void llLookAt(LSL_Vector target, double strength, double damping)
2807 { 3034 {
3035 /*
2808 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
2809 // Determine where we are looking from 3037 // Determine where we are looking from
2810 LSL_Vector from = llGetPos(); 3038 LSL_Vector from = llGetPos();
@@ -2824,10 +3052,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 // the angles of rotation in radians into rotation value 3052 // the angles of rotation in radians into rotation value
2825 3053
2826 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3054 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2827 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3055
2828 m_host.startLookAt(rotation, (float)damping, (float)strength); 3056 // This would only work if your physics system contains an APID controller:
3057 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3058 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3059
2829 // Orient the object to the angle calculated 3060 // Orient the object to the angle calculated
2830 //llSetRot(rot); 3061 llSetRot(rot);
3062 */
3063
3064 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3065 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3066 // http://bugs.meta7.com/view.php?id=28
3067 // - Tom
3068
3069 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3070 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3071 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3072 */
3073 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3074 {
3075 // Part is non-phys, convert this to a llSetRot()
3076 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3077 Vector3 dir = tgt - m_host.GroupPosition;
3078 dir.Normalize();
3079 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3080 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3081 float terot = (float)Math.Atan2(-dir.Z, txy);
3082 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3083 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3084 LSL_Types.Quaternion spin = llEuler2Rot(az);
3085 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3086 llSetRot(rot);
3087 }
3088 else
3089 {
3090 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3091 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3092 m_host.RotLookAt(q, (float)strength, (float)damping);
3093 }
3094
3095 }
3096
3097 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3098 {
3099 m_host.AddScriptLPS(1);
3100// NotImplemented("llRotLookAt");
3101 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3102
2831 } 3103 }
2832 3104
2833 public void llStopLookAt() 3105 public void llStopLookAt()
@@ -2876,13 +3148,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2876 { 3148 {
2877 TaskInventoryItem item; 3149 TaskInventoryItem item;
2878 3150
2879 lock (m_host.TaskInventory) 3151 m_host.TaskInventory.LockItemsForRead(true);
3152 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2880 { 3153 {
2881 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3154 m_host.TaskInventory.LockItemsForRead(false);
2882 return; 3155 return;
2883 else
2884 item = m_host.TaskInventory[InventorySelf()];
2885 } 3156 }
3157 else
3158 {
3159 item = m_host.TaskInventory[InventorySelf()];
3160 }
3161 m_host.TaskInventory.LockItemsForRead(false);
2886 3162
2887 if (item.PermsGranter != UUID.Zero) 3163 if (item.PermsGranter != UUID.Zero)
2888 { 3164 {
@@ -2904,13 +3180,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2904 { 3180 {
2905 TaskInventoryItem item; 3181 TaskInventoryItem item;
2906 3182
3183 m_host.TaskInventory.LockItemsForRead(true);
2907 lock (m_host.TaskInventory) 3184 lock (m_host.TaskInventory)
2908 { 3185 {
3186
2909 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3187 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3188 {
3189 m_host.TaskInventory.LockItemsForRead(false);
2910 return; 3190 return;
3191 }
2911 else 3192 else
3193 {
2912 item = m_host.TaskInventory[InventorySelf()]; 3194 item = m_host.TaskInventory[InventorySelf()];
3195 }
2913 } 3196 }
3197 m_host.TaskInventory.LockItemsForRead(false);
2914 3198
2915 m_host.AddScriptLPS(1); 3199 m_host.AddScriptLPS(1);
2916 3200
@@ -2942,18 +3226,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2942 { 3226 {
2943 m_host.AddScriptLPS(1); 3227 m_host.AddScriptLPS(1);
2944 3228
2945// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2946// return;
2947
2948 TaskInventoryItem item; 3229 TaskInventoryItem item;
2949 3230
2950 lock (m_host.TaskInventory) 3231 m_host.TaskInventory.LockItemsForRead(true);
3232
3233 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2951 { 3234 {
2952 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3235 m_host.TaskInventory.LockItemsForRead(false);
2953 return; 3236 return;
2954 else
2955 item = m_host.TaskInventory[InventorySelf()];
2956 } 3237 }
3238 else
3239 {
3240 item = m_host.TaskInventory[InventorySelf()];
3241 }
3242
3243 m_host.TaskInventory.LockItemsForRead(false);
2957 3244
2958 if (item.PermsGranter != m_host.OwnerID) 3245 if (item.PermsGranter != m_host.OwnerID)
2959 return; 3246 return;
@@ -2964,10 +3251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2964 3251
2965 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3252 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2966 3253
2967 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3254 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2968 if (attachmentsModule != null)
2969 attachmentsModule.AttachObject(presence.ControllingClient,
2970 grp, (uint)attachment, false);
2971 } 3255 }
2972 } 3256 }
2973 3257
@@ -2980,13 +3264,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 3264
2981 TaskInventoryItem item; 3265 TaskInventoryItem item;
2982 3266
2983 lock (m_host.TaskInventory) 3267 m_host.TaskInventory.LockItemsForRead(true);
3268
3269 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2984 { 3270 {
2985 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3271 m_host.TaskInventory.LockItemsForRead(false);
2986 return; 3272 return;
2987 else
2988 item = m_host.TaskInventory[InventorySelf()];
2989 } 3273 }
3274 else
3275 {
3276 item = m_host.TaskInventory[InventorySelf()];
3277 }
3278 m_host.TaskInventory.LockItemsForRead(false);
3279
2990 3280
2991 if (item.PermsGranter != m_host.OwnerID) 3281 if (item.PermsGranter != m_host.OwnerID)
2992 return; 3282 return;
@@ -3033,6 +3323,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3033 3323
3034 public void llInstantMessage(string user, string message) 3324 public void llInstantMessage(string user, string message)
3035 { 3325 {
3326 UUID result;
3327 if (!UUID.TryParse(user, out result))
3328 {
3329 ShoutError("An invalid key was passed to llInstantMessage");
3330 ScriptSleep(2000);
3331 return;
3332 }
3333
3334
3036 m_host.AddScriptLPS(1); 3335 m_host.AddScriptLPS(1);
3037 3336
3038 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3337 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3047,14 +3346,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 UUID friendTransactionID = UUID.Random(); 3346 UUID friendTransactionID = UUID.Random();
3048 3347
3049 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3348 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3050 3349
3051 GridInstantMessage msg = new GridInstantMessage(); 3350 GridInstantMessage msg = new GridInstantMessage();
3052 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3351 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3053 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3352 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3054 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3353 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3055// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3354// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3056// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3355// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3057 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3356// DateTime dt = DateTime.UtcNow;
3357//
3358// // Ticks from UtcNow, but make it look like local. Evil, huh?
3359// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3360//
3361// try
3362// {
3363// // Convert that to the PST timezone
3364// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3365// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3366// }
3367// catch
3368// {
3369// // No logging here, as it could be VERY spammy
3370// }
3371//
3372// // And make it look local again to fool the unix time util
3373// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3374
3375 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3376
3058 //if (client != null) 3377 //if (client != null)
3059 //{ 3378 //{
3060 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3379 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3068,12 +3387,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3068 msg.message = message.Substring(0, 1024); 3387 msg.message = message.Substring(0, 1024);
3069 else 3388 else
3070 msg.message = message; 3389 msg.message = message;
3071 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3390 msg.dialog = (byte)19; // MessageFromObject
3072 msg.fromGroup = false;// fromGroup; 3391 msg.fromGroup = false;// fromGroup;
3073 msg.offline = (byte)0; //offline; 3392 msg.offline = (byte)0; //offline;
3074 msg.ParentEstateID = 0; //ParentEstateID; 3393 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3075 msg.Position = new Vector3(m_host.AbsolutePosition); 3394 msg.Position = new Vector3(m_host.AbsolutePosition);
3076 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3395 msg.RegionID = World.RegionInfo.RegionID.Guid;
3077 msg.binaryBucket 3396 msg.binaryBucket
3078 = Util.StringToBytes256( 3397 = Util.StringToBytes256(
3079 "{0}/{1}/{2}/{3}", 3398 "{0}/{1}/{2}/{3}",
@@ -3101,7 +3420,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 } 3420 }
3102 3421
3103 emailModule.SendEmail(m_host.UUID, address, subject, message); 3422 emailModule.SendEmail(m_host.UUID, address, subject, message);
3104 ScriptSleep(20000); 3423 ScriptSleep(15000);
3105 } 3424 }
3106 3425
3107 public void llGetNextEmail(string address, string subject) 3426 public void llGetNextEmail(string address, string subject)
@@ -3201,13 +3520,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3201 m_host.AddScriptLPS(1); 3520 m_host.AddScriptLPS(1);
3202 } 3521 }
3203 3522
3204 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3205 {
3206 m_host.AddScriptLPS(1);
3207 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3208 m_host.RotLookAt(rot, (float)strength, (float)damping);
3209 }
3210
3211 public LSL_Integer llStringLength(string str) 3523 public LSL_Integer llStringLength(string str)
3212 { 3524 {
3213 m_host.AddScriptLPS(1); 3525 m_host.AddScriptLPS(1);
@@ -3231,14 +3543,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3231 3543
3232 TaskInventoryItem item; 3544 TaskInventoryItem item;
3233 3545
3234 lock (m_host.TaskInventory) 3546 m_host.TaskInventory.LockItemsForRead(true);
3547 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3235 { 3548 {
3236 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3549 m_host.TaskInventory.LockItemsForRead(false);
3237 return; 3550 return;
3238 else
3239 item = m_host.TaskInventory[InventorySelf()];
3240 } 3551 }
3241 3552 else
3553 {
3554 item = m_host.TaskInventory[InventorySelf()];
3555 }
3556 m_host.TaskInventory.LockItemsForRead(false);
3242 if (item.PermsGranter == UUID.Zero) 3557 if (item.PermsGranter == UUID.Zero)
3243 return; 3558 return;
3244 3559
@@ -3268,13 +3583,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 3583
3269 TaskInventoryItem item; 3584 TaskInventoryItem item;
3270 3585
3271 lock (m_host.TaskInventory) 3586 m_host.TaskInventory.LockItemsForRead(true);
3587 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3272 { 3588 {
3273 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3589 m_host.TaskInventory.LockItemsForRead(false);
3274 return; 3590 return;
3275 else
3276 item = m_host.TaskInventory[InventorySelf()];
3277 } 3591 }
3592 else
3593 {
3594 item = m_host.TaskInventory[InventorySelf()];
3595 }
3596 m_host.TaskInventory.LockItemsForRead(false);
3597
3278 3598
3279 if (item.PermsGranter == UUID.Zero) 3599 if (item.PermsGranter == UUID.Zero)
3280 return; 3600 return;
@@ -3339,10 +3659,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3339 3659
3340 TaskInventoryItem item; 3660 TaskInventoryItem item;
3341 3661
3342 lock (m_host.TaskInventory) 3662
3663 m_host.TaskInventory.LockItemsForRead(true);
3664 if (!m_host.TaskInventory.ContainsKey(invItemID))
3665 {
3666 m_host.TaskInventory.LockItemsForRead(false);
3667 return;
3668 }
3669 else
3343 { 3670 {
3344 item = m_host.TaskInventory[invItemID]; 3671 item = m_host.TaskInventory[invItemID];
3345 } 3672 }
3673 m_host.TaskInventory.LockItemsForRead(false);
3346 3674
3347 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3675 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3348 { 3676 {
@@ -3370,15 +3698,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3370 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3698 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3371 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3699 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3372 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3700 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3701 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3373 ScriptBaseClass.PERMISSION_ATTACH; 3702 ScriptBaseClass.PERMISSION_ATTACH;
3374 3703
3375 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3704 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3376 { 3705 {
3377 lock (m_host.TaskInventory) 3706 m_host.TaskInventory.LockItemsForWrite(true);
3378 { 3707 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3379 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3708 m_host.TaskInventory[invItemID].PermsMask = perm;
3380 m_host.TaskInventory[invItemID].PermsMask = perm; 3709 m_host.TaskInventory.LockItemsForWrite(false);
3381 }
3382 3710
3383 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3711 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3384 "run_time_permissions", new Object[] { 3712 "run_time_permissions", new Object[] {
@@ -3388,28 +3716,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3388 return; 3716 return;
3389 } 3717 }
3390 } 3718 }
3391 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3719 else
3392 { 3720 {
3393 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3721 bool sitting = false;
3394 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3722 if (m_host.SitTargetAvatar == agentID)
3395 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3723 {
3396 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3724 sitting = true;
3397 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3725 }
3726 else
3727 {
3728 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3729 {
3730 if (p.SitTargetAvatar == agentID)
3731 sitting = true;
3732 }
3733 }
3398 3734
3399 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3735 if (sitting)
3400 { 3736 {
3401 lock (m_host.TaskInventory) 3737 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3738 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3739 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3740 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3741 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3742
3743 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3402 { 3744 {
3745 m_host.TaskInventory.LockItemsForWrite(true);
3403 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3746 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3404 m_host.TaskInventory[invItemID].PermsMask = perm; 3747 m_host.TaskInventory[invItemID].PermsMask = perm;
3405 } 3748 m_host.TaskInventory.LockItemsForWrite(false);
3406 3749
3407 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3750 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3408 "run_time_permissions", new Object[] { 3751 "run_time_permissions", new Object[] {
3409 new LSL_Integer(perm) }, 3752 new LSL_Integer(perm) },
3410 new DetectParams[0])); 3753 new DetectParams[0]));
3411 3754
3412 return; 3755 return;
3756 }
3413 } 3757 }
3414 } 3758 }
3415 3759
@@ -3423,11 +3767,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3423 3767
3424 if (!m_waitingForScriptAnswer) 3768 if (!m_waitingForScriptAnswer)
3425 { 3769 {
3426 lock (m_host.TaskInventory) 3770 m_host.TaskInventory.LockItemsForWrite(true);
3427 { 3771 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3428 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3772 m_host.TaskInventory[invItemID].PermsMask = 0;
3429 m_host.TaskInventory[invItemID].PermsMask = 0; 3773 m_host.TaskInventory.LockItemsForWrite(false);
3430 }
3431 3774
3432 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3775 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3433 m_waitingForScriptAnswer=true; 3776 m_waitingForScriptAnswer=true;
@@ -3462,10 +3805,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3805 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3463 llReleaseControls(); 3806 llReleaseControls();
3464 3807
3465 lock (m_host.TaskInventory) 3808
3466 { 3809 m_host.TaskInventory.LockItemsForWrite(true);
3467 m_host.TaskInventory[invItemID].PermsMask = answer; 3810 m_host.TaskInventory[invItemID].PermsMask = answer;
3468 } 3811 m_host.TaskInventory.LockItemsForWrite(false);
3812
3469 3813
3470 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3814 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3471 "run_time_permissions", new Object[] { 3815 "run_time_permissions", new Object[] {
@@ -3477,16 +3821,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3477 { 3821 {
3478 m_host.AddScriptLPS(1); 3822 m_host.AddScriptLPS(1);
3479 3823
3480 lock (m_host.TaskInventory) 3824 m_host.TaskInventory.LockItemsForRead(true);
3825
3826 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3481 { 3827 {
3482 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3828 if (item.Type == 10 && item.ItemID == m_itemID)
3483 { 3829 {
3484 if (item.Type == 10 && item.ItemID == m_itemID) 3830 m_host.TaskInventory.LockItemsForRead(false);
3485 { 3831 return item.PermsGranter.ToString();
3486 return item.PermsGranter.ToString();
3487 }
3488 } 3832 }
3489 } 3833 }
3834 m_host.TaskInventory.LockItemsForRead(false);
3490 3835
3491 return UUID.Zero.ToString(); 3836 return UUID.Zero.ToString();
3492 } 3837 }
@@ -3495,19 +3840,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3495 { 3840 {
3496 m_host.AddScriptLPS(1); 3841 m_host.AddScriptLPS(1);
3497 3842
3498 lock (m_host.TaskInventory) 3843 m_host.TaskInventory.LockItemsForRead(true);
3844
3845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3499 { 3846 {
3500 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3847 if (item.Type == 10 && item.ItemID == m_itemID)
3501 { 3848 {
3502 if (item.Type == 10 && item.ItemID == m_itemID) 3849 int perms = item.PermsMask;
3503 { 3850 if (m_automaticLinkPermission)
3504 int perms = item.PermsMask; 3851 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3505 if (m_automaticLinkPermission) 3852 m_host.TaskInventory.LockItemsForRead(false);
3506 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3853 return perms;
3507 return perms;
3508 }
3509 } 3854 }
3510 } 3855 }
3856 m_host.TaskInventory.LockItemsForRead(false);
3511 3857
3512 return 0; 3858 return 0;
3513 } 3859 }
@@ -3529,9 +3875,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3529 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3875 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3530 { 3876 {
3531 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3877 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3532 3878 if (parts.Count > 0)
3533 foreach (SceneObjectPart part in parts) 3879 {
3534 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3880 try
3881 {
3882 parts[0].ParentGroup.areUpdatesSuspended = true;
3883 foreach (SceneObjectPart part in parts)
3884 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3885 }
3886 finally
3887 {
3888 parts[0].ParentGroup.areUpdatesSuspended = false;
3889 }
3890 }
3535 } 3891 }
3536 3892
3537 public void llCreateLink(string target, int parent) 3893 public void llCreateLink(string target, int parent)
@@ -3544,11 +3900,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3544 return; 3900 return;
3545 3901
3546 TaskInventoryItem item; 3902 TaskInventoryItem item;
3547 lock (m_host.TaskInventory) 3903 m_host.TaskInventory.LockItemsForRead(true);
3548 { 3904 item = m_host.TaskInventory[invItemID];
3549 item = m_host.TaskInventory[invItemID]; 3905 m_host.TaskInventory.LockItemsForRead(false);
3550 } 3906
3551
3552 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3907 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3553 && !m_automaticLinkPermission) 3908 && !m_automaticLinkPermission)
3554 { 3909 {
@@ -3565,11 +3920,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3565 3920
3566 if (targetPart.ParentGroup.AttachmentPoint != 0) 3921 if (targetPart.ParentGroup.AttachmentPoint != 0)
3567 return; // Fail silently if attached 3922 return; // Fail silently if attached
3923
3924 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3925 return;
3926
3568 SceneObjectGroup parentPrim = null, childPrim = null; 3927 SceneObjectGroup parentPrim = null, childPrim = null;
3569 3928
3570 if (targetPart != null) 3929 if (targetPart != null)
3571 { 3930 {
3572 if (parent != 0) { 3931 if (parent != 0)
3932 {
3573 parentPrim = m_host.ParentGroup; 3933 parentPrim = m_host.ParentGroup;
3574 childPrim = targetPart.ParentGroup; 3934 childPrim = targetPart.ParentGroup;
3575 } 3935 }
@@ -3601,16 +3961,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3601 m_host.AddScriptLPS(1); 3961 m_host.AddScriptLPS(1);
3602 UUID invItemID = InventorySelf(); 3962 UUID invItemID = InventorySelf();
3603 3963
3604 lock (m_host.TaskInventory) 3964 m_host.TaskInventory.LockItemsForRead(true);
3605 {
3606 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3965 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3607 && !m_automaticLinkPermission) 3966 && !m_automaticLinkPermission)
3608 { 3967 {
3609 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3968 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3969 m_host.TaskInventory.LockItemsForRead(false);
3610 return; 3970 return;
3611 } 3971 }
3612 } 3972 m_host.TaskInventory.LockItemsForRead(false);
3613 3973
3614 if (linknum < ScriptBaseClass.LINK_THIS) 3974 if (linknum < ScriptBaseClass.LINK_THIS)
3615 return; 3975 return;
3616 3976
@@ -3649,10 +4009,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3649 // Restructuring Multiple Prims. 4009 // Restructuring Multiple Prims.
3650 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4010 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3651 parts.Remove(parentPrim.RootPart); 4011 parts.Remove(parentPrim.RootPart);
3652 foreach (SceneObjectPart part in parts) 4012 if (parts.Count > 0)
3653 { 4013 {
3654 parentPrim.DelinkFromGroup(part.LocalId, true); 4014 try
4015 {
4016 parts[0].ParentGroup.areUpdatesSuspended = true;
4017 foreach (SceneObjectPart part in parts)
4018 {
4019 parentPrim.DelinkFromGroup(part.LocalId, true);
4020 }
4021 }
4022 finally
4023 {
4024 parts[0].ParentGroup.areUpdatesSuspended = false;
4025 }
3655 } 4026 }
4027
3656 parentPrim.HasGroupChanged = true; 4028 parentPrim.HasGroupChanged = true;
3657 parentPrim.ScheduleGroupForFullUpdate(); 4029 parentPrim.ScheduleGroupForFullUpdate();
3658 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4030 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3661,11 +4033,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 { 4033 {
3662 SceneObjectPart newRoot = parts[0]; 4034 SceneObjectPart newRoot = parts[0];
3663 parts.Remove(newRoot); 4035 parts.Remove(newRoot);
3664 foreach (SceneObjectPart part in parts) 4036
4037 try
3665 { 4038 {
3666 part.UpdateFlag = 0; 4039 parts[0].ParentGroup.areUpdatesSuspended = true;
3667 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4040 foreach (SceneObjectPart part in parts)
4041 {
4042 part.UpdateFlag = 0;
4043 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4044 }
3668 } 4045 }
4046 finally
4047 {
4048 parts[0].ParentGroup.areUpdatesSuspended = false;
4049 }
4050
4051
3669 newRoot.ParentGroup.HasGroupChanged = true; 4052 newRoot.ParentGroup.HasGroupChanged = true;
3670 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4053 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3671 } 4054 }
@@ -3685,6 +4068,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 public void llBreakAllLinks() 4068 public void llBreakAllLinks()
3686 { 4069 {
3687 m_host.AddScriptLPS(1); 4070 m_host.AddScriptLPS(1);
4071
4072 UUID invItemID = InventorySelf();
4073
4074 TaskInventoryItem item;
4075 m_host.TaskInventory.LockItemsForRead(true);
4076 item = m_host.TaskInventory[invItemID];
4077 m_host.TaskInventory.LockItemsForRead(false);
4078
4079 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4080 && !m_automaticLinkPermission)
4081 {
4082 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4083 return;
4084 }
4085
3688 SceneObjectGroup parentPrim = m_host.ParentGroup; 4086 SceneObjectGroup parentPrim = m_host.ParentGroup;
3689 if (parentPrim.AttachmentPoint != 0) 4087 if (parentPrim.AttachmentPoint != 0)
3690 return; // Fail silently if attached 4088 return; // Fail silently if attached
@@ -3711,6 +4109,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3711 } 4109 }
3712 else 4110 else
3713 { 4111 {
4112 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4113 {
4114 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4115
4116 if (linknum < 0)
4117 return UUID.Zero.ToString();
4118
4119 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4120 if (avatars.Count > linknum)
4121 {
4122 return avatars[linknum].UUID.ToString();
4123 }
4124 }
3714 return UUID.Zero.ToString(); 4125 return UUID.Zero.ToString();
3715 } 4126 }
3716 } 4127 }
@@ -3787,17 +4198,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3787 m_host.AddScriptLPS(1); 4198 m_host.AddScriptLPS(1);
3788 int count = 0; 4199 int count = 0;
3789 4200
3790 lock (m_host.TaskInventory) 4201 m_host.TaskInventory.LockItemsForRead(true);
4202 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3791 { 4203 {
3792 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4204 if (inv.Value.Type == type || type == -1)
3793 { 4205 {
3794 if (inv.Value.Type == type || type == -1) 4206 count = count + 1;
3795 {
3796 count = count + 1;
3797 }
3798 } 4207 }
3799 } 4208 }
3800 4209
4210 m_host.TaskInventory.LockItemsForRead(false);
3801 return count; 4211 return count;
3802 } 4212 }
3803 4213
@@ -3806,16 +4216,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3806 m_host.AddScriptLPS(1); 4216 m_host.AddScriptLPS(1);
3807 ArrayList keys = new ArrayList(); 4217 ArrayList keys = new ArrayList();
3808 4218
3809 lock (m_host.TaskInventory) 4219 m_host.TaskInventory.LockItemsForRead(true);
4220 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3810 { 4221 {
3811 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4222 if (inv.Value.Type == type || type == -1)
3812 { 4223 {
3813 if (inv.Value.Type == type || type == -1) 4224 keys.Add(inv.Value.Name);
3814 {
3815 keys.Add(inv.Value.Name);
3816 }
3817 } 4225 }
3818 } 4226 }
4227 m_host.TaskInventory.LockItemsForRead(false);
3819 4228
3820 if (keys.Count == 0) 4229 if (keys.Count == 0)
3821 { 4230 {
@@ -3852,25 +4261,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3852 } 4261 }
3853 4262
3854 // move the first object found with this inventory name 4263 // move the first object found with this inventory name
3855 lock (m_host.TaskInventory) 4264 m_host.TaskInventory.LockItemsForRead(true);
4265 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3856 { 4266 {
3857 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4267 if (inv.Value.Name == inventory)
3858 { 4268 {
3859 if (inv.Value.Name == inventory) 4269 found = true;
3860 { 4270 objId = inv.Key;
3861 found = true; 4271 assetType = inv.Value.Type;
3862 objId = inv.Key; 4272 objName = inv.Value.Name;
3863 assetType = inv.Value.Type; 4273 break;
3864 objName = inv.Value.Name;
3865 break;
3866 }
3867 } 4274 }
3868 } 4275 }
4276 m_host.TaskInventory.LockItemsForRead(false);
3869 4277
3870 if (!found) 4278 if (!found)
3871 { 4279 {
3872 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3873 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3874 } 4283 }
3875 4284
3876 // check if destination is an object 4285 // check if destination is an object
@@ -3896,6 +4305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 return; 4305 return;
3897 } 4306 }
3898 } 4307 }
4308
3899 // destination is an avatar 4309 // destination is an avatar
3900 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4310 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3901 4311
@@ -3918,26 +4328,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3918 bucket); 4328 bucket);
3919 if (m_TransferModule != null) 4329 if (m_TransferModule != null)
3920 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4330 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4331
4332 //This delay should only occur when giving inventory to avatars.
3921 ScriptSleep(3000); 4333 ScriptSleep(3000);
3922 } 4334 }
3923 } 4335 }
3924 4336
4337 [DebuggerNonUserCode]
3925 public void llRemoveInventory(string name) 4338 public void llRemoveInventory(string name)
3926 { 4339 {
3927 m_host.AddScriptLPS(1); 4340 m_host.AddScriptLPS(1);
3928 4341
3929 lock (m_host.TaskInventory) 4342 List<TaskInventoryItem> inv;
4343 try
3930 { 4344 {
3931 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4345 m_host.TaskInventory.LockItemsForRead(true);
4346 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4347 }
4348 finally
4349 {
4350 m_host.TaskInventory.LockItemsForRead(false);
4351 }
4352 foreach (TaskInventoryItem item in inv)
4353 {
4354 if (item.Name == name)
3932 { 4355 {
3933 if (item.Name == name) 4356 if (item.ItemID == m_itemID)
3934 { 4357 throw new ScriptDeleteException();
3935 if (item.ItemID == m_itemID) 4358 else
3936 throw new ScriptDeleteException(); 4359 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3937 else 4360 return;
3938 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3939 return;
3940 }
3941 } 4361 }
3942 } 4362 }
3943 } 4363 }
@@ -3972,112 +4392,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 { 4392 {
3973 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
3974 4394
3975 UUID uuid = (UUID)id; 4395 UUID uuid;
3976 PresenceInfo pinfo = null; 4396 if (UUID.TryParse(id, out uuid))
3977 UserAccount account;
3978
3979 UserInfoCacheEntry ce;
3980 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3981 { 4397 {
3982 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4398 PresenceInfo pinfo = null;
3983 if (account == null) 4399 UserAccount account;
4400
4401 UserInfoCacheEntry ce;
4402 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3984 { 4403 {
3985 m_userInfoCache[uuid] = null; // Cache negative 4404 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3986 return UUID.Zero.ToString(); 4405 if (account == null)
3987 } 4406 {
4407 m_userInfoCache[uuid] = null; // Cache negative
4408 return UUID.Zero.ToString();
4409 }
3988 4410
3989 4411
3990 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4412 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3991 if (pinfos != null && pinfos.Length > 0) 4413 if (pinfos != null && pinfos.Length > 0)
3992 {
3993 foreach (PresenceInfo p in pinfos)
3994 { 4414 {
3995 if (p.RegionID != UUID.Zero) 4415 foreach (PresenceInfo p in pinfos)
3996 { 4416 {
3997 pinfo = p; 4417 if (p.RegionID != UUID.Zero)
4418 {
4419 pinfo = p;
4420 }
3998 } 4421 }
3999 } 4422 }
4000 }
4001 4423
4002 ce = new UserInfoCacheEntry(); 4424 ce = new UserInfoCacheEntry();
4003 ce.time = Util.EnvironmentTickCount(); 4425 ce.time = Util.EnvironmentTickCount();
4004 ce.account = account; 4426 ce.account = account;
4005 ce.pinfo = pinfo; 4427 ce.pinfo = pinfo;
4006 } 4428 m_userInfoCache[uuid] = ce;
4007 else 4429 }
4008 { 4430 else
4009 if (ce == null) 4431 {
4010 return UUID.Zero.ToString(); 4432 if (ce == null)
4433 return UUID.Zero.ToString();
4011 4434
4012 account = ce.account; 4435 account = ce.account;
4013 pinfo = ce.pinfo; 4436 pinfo = ce.pinfo;
4014 } 4437 }
4015 4438
4016 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4439 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4017 {
4018 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4019 if (pinfos != null && pinfos.Length > 0)
4020 { 4440 {
4021 foreach (PresenceInfo p in pinfos) 4441 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4442 if (pinfos != null && pinfos.Length > 0)
4022 { 4443 {
4023 if (p.RegionID != UUID.Zero) 4444 foreach (PresenceInfo p in pinfos)
4024 { 4445 {
4025 pinfo = p; 4446 if (p.RegionID != UUID.Zero)
4447 {
4448 pinfo = p;
4449 }
4026 } 4450 }
4027 } 4451 }
4028 } 4452 else
4029 else 4453 pinfo = null;
4030 pinfo = null;
4031 4454
4032 ce.time = Util.EnvironmentTickCount(); 4455 ce.time = Util.EnvironmentTickCount();
4033 ce.pinfo = pinfo; 4456 ce.pinfo = pinfo;
4034 } 4457 }
4035 4458
4036 string reply = String.Empty; 4459 string reply = String.Empty;
4037 4460
4038 switch (data) 4461 switch (data)
4039 { 4462 {
4040 case 1: // DATA_ONLINE (0|1) 4463 case 1: // DATA_ONLINE (0|1)
4041 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4464 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4042 reply = "1"; 4465 reply = "1";
4043 else 4466 else
4044 reply = "0"; 4467 reply = "0";
4045 break; 4468 break;
4046 case 2: // DATA_NAME (First Last) 4469 case 2: // DATA_NAME (First Last)
4047 reply = account.FirstName + " " + account.LastName; 4470 reply = account.FirstName + " " + account.LastName;
4048 break; 4471 break;
4049 case 3: // DATA_BORN (YYYY-MM-DD) 4472 case 3: // DATA_BORN (YYYY-MM-DD)
4050 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4473 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4051 born = born.AddSeconds(account.Created); 4474 born = born.AddSeconds(account.Created);
4052 reply = born.ToString("yyyy-MM-dd"); 4475 reply = born.ToString("yyyy-MM-dd");
4053 break; 4476 break;
4054 case 4: // DATA_RATING (0,0,0,0,0,0) 4477 case 4: // DATA_RATING (0,0,0,0,0,0)
4055 reply = "0,0,0,0,0,0"; 4478 reply = "0,0,0,0,0,0";
4056 break; 4479 break;
4057 case 8: // DATA_PAYINFO (0|1|2|3) 4480 case 8: // DATA_PAYINFO (0|1|2|3)
4058 reply = "0"; 4481 reply = "0";
4059 break; 4482 break;
4060 default: 4483 default:
4061 return UUID.Zero.ToString(); // Raise no event 4484 return UUID.Zero.ToString(); // Raise no event
4062 } 4485 }
4063 4486
4064 UUID rq = UUID.Random(); 4487 UUID rq = UUID.Random();
4065 4488
4066 UUID tid = AsyncCommands. 4489 UUID tid = AsyncCommands.
4067 DataserverPlugin.RegisterRequest(m_localID, 4490 DataserverPlugin.RegisterRequest(m_localID,
4068 m_itemID, rq.ToString()); 4491 m_itemID, rq.ToString());
4069 4492
4070 AsyncCommands. 4493 AsyncCommands.
4071 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4494 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4072 4495
4073 ScriptSleep(100); 4496 ScriptSleep(100);
4074 return tid.ToString(); 4497 return tid.ToString();
4498 }
4499 else
4500 {
4501 ShoutError("Invalid UUID passed to llRequestAgentData.");
4502 }
4503 return "";
4075 } 4504 }
4076 4505
4077 public LSL_String llRequestInventoryData(string name) 4506 public LSL_String llRequestInventoryData(string name)
4078 { 4507 {
4079 m_host.AddScriptLPS(1); 4508 m_host.AddScriptLPS(1);
4080 4509
4510 //Clone is thread safe
4081 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4511 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4082 4512
4083 foreach (TaskInventoryItem item in itemDictionary.Values) 4513 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4131,6 +4561,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4131 ScenePresence presence = World.GetScenePresence(agentId); 4561 ScenePresence presence = World.GetScenePresence(agentId);
4132 if (presence != null) 4562 if (presence != null)
4133 { 4563 {
4564 // agent must not be a god
4565 if (presence.UserLevel >= 200) return;
4566
4134 // agent must be over the owners land 4567 // agent must be over the owners land
4135 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4568 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4136 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4569 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4153,7 +4586,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4153 UUID av = new UUID(); 4586 UUID av = new UUID();
4154 if (!UUID.TryParse(agent,out av)) 4587 if (!UUID.TryParse(agent,out av))
4155 { 4588 {
4156 LSLError("First parameter to llDialog needs to be a key"); 4589 //LSLError("First parameter to llDialog needs to be a key");
4157 return; 4590 return;
4158 } 4591 }
4159 4592
@@ -4190,17 +4623,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4190 UUID soundId = UUID.Zero; 4623 UUID soundId = UUID.Zero;
4191 if (!UUID.TryParse(impact_sound, out soundId)) 4624 if (!UUID.TryParse(impact_sound, out soundId))
4192 { 4625 {
4193 lock (m_host.TaskInventory) 4626 m_host.TaskInventory.LockItemsForRead(true);
4627 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4194 { 4628 {
4195 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4629 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4196 { 4630 {
4197 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4631 soundId = item.AssetID;
4198 { 4632 break;
4199 soundId = item.AssetID;
4200 break;
4201 }
4202 } 4633 }
4203 } 4634 }
4635 m_host.TaskInventory.LockItemsForRead(false);
4204 } 4636 }
4205 m_host.CollisionSound = soundId; 4637 m_host.CollisionSound = soundId;
4206 m_host.CollisionSoundVolume = (float)impact_volume; 4638 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4240,6 +4672,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4240 UUID partItemID; 4672 UUID partItemID;
4241 foreach (SceneObjectPart part in parts) 4673 foreach (SceneObjectPart part in parts)
4242 { 4674 {
4675 //Clone is thread safe
4243 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4676 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4244 4677
4245 foreach (TaskInventoryItem item in itemsDictionary.Values) 4678 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4454,17 +4887,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4454 4887
4455 m_host.AddScriptLPS(1); 4888 m_host.AddScriptLPS(1);
4456 4889
4457 lock (m_host.TaskInventory) 4890 m_host.TaskInventory.LockItemsForRead(true);
4891 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4458 { 4892 {
4459 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4893 if (item.Type == 10 && item.ItemID == m_itemID)
4460 { 4894 {
4461 if (item.Type == 10 && item.ItemID == m_itemID) 4895 result = item.Name!=null?item.Name:String.Empty;
4462 { 4896 break;
4463 result = item.Name != null ? item.Name : String.Empty;
4464 break;
4465 }
4466 } 4897 }
4467 } 4898 }
4899 m_host.TaskInventory.LockItemsForRead(false);
4468 4900
4469 return result; 4901 return result;
4470 } 4902 }
@@ -4633,23 +5065,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4633 { 5065 {
4634 m_host.AddScriptLPS(1); 5066 m_host.AddScriptLPS(1);
4635 5067
4636 lock (m_host.TaskInventory) 5068 m_host.TaskInventory.LockItemsForRead(true);
5069 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4637 { 5070 {
4638 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5071 if (inv.Value.Name == name)
4639 { 5072 {
4640 if (inv.Value.Name == name) 5073 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4641 { 5074 {
4642 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5075 m_host.TaskInventory.LockItemsForRead(false);
4643 { 5076 return inv.Value.AssetID.ToString();
4644 return inv.Value.AssetID.ToString(); 5077 }
4645 } 5078 else
4646 else 5079 {
4647 { 5080 m_host.TaskInventory.LockItemsForRead(false);
4648 return UUID.Zero.ToString(); 5081 return UUID.Zero.ToString();
4649 }
4650 } 5082 }
4651 } 5083 }
4652 } 5084 }
5085 m_host.TaskInventory.LockItemsForRead(false);
4653 5086
4654 return UUID.Zero.ToString(); 5087 return UUID.Zero.ToString();
4655 } 5088 }
@@ -4802,14 +5235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4802 { 5235 {
4803 m_host.AddScriptLPS(1); 5236 m_host.AddScriptLPS(1);
4804 5237
4805 if (src == null) 5238 return src.Length;
4806 {
4807 return 0;
4808 }
4809 else
4810 {
4811 return src.Length;
4812 }
4813 } 5239 }
4814 5240
4815 public LSL_Integer llList2Integer(LSL_List src, int index) 5241 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4855,7 +5281,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4855 else if (src.Data[index] is LSL_Float) 5281 else if (src.Data[index] is LSL_Float)
4856 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5282 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4857 else if (src.Data[index] is LSL_String) 5283 else if (src.Data[index] is LSL_String)
4858 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5284 {
5285 string str = ((LSL_String) src.Data[index]).m_string;
5286 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5287 if (m != Match.Empty)
5288 {
5289 str = m.Value;
5290 double d = 0.0;
5291 if (!Double.TryParse(str, out d))
5292 return 0.0;
5293
5294 return d;
5295 }
5296 return 0.0;
5297 }
4859 return Convert.ToDouble(src.Data[index]); 5298 return Convert.ToDouble(src.Data[index]);
4860 } 5299 }
4861 catch (FormatException) 5300 catch (FormatException)
@@ -5128,7 +5567,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5128 } 5567 }
5129 } 5568 }
5130 } 5569 }
5131 else { 5570 else
5571 {
5132 object[] array = new object[src.Length]; 5572 object[] array = new object[src.Length];
5133 Array.Copy(src.Data, 0, array, 0, src.Length); 5573 Array.Copy(src.Data, 0, array, 0, src.Length);
5134 result = new LSL_List(array); 5574 result = new LSL_List(array);
@@ -5579,10 +6019,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5579 m_host.AddScriptLPS(1); 6019 m_host.AddScriptLPS(1);
5580 6020
5581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6021 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5582 6022 if (parts.Count > 0)
5583 foreach (var part in parts)
5584 { 6023 {
5585 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6024 try
6025 {
6026 parts[0].ParentGroup.areUpdatesSuspended = true;
6027 foreach (var part in parts)
6028 {
6029 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6030 }
6031 }
6032 finally
6033 {
6034 parts[0].ParentGroup.areUpdatesSuspended = false;
6035 }
5586 } 6036 }
5587 } 6037 }
5588 6038
@@ -5636,6 +6086,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5636 ScriptSleep(5000); 6086 ScriptSleep(5000);
5637 } 6087 }
5638 6088
6089 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6090 {
6091 return ParseString2List(str, separators, in_spacers, false);
6092 }
6093
5639 public LSL_Integer llOverMyLand(string id) 6094 public LSL_Integer llOverMyLand(string id)
5640 { 6095 {
5641 m_host.AddScriptLPS(1); 6096 m_host.AddScriptLPS(1);
@@ -5836,7 +6291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5836 return m_host.ParentGroup.AttachmentPoint; 6291 return m_host.ParentGroup.AttachmentPoint;
5837 } 6292 }
5838 6293
5839 public LSL_Integer llGetFreeMemory() 6294 public virtual LSL_Integer llGetFreeMemory()
5840 { 6295 {
5841 m_host.AddScriptLPS(1); 6296 m_host.AddScriptLPS(1);
5842 // Make scripts designed for LSO happy 6297 // Make scripts designed for LSO happy
@@ -5953,7 +6408,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5953 SetParticleSystem(m_host, rules); 6408 SetParticleSystem(m_host, rules);
5954 } 6409 }
5955 6410
5956 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6411 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6412 {
5957 6413
5958 6414
5959 if (rules.Length == 0) 6415 if (rules.Length == 0)
@@ -6147,14 +6603,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6147 6603
6148 protected UUID GetTaskInventoryItem(string name) 6604 protected UUID GetTaskInventoryItem(string name)
6149 { 6605 {
6150 lock (m_host.TaskInventory) 6606 m_host.TaskInventory.LockItemsForRead(true);
6607 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6151 { 6608 {
6152 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6609 if (inv.Value.Name == name)
6153 { 6610 {
6154 if (inv.Value.Name == name) 6611 m_host.TaskInventory.LockItemsForRead(false);
6155 return inv.Key; 6612 return inv.Key;
6156 } 6613 }
6157 } 6614 }
6615 m_host.TaskInventory.LockItemsForRead(false);
6158 6616
6159 return UUID.Zero; 6617 return UUID.Zero;
6160 } 6618 }
@@ -6390,13 +6848,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6390 UUID av = new UUID(); 6848 UUID av = new UUID();
6391 if (!UUID.TryParse(avatar,out av)) 6849 if (!UUID.TryParse(avatar,out av))
6392 { 6850 {
6393 LSLError("First parameter to llDialog needs to be a key"); 6851 //LSLError("First parameter to llDialog needs to be a key");
6394 return; 6852 return;
6395 } 6853 }
6396 if (buttons.Length < 1) 6854 if (buttons.Length < 1)
6397 { 6855 {
6398 LSLError("No less than 1 button can be shown"); 6856 buttons.Add("OK");
6399 return;
6400 } 6857 }
6401 if (buttons.Length > 12) 6858 if (buttons.Length > 12)
6402 { 6859 {
@@ -6413,7 +6870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6413 } 6870 }
6414 if (buttons.Data[i].ToString().Length > 24) 6871 if (buttons.Data[i].ToString().Length > 24)
6415 { 6872 {
6416 LSLError("button label cannot be longer than 24 characters"); 6873 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6417 return; 6874 return;
6418 } 6875 }
6419 buts[i] = buttons.Data[i].ToString(); 6876 buts[i] = buttons.Data[i].ToString();
@@ -6472,22 +6929,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6472 } 6929 }
6473 6930
6474 // copy the first script found with this inventory name 6931 // copy the first script found with this inventory name
6475 lock (m_host.TaskInventory) 6932 TaskInventoryItem scriptItem = null;
6933 m_host.TaskInventory.LockItemsForRead(true);
6934 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6476 { 6935 {
6477 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6936 if (inv.Value.Name == name)
6478 { 6937 {
6479 if (inv.Value.Name == name) 6938 // make sure the object is a script
6939 if (10 == inv.Value.Type)
6480 { 6940 {
6481 // make sure the object is a script 6941 found = true;
6482 if (10 == inv.Value.Type) 6942 srcId = inv.Key;
6483 { 6943 scriptItem = inv.Value;
6484 found = true; 6944 break;
6485 srcId = inv.Key;
6486 break;
6487 }
6488 } 6945 }
6489 } 6946 }
6490 } 6947 }
6948 m_host.TaskInventory.LockItemsForRead(false);
6491 6949
6492 if (!found) 6950 if (!found)
6493 { 6951 {
@@ -6495,8 +6953,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6495 return; 6953 return;
6496 } 6954 }
6497 6955
6498 // the rest of the permission checks are done in RezScript, so check the pin there as well 6956 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6499 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6957 if (dest != null)
6958 {
6959 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6960 {
6961 // the rest of the permission checks are done in RezScript, so check the pin there as well
6962 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6963
6964 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6965 m_host.Inventory.RemoveInventoryItem(srcId);
6966 }
6967 }
6500 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6968 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6501 ScriptSleep(3000); 6969 ScriptSleep(3000);
6502 } 6970 }
@@ -6559,18 +7027,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6559 public LSL_String llMD5String(string src, int nonce) 7027 public LSL_String llMD5String(string src, int nonce)
6560 { 7028 {
6561 m_host.AddScriptLPS(1); 7029 m_host.AddScriptLPS(1);
6562 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7030 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6563 } 7031 }
6564 7032
6565 public LSL_String llSHA1String(string src) 7033 public LSL_String llSHA1String(string src)
6566 { 7034 {
6567 m_host.AddScriptLPS(1); 7035 m_host.AddScriptLPS(1);
6568 return Util.SHA1Hash(src).ToLower(); 7036 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6569 } 7037 }
6570 7038
6571 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7039 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6572 { 7040 {
6573 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7041 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7042 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7043 return shapeBlock;
6574 7044
6575 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7045 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6576 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7046 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6663,6 +7133,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6663 // Prim type box, cylinder and prism. 7133 // Prim type box, cylinder and prism.
6664 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) 7134 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)
6665 { 7135 {
7136 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7137 return;
7138
6666 ObjectShapePacket.ObjectDataBlock shapeBlock; 7139 ObjectShapePacket.ObjectDataBlock shapeBlock;
6667 7140
6668 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7141 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6711,6 +7184,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6711 // Prim type sphere. 7184 // Prim type sphere.
6712 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7185 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6713 { 7186 {
7187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7188 return;
7189
6714 ObjectShapePacket.ObjectDataBlock shapeBlock; 7190 ObjectShapePacket.ObjectDataBlock shapeBlock;
6715 7191
6716 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7192 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6752,6 +7228,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6752 // Prim type torus, tube and ring. 7228 // Prim type torus, tube and ring.
6753 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) 7229 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)
6754 { 7230 {
7231 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7232 return;
7233
6755 ObjectShapePacket.ObjectDataBlock shapeBlock; 7234 ObjectShapePacket.ObjectDataBlock shapeBlock;
6756 7235
6757 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7236 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6877,6 +7356,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 // Prim type sculpt. 7356 // Prim type sculpt.
6878 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7357 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6879 { 7358 {
7359 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7360 return;
7361
6880 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7362 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6881 UUID sculptId; 7363 UUID sculptId;
6882 7364
@@ -6893,13 +7375,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6893 shapeBlock.PathScaleX = 100; 7375 shapeBlock.PathScaleX = 100;
6894 shapeBlock.PathScaleY = 150; 7376 shapeBlock.PathScaleY = 150;
6895 7377
6896 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7378 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6897 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7379 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6898 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7380 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6899 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7381 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6900 { 7382 {
6901 // default 7383 // default
6902 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7384 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6903 } 7385 }
6904 7386
6905 part.Shape.SetSculptProperties((byte)type, sculptId); 7387 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -6915,32 +7397,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6915 ScriptSleep(200); 7397 ScriptSleep(200);
6916 } 7398 }
6917 7399
6918 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7400 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6919 { 7401 {
6920 m_host.AddScriptLPS(1); 7402 m_host.AddScriptLPS(1);
6921 7403
6922 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7404 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7405 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7406 if (parts.Count>0)
7407 {
7408 try
7409 {
7410 parts[0].ParentGroup.areUpdatesSuspended = true;
7411 foreach (SceneObjectPart part in parts)
7412 SetPrimParams(part, rules);
7413 }
7414 finally
7415 {
7416 parts[0].ParentGroup.areUpdatesSuspended = false;
7417 }
7418 }
7419 if (avatars.Count > 0)
7420 {
7421 foreach (ScenePresence avatar in avatars)
7422 SetPrimParams(avatar, rules);
7423 }
7424 }
6923 7425
6924 foreach (SceneObjectPart part in parts) 7426 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6925 SetPrimParams(part, rules); 7427 {
6926 7428 llSetLinkPrimitiveParamsFast(linknumber, rules);
6927 ScriptSleep(200); 7429 ScriptSleep(200);
6928 } 7430 }
6929 7431
6930 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7432 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6931 { 7433 {
6932 m_host.AddScriptLPS(1); 7434 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7435 //We only support PRIM_POSITION and PRIM_ROTATION
6933 7436
6934 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7437 int idx = 0;
6935 7438
6936 foreach (SceneObjectPart part in parts) 7439 while (idx < rules.Length)
6937 SetPrimParams(part, rules); 7440 {
7441 int code = rules.GetLSLIntegerItem(idx++);
7442
7443 int remain = rules.Length - idx;
7444
7445
7446
7447 switch (code)
7448 {
7449 case (int)ScriptBaseClass.PRIM_POSITION:
7450 if (remain < 1)
7451 return;
7452 LSL_Vector v;
7453 v = rules.GetVector3Item(idx++);
7454 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7455 av.SendAvatarDataToAllAgents();
7456
7457 break;
7458
7459 case (int)ScriptBaseClass.PRIM_ROTATION:
7460 if (remain < 1)
7461 return;
7462 LSL_Rotation r;
7463 r = rules.GetQuaternionItem(idx++);
7464 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7465 av.SendAvatarDataToAllAgents();
7466 break;
7467 }
7468 }
6938 } 7469 }
6939 7470
6940 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7471 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6941 { 7472 {
7473 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7474 return;
7475
6942 int idx = 0; 7476 int idx = 0;
6943 7477
7478 bool positionChanged = false;
7479 LSL_Vector currentPosition = GetPartLocalPos(part);
7480
6944 while (idx < rules.Length) 7481 while (idx < rules.Length)
6945 { 7482 {
6946 int code = rules.GetLSLIntegerItem(idx++); 7483 int code = rules.GetLSLIntegerItem(idx++);
@@ -6949,7 +7486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6949 7486
6950 int face; 7487 int face;
6951 LSL_Vector v; 7488 LSL_Vector v;
6952 7489
6953 switch (code) 7490 switch (code)
6954 { 7491 {
6955 case (int)ScriptBaseClass.PRIM_POSITION: 7492 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6957,7 +7494,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6957 return; 7494 return;
6958 7495
6959 v=rules.GetVector3Item(idx++); 7496 v=rules.GetVector3Item(idx++);
6960 SetPos(part, v); 7497 positionChanged = true;
7498 currentPosition = GetSetPosTarget(part, v, currentPosition);
6961 7499
6962 break; 7500 break;
6963 case (int)ScriptBaseClass.PRIM_SIZE: 7501 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7302,6 +7840,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7302 break; 7840 break;
7303 } 7841 }
7304 } 7842 }
7843
7844 if (positionChanged)
7845 {
7846 if (part.ParentGroup.RootPart == part)
7847 {
7848 SceneObjectGroup parent = part.ParentGroup;
7849 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7850 }
7851 else
7852 {
7853 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7854 SceneObjectGroup parent = part.ParentGroup;
7855 parent.HasGroupChanged = true;
7856 parent.ScheduleGroupForTerseUpdate();
7857 }
7858 }
7305 } 7859 }
7306 7860
7307 public LSL_String llStringToBase64(string str) 7861 public LSL_String llStringToBase64(string str)
@@ -7450,13 +8004,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7450 public LSL_Integer llGetNumberOfPrims() 8004 public LSL_Integer llGetNumberOfPrims()
7451 { 8005 {
7452 m_host.AddScriptLPS(1); 8006 m_host.AddScriptLPS(1);
7453 int avatarCount = 0; 8007 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7454 World.ForEachScenePresence(delegate(ScenePresence presence) 8008
7455 {
7456 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7457 avatarCount++;
7458 });
7459
7460 return m_host.ParentGroup.PrimCount + avatarCount; 8009 return m_host.ParentGroup.PrimCount + avatarCount;
7461 } 8010 }
7462 8011
@@ -7472,55 +8021,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7472 m_host.AddScriptLPS(1); 8021 m_host.AddScriptLPS(1);
7473 UUID objID = UUID.Zero; 8022 UUID objID = UUID.Zero;
7474 LSL_List result = new LSL_List(); 8023 LSL_List result = new LSL_List();
8024
8025 // If the ID is not valid, return null result
7475 if (!UUID.TryParse(obj, out objID)) 8026 if (!UUID.TryParse(obj, out objID))
7476 { 8027 {
7477 result.Add(new LSL_Vector()); 8028 result.Add(new LSL_Vector());
7478 result.Add(new LSL_Vector()); 8029 result.Add(new LSL_Vector());
7479 return result; 8030 return result;
7480 } 8031 }
8032
8033 // Check if this is an attached prim. If so, replace
8034 // the UUID with the avatar UUID and report it's bounding box
8035 SceneObjectPart part = World.GetSceneObjectPart(objID);
8036 if (part != null && part.ParentGroup.IsAttachment)
8037 objID = part.ParentGroup.RootPart.AttachedAvatar;
8038
8039 // Find out if this is an avatar ID. If so, return it's box
7481 ScenePresence presence = World.GetScenePresence(objID); 8040 ScenePresence presence = World.GetScenePresence(objID);
7482 if (presence != null) 8041 if (presence != null)
7483 { 8042 {
7484 if (presence.ParentID == 0) // not sat on an object 8043 // As per LSL Wiki, there is no difference between sitting
8044 // and standing avatar since server 1.36
8045 LSL_Vector lower;
8046 LSL_Vector upper;
8047 if (presence.Animator.Animations.DefaultAnimation.AnimID
8048 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7485 { 8049 {
7486 LSL_Vector lower; 8050 // This is for ground sitting avatars
7487 LSL_Vector upper; 8051 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7488 if (presence.Animator.Animations.DefaultAnimation.AnimID 8052 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7489 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8053 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7490 {
7491 // This is for ground sitting avatars
7492 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7493 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7494 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7495 }
7496 else
7497 {
7498 // This is for standing/flying avatars
7499 float height = presence.Appearance.AvatarHeight / 2.0f;
7500 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7501 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7502 }
7503 result.Add(lower);
7504 result.Add(upper);
7505 return result;
7506 } 8054 }
7507 else 8055 else
7508 { 8056 {
7509 // sitting on an object so we need the bounding box of that 8057 // This is for standing/flying avatars
7510 // which should include the avatar so set the UUID to the 8058 float height = presence.Appearance.AvatarHeight / 2.0f;
7511 // UUID of the object the avatar is sat on and allow it to fall through 8059 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7512 // to processing an object 8060 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7513 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7514 objID = p.UUID;
7515 } 8061 }
8062
8063 // Adjust to the documented error offsets (see LSL Wiki)
8064 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8065 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8066
8067 if (lower.x > upper.x)
8068 lower.x = upper.x;
8069 if (lower.y > upper.y)
8070 lower.y = upper.y;
8071 if (lower.z > upper.z)
8072 lower.z = upper.z;
8073
8074 result.Add(lower);
8075 result.Add(upper);
8076 return result;
7516 } 8077 }
7517 SceneObjectPart part = World.GetSceneObjectPart(objID); 8078
8079 part = World.GetSceneObjectPart(objID);
7518 // Currently only works for single prims without a sitting avatar 8080 // Currently only works for single prims without a sitting avatar
7519 if (part != null) 8081 if (part != null)
7520 { 8082 {
7521 Vector3 halfSize = part.Scale / 2.0f; 8083 float minX;
7522 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8084 float maxX;
7523 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8085 float minY;
8086 float maxY;
8087 float minZ;
8088 float maxZ;
8089
8090 // This BBox is in sim coordinates, with the offset being
8091 // a contained point.
8092 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8093 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8094
8095 minX -= offsets[0].X;
8096 maxX -= offsets[0].X;
8097 minY -= offsets[0].Y;
8098 maxY -= offsets[0].Y;
8099 minZ -= offsets[0].Z;
8100 maxZ -= offsets[0].Z;
8101
8102 LSL_Vector lower;
8103 LSL_Vector upper;
8104
8105 // Adjust to the documented error offsets (see LSL Wiki)
8106 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8107 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8108
8109 if (lower.x > upper.x)
8110 lower.x = upper.x;
8111 if (lower.y > upper.y)
8112 lower.y = upper.y;
8113 if (lower.z > upper.z)
8114 lower.z = upper.z;
8115
7524 result.Add(lower); 8116 result.Add(lower);
7525 result.Add(upper); 8117 result.Add(upper);
7526 return result; 8118 return result;
@@ -7600,13 +8192,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7600 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8192 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7601 part.AbsolutePosition.Y, 8193 part.AbsolutePosition.Y,
7602 part.AbsolutePosition.Z); 8194 part.AbsolutePosition.Z);
7603 // For some reason, the part.AbsolutePosition.* values do not change if the
7604 // linkset is rotated; they always reflect the child prim's world position
7605 // as though the linkset is unrotated. This is incompatible behavior with SL's
7606 // implementation, so will break scripts imported from there (not to mention it
7607 // makes it more difficult to determine a child prim's actual inworld position).
7608 if (part.ParentID != 0)
7609 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7610 res.Add(v); 8195 res.Add(v);
7611 break; 8196 break;
7612 8197
@@ -7767,56 +8352,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7767 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8352 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7768 if (remain < 1) 8353 if (remain < 1)
7769 return res; 8354 return res;
7770 8355 face = (int)rules.GetLSLIntegerItem(idx++);
7771 face=(int)rules.GetLSLIntegerItem(idx++);
7772 8356
7773 tex = part.Shape.Textures; 8357 tex = part.Shape.Textures;
8358 int shiny;
7774 if (face == ScriptBaseClass.ALL_SIDES) 8359 if (face == ScriptBaseClass.ALL_SIDES)
7775 { 8360 {
7776 for (face = 0; face < GetNumberOfSides(part); face++) 8361 for (face = 0; face < GetNumberOfSides(part); face++)
7777 { 8362 {
7778 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8363 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7779 // Convert Shininess to PRIM_SHINY_* 8364 if (shinyness == Shininess.High)
7780 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8365 {
7781 // PRIM_BUMP_* 8366 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7782 res.Add(new LSL_Integer((int)texface.Bump)); 8367 }
8368 else if (shinyness == Shininess.Medium)
8369 {
8370 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8371 }
8372 else if (shinyness == Shininess.Low)
8373 {
8374 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8375 }
8376 else
8377 {
8378 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8379 }
8380 res.Add(new LSL_Integer(shiny));
8381 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7783 } 8382 }
7784 } 8383 }
7785 else 8384 else
7786 { 8385 {
7787 if (face >= 0 && face < GetNumberOfSides(part)) 8386 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8387 if (shinyness == Shininess.High)
7788 { 8388 {
7789 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8389 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7790 // Convert Shininess to PRIM_SHINY_*
7791 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7792 // PRIM_BUMP_*
7793 res.Add(new LSL_Integer((int)texface.Bump));
7794 } 8390 }
8391 else if (shinyness == Shininess.Medium)
8392 {
8393 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8394 }
8395 else if (shinyness == Shininess.Low)
8396 {
8397 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8398 }
8399 else
8400 {
8401 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8402 }
8403 res.Add(new LSL_Integer(shiny));
8404 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7795 } 8405 }
7796 break; 8406 break;
7797 8407
7798 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8408 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7799 if (remain < 1) 8409 if (remain < 1)
7800 return res; 8410 return res;
7801 8411 face = (int)rules.GetLSLIntegerItem(idx++);
7802 face=(int)rules.GetLSLIntegerItem(idx++);
7803 8412
7804 tex = part.Shape.Textures; 8413 tex = part.Shape.Textures;
8414 int fullbright;
7805 if (face == ScriptBaseClass.ALL_SIDES) 8415 if (face == ScriptBaseClass.ALL_SIDES)
7806 { 8416 {
7807 for (face = 0; face < GetNumberOfSides(part); face++) 8417 for (face = 0; face < GetNumberOfSides(part); face++)
7808 { 8418 {
7809 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8419 if (tex.GetFace((uint)face).Fullbright == true)
7810 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8420 {
8421 fullbright = ScriptBaseClass.TRUE;
8422 }
8423 else
8424 {
8425 fullbright = ScriptBaseClass.FALSE;
8426 }
8427 res.Add(new LSL_Integer(fullbright));
7811 } 8428 }
7812 } 8429 }
7813 else 8430 else
7814 { 8431 {
7815 if (face >= 0 && face < GetNumberOfSides(part)) 8432 if (tex.GetFace((uint)face).Fullbright == true)
7816 { 8433 {
7817 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8434 fullbright = ScriptBaseClass.TRUE;
7818 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7819 } 8435 }
8436 else
8437 {
8438 fullbright = ScriptBaseClass.FALSE;
8439 }
8440 res.Add(new LSL_Integer(fullbright));
7820 } 8441 }
7821 break; 8442 break;
7822 8443
@@ -7838,27 +8459,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7838 break; 8459 break;
7839 8460
7840 case (int)ScriptBaseClass.PRIM_TEXGEN: 8461 case (int)ScriptBaseClass.PRIM_TEXGEN:
8462 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7841 if (remain < 1) 8463 if (remain < 1)
7842 return res; 8464 return res;
7843 8465 face = (int)rules.GetLSLIntegerItem(idx++);
7844 face=(int)rules.GetLSLIntegerItem(idx++);
7845 8466
7846 tex = part.Shape.Textures; 8467 tex = part.Shape.Textures;
7847 if (face == ScriptBaseClass.ALL_SIDES) 8468 if (face == ScriptBaseClass.ALL_SIDES)
7848 { 8469 {
7849 for (face = 0; face < GetNumberOfSides(part); face++) 8470 for (face = 0; face < GetNumberOfSides(part); face++)
7850 { 8471 {
7851 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8472 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7852 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8473 {
7853 res.Add(new LSL_Integer((uint)texgen >> 1)); 8474 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8475 }
8476 else
8477 {
8478 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8479 }
7854 } 8480 }
7855 } 8481 }
7856 else 8482 else
7857 { 8483 {
7858 if (face >= 0 && face < GetNumberOfSides(part)) 8484 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7859 { 8485 {
7860 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8486 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
7861 res.Add(new LSL_Integer((uint)texgen >> 1)); 8487 }
8488 else
8489 {
8490 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7862 } 8491 }
7863 } 8492 }
7864 break; 8493 break;
@@ -7881,28 +8510,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7881 case (int)ScriptBaseClass.PRIM_GLOW: 8510 case (int)ScriptBaseClass.PRIM_GLOW:
7882 if (remain < 1) 8511 if (remain < 1)
7883 return res; 8512 return res;
7884 8513 face = (int)rules.GetLSLIntegerItem(idx++);
7885 face=(int)rules.GetLSLIntegerItem(idx++);
7886 8514
7887 tex = part.Shape.Textures; 8515 tex = part.Shape.Textures;
8516 float primglow;
7888 if (face == ScriptBaseClass.ALL_SIDES) 8517 if (face == ScriptBaseClass.ALL_SIDES)
7889 { 8518 {
7890 for (face = 0; face < GetNumberOfSides(part); face++) 8519 for (face = 0; face < GetNumberOfSides(part); face++)
7891 { 8520 {
7892 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8521 primglow = tex.GetFace((uint)face).Glow;
7893 res.Add(new LSL_Float(texface.Glow)); 8522 res.Add(new LSL_Float(primglow));
7894 } 8523 }
7895 } 8524 }
7896 else 8525 else
7897 { 8526 {
7898 if (face >= 0 && face < GetNumberOfSides(part)) 8527 primglow = tex.GetFace((uint)face).Glow;
7899 { 8528 res.Add(new LSL_Float(primglow));
7900 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7901 res.Add(new LSL_Float(texface.Glow));
7902 }
7903 } 8529 }
7904 break; 8530 break;
7905
7906 case (int)ScriptBaseClass.PRIM_TEXT: 8531 case (int)ScriptBaseClass.PRIM_TEXT:
7907 Color4 textColor = part.GetTextColor(); 8532 Color4 textColor = part.GetTextColor();
7908 res.Add(new LSL_String(part.Text)); 8533 res.Add(new LSL_String(part.Text));
@@ -8451,8 +9076,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8451 // The function returns an ordered list 9076 // The function returns an ordered list
8452 // representing the tokens found in the supplied 9077 // representing the tokens found in the supplied
8453 // sources string. If two successive tokenizers 9078 // sources string. If two successive tokenizers
8454 // are encountered, then a NULL entry is added 9079 // are encountered, then a null-string entry is
8455 // to the list. 9080 // added to the list.
8456 // 9081 //
8457 // It is a precondition that the source and 9082 // It is a precondition that the source and
8458 // toekizer lisst are non-null. If they are null, 9083 // toekizer lisst are non-null. If they are null,
@@ -8460,7 +9085,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8460 // while their lengths are being determined. 9085 // while their lengths are being determined.
8461 // 9086 //
8462 // A small amount of working memoryis required 9087 // A small amount of working memoryis required
8463 // of approximately 8*#tokenizers. 9088 // of approximately 8*#tokenizers + 8*srcstrlen.
8464 // 9089 //
8465 // There are many ways in which this function 9090 // There are many ways in which this function
8466 // can be implemented, this implementation is 9091 // can be implemented, this implementation is
@@ -8476,155 +9101,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8476 // and eliminates redundant tokenizers as soon 9101 // and eliminates redundant tokenizers as soon
8477 // as is possible. 9102 // as is possible.
8478 // 9103 //
8479 // The implementation tries to avoid any copying 9104 // The implementation tries to minimize temporary
8480 // of arrays or other objects. 9105 // garbage generation.
8481 // </remarks> 9106 // </remarks>
8482 9107
8483 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9108 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8484 { 9109 {
8485 int beginning = 0; 9110 return ParseString2List(src, separators, spacers, true);
8486 int srclen = src.Length; 9111 }
8487 int seplen = separators.Length;
8488 object[] separray = separators.Data;
8489 int spclen = spacers.Length;
8490 object[] spcarray = spacers.Data;
8491 int mlen = seplen+spclen;
8492
8493 int[] offset = new int[mlen+1];
8494 bool[] active = new bool[mlen];
8495
8496 int best;
8497 int j;
8498
8499 // Initial capacity reduces resize cost
8500 9112
8501 LSL_List tokens = new LSL_List(); 9113 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9114 {
9115 int srclen = src.Length;
9116 int seplen = separators.Length;
9117 object[] separray = separators.Data;
9118 int spclen = spacers.Length;
9119 object[] spcarray = spacers.Data;
9120 int dellen = 0;
9121 string[] delarray = new string[seplen+spclen];
8502 9122
8503 // All entries are initially valid 9123 int outlen = 0;
9124 string[] outarray = new string[srclen*2+1];
8504 9125
8505 for (int i = 0; i < mlen; i++) 9126 int i, j;
8506 active[i] = true; 9127 string d;
8507 9128
8508 offset[mlen] = srclen; 9129 m_host.AddScriptLPS(1);
8509 9130
8510 while (beginning < srclen) 9131 /*
9132 * Convert separator and spacer lists to C# strings.
9133 * Also filter out null strings so we don't hang.
9134 */
9135 for (i = 0; i < seplen; i ++)
8511 { 9136 {
9137 d = separray[i].ToString();
9138 if (d.Length > 0)
9139 {
9140 delarray[dellen++] = d;
9141 }
9142 }
9143 seplen = dellen;
8512 9144
8513 best = mlen; // as bad as it gets 9145 for (i = 0; i < spclen; i ++)
9146 {
9147 d = spcarray[i].ToString();
9148 if (d.Length > 0)
9149 {
9150 delarray[dellen++] = d;
9151 }
9152 }
8514 9153
8515 // Scan for separators 9154 /*
9155 * Scan through source string from beginning to end.
9156 */
9157 for (i = 0;;)
9158 {
8516 9159
8517 for (j = 0; j < seplen; j++) 9160 /*
9161 * Find earliest delimeter in src starting at i (if any).
9162 */
9163 int earliestDel = -1;
9164 int earliestSrc = srclen;
9165 string earliestStr = null;
9166 for (j = 0; j < dellen; j ++)
8518 { 9167 {
8519 if (separray[j].ToString() == String.Empty) 9168 d = delarray[j];
8520 active[j] = false; 9169 if (d != null)
8521
8522 if (active[j])
8523 { 9170 {
8524 // scan all of the markers 9171 int index = src.IndexOf(d, i);
8525 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9172 if (index < 0)
8526 { 9173 {
8527 // not present at all 9174 delarray[j] = null; // delim nowhere in src, don't check it anymore
8528 active[j] = false;
8529 } 9175 }
8530 else 9176 else if (index < earliestSrc)
8531 { 9177 {
8532 // present and correct 9178 earliestSrc = index; // where delimeter starts in source string
8533 if (offset[j] < offset[best]) 9179 earliestDel = j; // where delimeter is in delarray[]
8534 { 9180 earliestStr = d; // the delimeter string from delarray[]
8535 // closest so far 9181 if (index == i) break; // can't do any better than found at beg of string
8536 best = j;
8537 if (offset[best] == beginning)
8538 break;
8539 }
8540 } 9182 }
8541 } 9183 }
8542 } 9184 }
8543 9185
8544 // Scan for spacers 9186 /*
8545 9187 * Output source string starting at i through start of earliest delimeter.
8546 if (offset[best] != beginning) 9188 */
9189 if (keepNulls || (earliestSrc > i))
8547 { 9190 {
8548 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9191 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8549 {
8550 if (spcarray[j-seplen].ToString() == String.Empty)
8551 active[j] = false;
8552
8553 if (active[j])
8554 {
8555 // scan all of the markers
8556 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8557 {
8558 // not present at all
8559 active[j] = false;
8560 }
8561 else
8562 {
8563 // present and correct
8564 if (offset[j] < offset[best])
8565 {
8566 // closest so far
8567 best = j;
8568 }
8569 }
8570 }
8571 }
8572 } 9192 }
8573 9193
8574 // This is the normal exit from the scanning loop 9194 /*
9195 * If no delimeter found at or after i, we're done scanning.
9196 */
9197 if (earliestDel < 0) break;
8575 9198
8576 if (best == mlen) 9199 /*
9200 * If delimeter was a spacer, output the spacer.
9201 */
9202 if (earliestDel >= seplen)
8577 { 9203 {
8578 // no markers were found on this pass 9204 outarray[outlen++] = earliestStr;
8579 // so we're pretty much done
8580 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8581 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8582 break;
8583 } 9205 }
8584 9206
8585 // Otherwise we just add the newly delimited token 9207 /*
8586 // and recalculate where the search should continue. 9208 * Look at rest of src string following delimeter.
8587 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9209 */
8588 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9210 i = earliestSrc + earliestStr.Length;
8589
8590 if (best < seplen)
8591 {
8592 beginning = offset[best] + (separray[best].ToString()).Length;
8593 }
8594 else
8595 {
8596 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8597 string str = spcarray[best - seplen].ToString();
8598 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8599 tokens.Add(new LSL_String(str));
8600 }
8601 } 9211 }
8602 9212
8603 // This an awkward an not very intuitive boundary case. If the 9213 /*
8604 // last substring is a tokenizer, then there is an implied trailing 9214 * Make up an exact-sized output array suitable for an LSL_List object.
8605 // null list entry. Hopefully the single comparison will not be too 9215 */
8606 // arduous. Alternatively the 'break' could be replced with a return 9216 object[] outlist = new object[outlen];
8607 // but that's shabby programming. 9217 for (i = 0; i < outlen; i ++)
8608
8609 if ((beginning == srclen) && (keepNulls))
8610 { 9218 {
8611 if (srclen != 0) 9219 outlist[i] = new LSL_String(outarray[i]);
8612 tokens.Add(new LSL_String(""));
8613 } 9220 }
8614 9221 return new LSL_List(outlist);
8615 return tokens;
8616 }
8617
8618 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8619 {
8620 m_host.AddScriptLPS(1);
8621 return this.ParseString(src, separators, spacers, false);
8622 }
8623
8624 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8625 {
8626 m_host.AddScriptLPS(1);
8627 return this.ParseString(src, separators, spacers, true);
8628 } 9222 }
8629 9223
8630 public LSL_Integer llGetObjectPermMask(int mask) 9224 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8701,28 +9295,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8701 { 9295 {
8702 m_host.AddScriptLPS(1); 9296 m_host.AddScriptLPS(1);
8703 9297
8704 lock (m_host.TaskInventory) 9298 m_host.TaskInventory.LockItemsForRead(true);
9299 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8705 { 9300 {
8706 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9301 if (inv.Value.Name == item)
8707 { 9302 {
8708 if (inv.Value.Name == item) 9303 m_host.TaskInventory.LockItemsForRead(false);
9304 switch (mask)
8709 { 9305 {
8710 switch (mask) 9306 case 0:
8711 { 9307 return (int)inv.Value.BasePermissions;
8712 case 0: 9308 case 1:
8713 return (int)inv.Value.BasePermissions; 9309 return (int)inv.Value.CurrentPermissions;
8714 case 1: 9310 case 2:
8715 return (int)inv.Value.CurrentPermissions; 9311 return (int)inv.Value.GroupPermissions;
8716 case 2: 9312 case 3:
8717 return (int)inv.Value.GroupPermissions; 9313 return (int)inv.Value.EveryonePermissions;
8718 case 3: 9314 case 4:
8719 return (int)inv.Value.EveryonePermissions; 9315 return (int)inv.Value.NextPermissions;
8720 case 4:
8721 return (int)inv.Value.NextPermissions;
8722 }
8723 } 9316 }
8724 } 9317 }
8725 } 9318 }
9319 m_host.TaskInventory.LockItemsForRead(false);
8726 9320
8727 return -1; 9321 return -1;
8728 } 9322 }
@@ -8769,16 +9363,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8769 { 9363 {
8770 m_host.AddScriptLPS(1); 9364 m_host.AddScriptLPS(1);
8771 9365
8772 lock (m_host.TaskInventory) 9366 m_host.TaskInventory.LockItemsForRead(true);
9367 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8773 { 9368 {
8774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9369 if (inv.Value.Name == item)
8775 { 9370 {
8776 if (inv.Value.Name == item) 9371 m_host.TaskInventory.LockItemsForRead(false);
8777 { 9372 return inv.Value.CreatorID.ToString();
8778 return inv.Value.CreatorID.ToString();
8779 }
8780 } 9373 }
8781 } 9374 }
9375 m_host.TaskInventory.LockItemsForRead(false);
8782 9376
8783 llSay(0, "No item name '" + item + "'"); 9377 llSay(0, "No item name '" + item + "'");
8784 9378
@@ -8926,7 +9520,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8926 } 9520 }
8927 9521
8928 /// <summary> 9522 /// <summary>
8929 /// illListReplaceList removes the sub-list defined by the inclusive indices 9523 /// llListReplaceList removes the sub-list defined by the inclusive indices
8930 /// start and end and inserts the src list in its place. The inclusive 9524 /// start and end and inserts the src list in its place. The inclusive
8931 /// nature of the indices means that at least one element must be deleted 9525 /// nature of the indices means that at least one element must be deleted
8932 /// if the indices are within the bounds of the existing list. I.e. 2,2 9526 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8983,16 +9577,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8983 // based upon end. Note that if end exceeds the upper 9577 // based upon end. Note that if end exceeds the upper
8984 // bound in this case, the entire destination list 9578 // bound in this case, the entire destination list
8985 // is removed. 9579 // is removed.
8986 else 9580 else if (start == 0)
8987 { 9581 {
8988 if (end + 1 < dest.Length) 9582 if (end + 1 < dest.Length)
8989 {
8990 return src + dest.GetSublist(end + 1, -1); 9583 return src + dest.GetSublist(end + 1, -1);
8991 }
8992 else 9584 else
8993 {
8994 return src; 9585 return src;
8995 } 9586 }
9587 else // Start < 0
9588 {
9589 if (end + 1 < dest.Length)
9590 return dest.GetSublist(end + 1, -1);
9591 else
9592 return new LSL_List();
8996 } 9593 }
8997 } 9594 }
8998 // Finally, if start > end, we strip away a prefix and 9595 // Finally, if start > end, we strip away a prefix and
@@ -9043,17 +9640,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9043 int width = 0; 9640 int width = 0;
9044 int height = 0; 9641 int height = 0;
9045 9642
9046 ParcelMediaCommandEnum? commandToSend = null; 9643 uint commandToSend = 0;
9047 float time = 0.0f; // default is from start 9644 float time = 0.0f; // default is from start
9048 9645
9049 ScenePresence presence = null; 9646 ScenePresence presence = null;
9050 9647
9051 for (int i = 0; i < commandList.Data.Length; i++) 9648 for (int i = 0; i < commandList.Data.Length; i++)
9052 { 9649 {
9053 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9650 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9054 switch (command) 9651 switch (command)
9055 { 9652 {
9056 case ParcelMediaCommandEnum.Agent: 9653 case (uint)ParcelMediaCommandEnum.Agent:
9057 // we send only to one agent 9654 // we send only to one agent
9058 if ((i + 1) < commandList.Length) 9655 if ((i + 1) < commandList.Length)
9059 { 9656 {
@@ -9070,25 +9667,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9070 } 9667 }
9071 break; 9668 break;
9072 9669
9073 case ParcelMediaCommandEnum.Loop: 9670 case (uint)ParcelMediaCommandEnum.Loop:
9074 loop = 1; 9671 loop = 1;
9075 commandToSend = command; 9672 commandToSend = command;
9076 update = true; //need to send the media update packet to set looping 9673 update = true; //need to send the media update packet to set looping
9077 break; 9674 break;
9078 9675
9079 case ParcelMediaCommandEnum.Play: 9676 case (uint)ParcelMediaCommandEnum.Play:
9080 loop = 0; 9677 loop = 0;
9081 commandToSend = command; 9678 commandToSend = command;
9082 update = true; //need to send the media update packet to make sure it doesn't loop 9679 update = true; //need to send the media update packet to make sure it doesn't loop
9083 break; 9680 break;
9084 9681
9085 case ParcelMediaCommandEnum.Pause: 9682 case (uint)ParcelMediaCommandEnum.Pause:
9086 case ParcelMediaCommandEnum.Stop: 9683 case (uint)ParcelMediaCommandEnum.Stop:
9087 case ParcelMediaCommandEnum.Unload: 9684 case (uint)ParcelMediaCommandEnum.Unload:
9088 commandToSend = command; 9685 commandToSend = command;
9089 break; 9686 break;
9090 9687
9091 case ParcelMediaCommandEnum.Url: 9688 case (uint)ParcelMediaCommandEnum.Url:
9092 if ((i + 1) < commandList.Length) 9689 if ((i + 1) < commandList.Length)
9093 { 9690 {
9094 if (commandList.Data[i + 1] is LSL_String) 9691 if (commandList.Data[i + 1] is LSL_String)
@@ -9101,7 +9698,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9101 } 9698 }
9102 break; 9699 break;
9103 9700
9104 case ParcelMediaCommandEnum.Texture: 9701 case (uint)ParcelMediaCommandEnum.Texture:
9105 if ((i + 1) < commandList.Length) 9702 if ((i + 1) < commandList.Length)
9106 { 9703 {
9107 if (commandList.Data[i + 1] is LSL_String) 9704 if (commandList.Data[i + 1] is LSL_String)
@@ -9114,7 +9711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9114 } 9711 }
9115 break; 9712 break;
9116 9713
9117 case ParcelMediaCommandEnum.Time: 9714 case (uint)ParcelMediaCommandEnum.Time:
9118 if ((i + 1) < commandList.Length) 9715 if ((i + 1) < commandList.Length)
9119 { 9716 {
9120 if (commandList.Data[i + 1] is LSL_Float) 9717 if (commandList.Data[i + 1] is LSL_Float)
@@ -9126,7 +9723,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9126 } 9723 }
9127 break; 9724 break;
9128 9725
9129 case ParcelMediaCommandEnum.AutoAlign: 9726 case (uint)ParcelMediaCommandEnum.AutoAlign:
9130 if ((i + 1) < commandList.Length) 9727 if ((i + 1) < commandList.Length)
9131 { 9728 {
9132 if (commandList.Data[i + 1] is LSL_Integer) 9729 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9140,7 +9737,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9140 } 9737 }
9141 break; 9738 break;
9142 9739
9143 case ParcelMediaCommandEnum.Type: 9740 case (uint)ParcelMediaCommandEnum.Type:
9144 if ((i + 1) < commandList.Length) 9741 if ((i + 1) < commandList.Length)
9145 { 9742 {
9146 if (commandList.Data[i + 1] is LSL_String) 9743 if (commandList.Data[i + 1] is LSL_String)
@@ -9153,7 +9750,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9153 } 9750 }
9154 break; 9751 break;
9155 9752
9156 case ParcelMediaCommandEnum.Desc: 9753 case (uint)ParcelMediaCommandEnum.Desc:
9157 if ((i + 1) < commandList.Length) 9754 if ((i + 1) < commandList.Length)
9158 { 9755 {
9159 if (commandList.Data[i + 1] is LSL_String) 9756 if (commandList.Data[i + 1] is LSL_String)
@@ -9166,7 +9763,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 } 9763 }
9167 break; 9764 break;
9168 9765
9169 case ParcelMediaCommandEnum.Size: 9766 case (uint)ParcelMediaCommandEnum.Size:
9170 if ((i + 2) < commandList.Length) 9767 if ((i + 2) < commandList.Length)
9171 { 9768 {
9172 if (commandList.Data[i + 1] is LSL_Integer) 9769 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9236,7 +9833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9236 } 9833 }
9237 } 9834 }
9238 9835
9239 if (commandToSend != null) 9836 if (commandToSend != 0)
9240 { 9837 {
9241 // the commandList contained a start/stop/... command, too 9838 // the commandList contained a start/stop/... command, too
9242 if (presence == null) 9839 if (presence == null)
@@ -9273,7 +9870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9273 9870
9274 if (aList.Data[i] != null) 9871 if (aList.Data[i] != null)
9275 { 9872 {
9276 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9873 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9277 { 9874 {
9278 case ParcelMediaCommandEnum.Url: 9875 case ParcelMediaCommandEnum.Url:
9279 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9876 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9316,16 +9913,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9316 { 9913 {
9317 m_host.AddScriptLPS(1); 9914 m_host.AddScriptLPS(1);
9318 9915
9319 lock (m_host.TaskInventory) 9916 m_host.TaskInventory.LockItemsForRead(true);
9917 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9320 { 9918 {
9321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9919 if (inv.Value.Name == name)
9322 { 9920 {
9323 if (inv.Value.Name == name) 9921 m_host.TaskInventory.LockItemsForRead(false);
9324 { 9922 return inv.Value.Type;
9325 return inv.Value.Type;
9326 }
9327 } 9923 }
9328 } 9924 }
9925 m_host.TaskInventory.LockItemsForRead(false);
9329 9926
9330 return -1; 9927 return -1;
9331 } 9928 }
@@ -9336,15 +9933,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9336 9933
9337 if (quick_pay_buttons.Data.Length < 4) 9934 if (quick_pay_buttons.Data.Length < 4)
9338 { 9935 {
9339 LSLError("List must have at least 4 elements"); 9936 int x;
9340 return; 9937 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9938 {
9939 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9940 }
9341 } 9941 }
9342 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9942 int[] nPrice = new int[5];
9343 9943 nPrice[0] = price;
9344 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9944 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9345 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9945 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9346 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9946 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9347 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9947 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9948 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9348 m_host.ParentGroup.HasGroupChanged = true; 9949 m_host.ParentGroup.HasGroupChanged = true;
9349 } 9950 }
9350 9951
@@ -9356,17 +9957,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9356 if (invItemID == UUID.Zero) 9957 if (invItemID == UUID.Zero)
9357 return new LSL_Vector(); 9958 return new LSL_Vector();
9358 9959
9359 lock (m_host.TaskInventory) 9960 m_host.TaskInventory.LockItemsForRead(true);
9961 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9360 { 9962 {
9361 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9963 m_host.TaskInventory.LockItemsForRead(false);
9362 return new LSL_Vector(); 9964 return new LSL_Vector();
9965 }
9363 9966
9364 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9967 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9365 { 9968 {
9366 ShoutError("No permissions to track the camera"); 9969 ShoutError("No permissions to track the camera");
9367 return new LSL_Vector(); 9970 m_host.TaskInventory.LockItemsForRead(false);
9368 } 9971 return new LSL_Vector();
9369 } 9972 }
9973 m_host.TaskInventory.LockItemsForRead(false);
9370 9974
9371 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9975 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9372 if (presence != null) 9976 if (presence != null)
@@ -9384,17 +9988,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9384 if (invItemID == UUID.Zero) 9988 if (invItemID == UUID.Zero)
9385 return new LSL_Rotation(); 9989 return new LSL_Rotation();
9386 9990
9387 lock (m_host.TaskInventory) 9991 m_host.TaskInventory.LockItemsForRead(true);
9992 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9388 { 9993 {
9389 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9994 m_host.TaskInventory.LockItemsForRead(false);
9390 return new LSL_Rotation(); 9995 return new LSL_Rotation();
9391
9392 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9393 {
9394 ShoutError("No permissions to track the camera");
9395 return new LSL_Rotation();
9396 }
9397 } 9996 }
9997 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9998 {
9999 ShoutError("No permissions to track the camera");
10000 m_host.TaskInventory.LockItemsForRead(false);
10001 return new LSL_Rotation();
10002 }
10003 m_host.TaskInventory.LockItemsForRead(false);
9398 10004
9399 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10005 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9400 if (presence != null) 10006 if (presence != null)
@@ -9456,8 +10062,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9456 { 10062 {
9457 m_host.AddScriptLPS(1); 10063 m_host.AddScriptLPS(1);
9458 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10064 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9459 if (detectedParams == null) return; // only works on the first detected avatar 10065 if (detectedParams == null)
9460 10066 {
10067 if (m_host.IsAttachment == true)
10068 {
10069 detectedParams = new DetectParams();
10070 detectedParams.Key = m_host.OwnerID;
10071 }
10072 else
10073 {
10074 return;
10075 }
10076 }
10077
9461 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10078 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9462 if (avatar != null) 10079 if (avatar != null)
9463 { 10080 {
@@ -9465,6 +10082,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10082 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9466 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10083 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9467 } 10084 }
10085
9468 ScriptSleep(1000); 10086 ScriptSleep(1000);
9469 } 10087 }
9470 10088
@@ -9557,14 +10175,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9557 if (objectID == UUID.Zero) return; 10175 if (objectID == UUID.Zero) return;
9558 10176
9559 UUID agentID; 10177 UUID agentID;
9560 lock (m_host.TaskInventory) 10178 m_host.TaskInventory.LockItemsForRead(true);
9561 { 10179 // we need the permission first, to know which avatar we want to set the camera for
9562 // we need the permission first, to know which avatar we want to set the camera for 10180 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9563 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9564 10181
9565 if (agentID == UUID.Zero) return; 10182 if (agentID == UUID.Zero)
9566 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10183 {
10184 m_host.TaskInventory.LockItemsForRead(false);
10185 return;
9567 } 10186 }
10187 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10188 {
10189 m_host.TaskInventory.LockItemsForRead(false);
10190 return;
10191 }
10192 m_host.TaskInventory.LockItemsForRead(false);
9568 10193
9569 ScenePresence presence = World.GetScenePresence(agentID); 10194 ScenePresence presence = World.GetScenePresence(agentID);
9570 10195
@@ -9573,12 +10198,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9573 10198
9574 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10199 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9575 object[] data = rules.Data; 10200 object[] data = rules.Data;
9576 for (int i = 0; i < data.Length; ++i) { 10201 for (int i = 0; i < data.Length; ++i)
10202 {
9577 int type = Convert.ToInt32(data[i++].ToString()); 10203 int type = Convert.ToInt32(data[i++].ToString());
9578 if (i >= data.Length) break; // odd number of entries => ignore the last 10204 if (i >= data.Length) break; // odd number of entries => ignore the last
9579 10205
9580 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10206 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9581 switch (type) { 10207 switch (type)
10208 {
9582 case ScriptBaseClass.CAMERA_FOCUS: 10209 case ScriptBaseClass.CAMERA_FOCUS:
9583 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10210 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9584 case ScriptBaseClass.CAMERA_POSITION: 10211 case ScriptBaseClass.CAMERA_POSITION:
@@ -9614,12 +10241,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9614 10241
9615 // we need the permission first, to know which avatar we want to clear the camera for 10242 // we need the permission first, to know which avatar we want to clear the camera for
9616 UUID agentID; 10243 UUID agentID;
9617 lock (m_host.TaskInventory) 10244 m_host.TaskInventory.LockItemsForRead(true);
10245 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10246 if (agentID == UUID.Zero)
9618 { 10247 {
9619 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10248 m_host.TaskInventory.LockItemsForRead(false);
9620 if (agentID == UUID.Zero) return; 10249 return;
9621 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10250 }
10251 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10252 {
10253 m_host.TaskInventory.LockItemsForRead(false);
10254 return;
9622 } 10255 }
10256 m_host.TaskInventory.LockItemsForRead(false);
9623 10257
9624 ScenePresence presence = World.GetScenePresence(agentID); 10258 ScenePresence presence = World.GetScenePresence(agentID);
9625 10259
@@ -9686,19 +10320,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9686 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10320 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9687 { 10321 {
9688 m_host.AddScriptLPS(1); 10322 m_host.AddScriptLPS(1);
9689 string ret = String.Empty; 10323
9690 string src1 = llBase64ToString(str1); 10324 if (str1 == String.Empty)
9691 string src2 = llBase64ToString(str2); 10325 return String.Empty;
9692 int c = 0; 10326 if (str2 == String.Empty)
9693 for (int i = 0; i < src1.Length; i++) 10327 return str1;
10328
10329 int len = str2.Length;
10330 if ((len % 4) != 0) // LL is EVIL!!!!
10331 {
10332 while (str2.EndsWith("="))
10333 str2 = str2.Substring(0, str2.Length - 1);
10334
10335 len = str2.Length;
10336 int mod = len % 4;
10337
10338 if (mod == 1)
10339 str2 = str2.Substring(0, str2.Length - 1);
10340 else if (mod == 2)
10341 str2 += "==";
10342 else if (mod == 3)
10343 str2 += "=";
10344 }
10345
10346 byte[] data1;
10347 byte[] data2;
10348 try
10349 {
10350 data1 = Convert.FromBase64String(str1);
10351 data2 = Convert.FromBase64String(str2);
10352 }
10353 catch (Exception)
10354 {
10355 return new LSL_String(String.Empty);
10356 }
10357
10358 byte[] d2 = new Byte[data1.Length];
10359 int pos = 0;
10360
10361 if (data1.Length <= data2.Length)
9694 { 10362 {
9695 ret += (char) (src1[i] ^ src2[c]); 10363 Array.Copy(data2, 0, d2, 0, data1.Length);
10364 }
10365 else
10366 {
10367 while (pos < data1.Length)
10368 {
10369 len = data1.Length - pos;
10370 if (len > data2.Length)
10371 len = data2.Length;
9696 10372
9697 c++; 10373 Array.Copy(data2, 0, d2, pos, len);
9698 if (c >= src2.Length) 10374 pos += len;
9699 c = 0; 10375 }
9700 } 10376 }
9701 return llStringToBase64(ret); 10377
10378 for (pos = 0 ; pos < data1.Length ; pos++ )
10379 data1[pos] ^= d2[pos];
10380
10381 return Convert.ToBase64String(data1);
9702 } 10382 }
9703 10383
9704 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10384 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9757,12 +10437,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9757 Regex r = new Regex(authregex); 10437 Regex r = new Regex(authregex);
9758 int[] gnums = r.GetGroupNumbers(); 10438 int[] gnums = r.GetGroupNumbers();
9759 Match m = r.Match(url); 10439 Match m = r.Match(url);
9760 if (m.Success) { 10440 if (m.Success)
9761 for (int i = 1; i < gnums.Length; i++) { 10441 {
10442 for (int i = 1; i < gnums.Length; i++)
10443 {
9762 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10444 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9763 //CaptureCollection cc = g.Captures; 10445 //CaptureCollection cc = g.Captures;
9764 } 10446 }
9765 if (m.Groups.Count == 5) { 10447 if (m.Groups.Count == 5)
10448 {
9766 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10449 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9767 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10450 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9768 } 10451 }
@@ -10048,15 +10731,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10048 10731
10049 internal UUID ScriptByName(string name) 10732 internal UUID ScriptByName(string name)
10050 { 10733 {
10051 lock (m_host.TaskInventory) 10734 m_host.TaskInventory.LockItemsForRead(true);
10735
10736 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10052 { 10737 {
10053 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10738 if (item.Type == 10 && item.Name == name)
10054 { 10739 {
10055 if (item.Type == 10 && item.Name == name) 10740 m_host.TaskInventory.LockItemsForRead(false);
10056 return item.ItemID; 10741 return item.ItemID;
10057 } 10742 }
10058 } 10743 }
10059 10744
10745 m_host.TaskInventory.LockItemsForRead(false);
10746
10060 return UUID.Zero; 10747 return UUID.Zero;
10061 } 10748 }
10062 10749
@@ -10097,6 +10784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10097 { 10784 {
10098 m_host.AddScriptLPS(1); 10785 m_host.AddScriptLPS(1);
10099 10786
10787 //Clone is thread safe
10100 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10788 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10101 10789
10102 UUID assetID = UUID.Zero; 10790 UUID assetID = UUID.Zero;
@@ -10159,6 +10847,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10159 { 10847 {
10160 m_host.AddScriptLPS(1); 10848 m_host.AddScriptLPS(1);
10161 10849
10850 //Clone is thread safe
10162 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10851 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10163 10852
10164 UUID assetID = UUID.Zero; 10853 UUID assetID = UUID.Zero;
@@ -10239,15 +10928,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10239 return GetLinkPrimitiveParams(obj, rules); 10928 return GetLinkPrimitiveParams(obj, rules);
10240 } 10929 }
10241 10930
10242 public void print(string str) 10931 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10243 { 10932 {
10244 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10933 List<SceneObjectPart> parts = GetLinkParts(link);
10245 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10934 if (parts.Count < 1)
10246 if (ossl != null) 10935 return 0;
10247 { 10936
10248 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10937 return GetNumberOfSides(parts[0]);
10249 m_log.Info("LSL print():" + str);
10250 }
10251 } 10938 }
10252 10939
10253 private string Name2Username(string name) 10940 private string Name2Username(string name)
@@ -10293,6 +10980,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10293 return rq.ToString(); 10980 return rq.ToString();
10294 } 10981 }
10295 10982
10983 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
10984 {
10985 m_SayShoutCount = 0;
10986 }
10296 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 10987 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10297 { 10988 {
10298 m_host.AddScriptLPS(1); 10989 m_host.AddScriptLPS(1);
@@ -10462,22 +11153,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10462 NotImplemented("llGetSPMaxMemory"); 11153 NotImplemented("llGetSPMaxMemory");
10463 } 11154 }
10464 11155
10465 public void llGetUsedMemory() 11156 public virtual LSL_Integer llGetUsedMemory()
10466 { 11157 {
10467 m_host.AddScriptLPS(1); 11158 m_host.AddScriptLPS(1);
10468 NotImplemented("llGetUsedMemory"); 11159 NotImplemented("llGetUsedMemory");
11160 return 0;
10469 } 11161 }
10470 11162
10471 public void llScriptProfiler(LSL_Integer flags) 11163 public void llScriptProfiler(LSL_Integer flags)
10472 { 11164 {
10473 m_host.AddScriptLPS(1); 11165 m_host.AddScriptLPS(1);
10474 NotImplemented("llScriptProfiler"); 11166 //NotImplemented("llScriptProfiler");
10475 } 11167 }
10476 11168
10477 public void llSetSoundQueueing(int queue) 11169 public void llSetSoundQueueing(int queue)
10478 { 11170 {
10479 m_host.AddScriptLPS(1); 11171 m_host.AddScriptLPS(1);
10480 NotImplemented("llSetSoundQueueing");
10481 } 11172 }
10482 11173
10483 public void llCollisionSprite(string impact_sprite) 11174 public void llCollisionSprite(string impact_sprite)
@@ -10489,7 +11180,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10489 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11180 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10490 { 11181 {
10491 m_host.AddScriptLPS(1); 11182 m_host.AddScriptLPS(1);
10492 NotImplemented("llGodLikeRezObject"); 11183
11184 if (!World.Permissions.IsGod(m_host.OwnerID))
11185 NotImplemented("llGodLikeRezObject");
11186
11187 AssetBase rezAsset = World.AssetService.Get(inventory);
11188 if (rezAsset == null)
11189 {
11190 llSay(0, "Asset not found");
11191 return;
11192 }
11193
11194 SceneObjectGroup group = null;
11195
11196 try
11197 {
11198 string xmlData = Utils.BytesToString(rezAsset.Data);
11199 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11200 }
11201 catch
11202 {
11203 llSay(0, "Asset not found");
11204 return;
11205 }
11206
11207 if (group == null)
11208 {
11209 llSay(0, "Asset not found");
11210 return;
11211 }
11212
11213 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11214 group.RootPart.AttachOffset = group.AbsolutePosition;
11215
11216 group.ResetIDs();
11217
11218 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11219 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11220 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11221 group.ScheduleGroupForFullUpdate();
11222
11223 // objects rezzed with this method are die_at_edge by default.
11224 group.RootPart.SetDieAtEdge(true);
11225
11226 group.ResumeScripts();
11227
11228 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11229 "object_rez", new Object[] {
11230 new LSL_String(
11231 group.RootPart.UUID.ToString()) },
11232 new DetectParams[0]));
10493 } 11233 }
10494 11234
10495 #endregion 11235 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 3ddd79b..9ec8a42 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
136 internal float m_ScriptDelayFactor = 1.0f; 136 internal float m_ScriptDelayFactor = 1.0f;
137 internal float m_ScriptDistanceFactor = 1.0f; 137 internal float m_ScriptDistanceFactor = 1.0f;
138 internal bool m_debuggerSafe = false;
138 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 139 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
139 140
140 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -143,6 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 m_host = host; 144 m_host = host;
144 m_localID = localID; 145 m_localID = localID;
145 m_itemID = itemID; 146 m_itemID = itemID;
147 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 148
147 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
148 m_OSFunctionsEnabled = true; 150 m_OSFunctionsEnabled = true;
@@ -201,7 +203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 203
202 internal void OSSLError(string msg) 204 internal void OSSLError(string msg)
203 { 205 {
204 throw new Exception("OSSL Runtime Error: " + msg); 206 if (m_debuggerSafe)
207 {
208 OSSLShoutError(msg);
209 }
210 else
211 {
212 throw new Exception("OSSL Runtime Error: " + msg);
213 }
205 } 214 }
206 215
207 private void InitLSL() 216 private void InitLSL()
@@ -833,18 +842,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
833 if (target != null) 842 if (target != null)
834 { 843 {
835 UUID animID=UUID.Zero; 844 UUID animID=UUID.Zero;
836 lock (m_host.TaskInventory) 845 m_host.TaskInventory.LockItemsForRead(true);
846 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
837 { 847 {
838 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 848 if (inv.Value.Name == animation)
839 { 849 {
840 if (inv.Value.Name == animation) 850 if (inv.Value.Type == (int)AssetType.Animation)
841 { 851 animID = inv.Value.AssetID;
842 if (inv.Value.Type == (int)AssetType.Animation) 852 continue;
843 animID = inv.Value.AssetID;
844 continue;
845 }
846 } 853 }
847 } 854 }
855 m_host.TaskInventory.LockItemsForRead(false);
848 if (animID == UUID.Zero) 856 if (animID == UUID.Zero)
849 target.Animator.AddAnimation(animation, m_host.UUID); 857 target.Animator.AddAnimation(animation, m_host.UUID);
850 else 858 else
@@ -866,18 +874,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
866 if (target != null) 874 if (target != null)
867 { 875 {
868 UUID animID = UUID.Zero; 876 UUID animID = UUID.Zero;
869 lock (m_host.TaskInventory) 877 m_host.TaskInventory.LockItemsForRead(true);
878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
870 { 879 {
871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 880 if (inv.Value.Name == animation)
872 { 881 {
873 if (inv.Value.Name == animation) 882 if (inv.Value.Type == (int)AssetType.Animation)
874 { 883 animID = inv.Value.AssetID;
875 if (inv.Value.Type == (int)AssetType.Animation) 884 continue;
876 animID = inv.Value.AssetID;
877 continue;
878 }
879 } 885 }
880 } 886 }
887 m_host.TaskInventory.LockItemsForRead(false);
881 888
882 if (animID == UUID.Zero) 889 if (animID == UUID.Zero)
883 target.Animator.RemoveAnimation(animation); 890 target.Animator.RemoveAnimation(animation);
@@ -1827,6 +1834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1827 1834
1828 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1835 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1829 { 1836 {
1837 m_host.TaskInventory.LockItemsForRead(true);
1830 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1838 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1831 { 1839 {
1832 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1840 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1834,6 +1842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1834 assetID = item.AssetID; 1842 assetID = item.AssetID;
1835 } 1843 }
1836 } 1844 }
1845 m_host.TaskInventory.LockItemsForRead(false);
1837 } 1846 }
1838 1847
1839 if (assetID == UUID.Zero) 1848 if (assetID == UUID.Zero)
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 4d7d60d..7c388fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -122,6 +122,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
122 LSL_Float llGetEnergy(); 122 LSL_Float llGetEnergy();
123 LSL_Vector llGetForce(); 123 LSL_Vector llGetForce();
124 LSL_Integer llGetFreeMemory(); 124 LSL_Integer llGetFreeMemory();
125 LSL_Integer llGetUsedMemory();
125 LSL_Integer llGetFreeURLs(); 126 LSL_Integer llGetFreeURLs();
126 LSL_Vector llGetGeometricCenter(); 127 LSL_Vector llGetGeometricCenter();
127 LSL_Float llGetGMTclock(); 128 LSL_Float llGetGMTclock();
@@ -404,7 +405,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
404 LSL_Vector llWind(LSL_Vector offset); 405 LSL_Vector llWind(LSL_Vector offset);
405 LSL_String llXorBase64Strings(string str1, string str2); 406 LSL_String llXorBase64Strings(string str1, string str2);
406 LSL_String llXorBase64StringsCorrect(string str1, string str2); 407 LSL_String llXorBase64StringsCorrect(string str1, string str2);
407 void print(string str); 408 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
408 409
409 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
410 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 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 87cfe1a..5ddba60 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 e82c281..59eaccb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 96e46fd..ca54862 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
@@ -459,6 +461,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
459 return m_LSL_Functions.llGetFreeMemory(); 461 return m_LSL_Functions.llGetFreeMemory();
460 } 462 }
461 463
464 public LSL_Integer llGetUsedMemory()
465 {
466 return m_LSL_Functions.llGetUsedMemory();
467 }
468
462 public LSL_Integer llGetFreeURLs() 469 public LSL_Integer llGetFreeURLs()
463 { 470 {
464 return m_LSL_Functions.llGetFreeURLs(); 471 return m_LSL_Functions.llGetFreeURLs();
@@ -1873,9 +1880,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1873 return m_LSL_Functions.llClearPrimMedia(face); 1880 return m_LSL_Functions.llClearPrimMedia(face);
1874 } 1881 }
1875 1882
1876 public void print(string str) 1883 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1877 { 1884 {
1878 m_LSL_Functions.print(str); 1885 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1879 } 1886 }
1880 } 1887 }
1881} 1888}
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 6e9f3ec..cf25189 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 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 c443669..9cb074a 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -269,43 +337,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
269 337
270 public void RemoveRegion(Scene scene) 338 public void RemoveRegion(Scene scene)
271 { 339 {
272 lock (m_Scripts) 340 lockScriptsForRead(true);
341 foreach (IScriptInstance instance in m_Scripts.Values)
273 { 342 {
274 foreach (IScriptInstance instance in m_Scripts.Values) 343 // Force a final state save
344 //
345 if (m_Assemblies.ContainsKey(instance.AssetID))
275 { 346 {
276 // Force a final state save 347 string assembly = m_Assemblies[instance.AssetID];
277 // 348 instance.SaveState(assembly);
278 if (m_Assemblies.ContainsKey(instance.AssetID)) 349 }
279 {
280 string assembly = m_Assemblies[instance.AssetID];
281 instance.SaveState(assembly);
282 }
283 350
284 // Clear the event queue and abort the instance thread 351 // Clear the event queue and abort the instance thread
285 // 352 //
286 instance.ClearQueue(); 353 instance.ClearQueue();
287 instance.Stop(0); 354 instance.Stop(0);
288 355
289 // Release events, timer, etc 356 // Release events, timer, etc
290 // 357 //
291 instance.DestroyScriptInstance(); 358 instance.DestroyScriptInstance();
292 359
293 // Unload scripts and app domains 360 // Unload scripts and app domains
294 // Must be done explicitly because they have infinite 361 // Must be done explicitly because they have infinite
295 // lifetime 362 // lifetime
296 // 363 //
297 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 364 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
298 if (m_DomainScripts[instance.AppDomain].Count == 0) 365 if (m_DomainScripts[instance.AppDomain].Count == 0)
299 { 366 {
300 m_DomainScripts.Remove(instance.AppDomain); 367 m_DomainScripts.Remove(instance.AppDomain);
301 UnloadAppDomain(instance.AppDomain); 368 UnloadAppDomain(instance.AppDomain);
302 }
303 } 369 }
304 m_Scripts.Clear();
305 m_PrimObjects.Clear();
306 m_Assemblies.Clear();
307 m_DomainScripts.Clear();
308 } 370 }
371 lockScriptsForRead(false);
372 lockScriptsForWrite(true);
373 m_Scripts.Clear();
374 lockScriptsForWrite(false);
375 m_PrimObjects.Clear();
376 m_Assemblies.Clear();
377 m_DomainScripts.Clear();
378
309 lock (m_ScriptEngines) 379 lock (m_ScriptEngines)
310 { 380 {
311 m_ScriptEngines.Remove(this); 381 m_ScriptEngines.Remove(this);
@@ -364,22 +434,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
364 434
365 List<IScriptInstance> instances = new List<IScriptInstance>(); 435 List<IScriptInstance> instances = new List<IScriptInstance>();
366 436
367 lock (m_Scripts) 437 lockScriptsForRead(true);
368 { 438 foreach (IScriptInstance instance in m_Scripts.Values)
369 foreach (IScriptInstance instance in m_Scripts.Values)
370 instances.Add(instance); 439 instances.Add(instance);
371 } 440 lockScriptsForRead(false);
372 441
373 foreach (IScriptInstance i in instances) 442 foreach (IScriptInstance i in instances)
374 { 443 {
375 string assembly = String.Empty; 444 string assembly = String.Empty;
376 445
377 lock (m_Scripts) 446
378 {
379 if (!m_Assemblies.ContainsKey(i.AssetID)) 447 if (!m_Assemblies.ContainsKey(i.AssetID))
380 continue; 448 continue;
381 assembly = m_Assemblies[i.AssetID]; 449 assembly = m_Assemblies[i.AssetID];
382 } 450
383 451
384 i.SaveState(assembly); 452 i.SaveState(assembly);
385 } 453 }
@@ -713,92 +781,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
713 } 781 }
714 782
715 ScriptInstance instance = null; 783 ScriptInstance instance = null;
716 lock (m_Scripts) 784 // Create the object record
785 lockScriptsForRead(true);
786 if ((!m_Scripts.ContainsKey(itemID)) ||
787 (m_Scripts[itemID].AssetID != assetID))
717 { 788 {
718 // Create the object record 789 lockScriptsForRead(false);
719 790
720 if ((!m_Scripts.ContainsKey(itemID)) || 791 UUID appDomain = assetID;
721 (m_Scripts[itemID].AssetID != assetID))
722 {
723 UUID appDomain = assetID;
724 792
725 if (part.ParentGroup.IsAttachment) 793 if (part.ParentGroup.IsAttachment)
726 appDomain = part.ParentGroup.RootPart.UUID; 794 appDomain = part.ParentGroup.RootPart.UUID;
727 795
728 if (!m_AppDomains.ContainsKey(appDomain)) 796 if (!m_AppDomains.ContainsKey(appDomain))
797 {
798 try
729 { 799 {
730 try 800 AppDomainSetup appSetup = new AppDomainSetup();
731 { 801 appSetup.PrivateBinPath = Path.Combine(
732 AppDomainSetup appSetup = new AppDomainSetup(); 802 m_ScriptEnginesPath,
733 appSetup.PrivateBinPath = Path.Combine( 803 m_Scene.RegionInfo.RegionID.ToString());
734 m_ScriptEnginesPath, 804
735 m_Scene.RegionInfo.RegionID.ToString()); 805 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
736 806 Evidence evidence = new Evidence(baseEvidence);
737 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 807
738 Evidence evidence = new Evidence(baseEvidence); 808 AppDomain sandbox;
739 809 if (m_AppDomainLoading)
740 AppDomain sandbox; 810 sandbox = AppDomain.CreateDomain(
741 if (m_AppDomainLoading) 811 m_Scene.RegionInfo.RegionID.ToString(),
742 sandbox = AppDomain.CreateDomain( 812 evidence, appSetup);
743 m_Scene.RegionInfo.RegionID.ToString(), 813 else
744 evidence, appSetup); 814 sandbox = AppDomain.CurrentDomain;
745 else 815
746 sandbox = AppDomain.CurrentDomain; 816 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
747 817 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
748 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 818 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
749 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 819 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
750 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 820 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
751 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 821 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
752 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 822 //sandbox.SetAppDomainPolicy(sandboxPolicy);
753 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 823
754 //sandbox.SetAppDomainPolicy(sandboxPolicy); 824 m_AppDomains[appDomain] = sandbox;
755 825
756 m_AppDomains[appDomain] = sandbox; 826 m_AppDomains[appDomain].AssemblyResolve +=
757 827 new ResolveEventHandler(
758 m_AppDomains[appDomain].AssemblyResolve += 828 AssemblyResolver.OnAssemblyResolve);
759 new ResolveEventHandler( 829 m_DomainScripts[appDomain] = new List<UUID>();
760 AssemblyResolver.OnAssemblyResolve); 830 }
761 m_DomainScripts[appDomain] = new List<UUID>(); 831 catch (Exception e)
762 } 832 {
763 catch (Exception e) 833 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
834 m_ScriptErrorMessage += "Exception creating app domain:\n";
835 m_ScriptFailCount++;
836 lock (m_AddingAssemblies)
764 { 837 {
765 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 838 m_AddingAssemblies[assembly]--;
766 m_ScriptErrorMessage += "Exception creating app domain:\n";
767 m_ScriptFailCount++;
768 lock (m_AddingAssemblies)
769 {
770 m_AddingAssemblies[assembly]--;
771 }
772 return false;
773 } 839 }
840 return false;
774 } 841 }
775 m_DomainScripts[appDomain].Add(itemID); 842 }
776 843 m_DomainScripts[appDomain].Add(itemID);
777 instance = new ScriptInstance(this, part, 844
778 itemID, assetID, assembly, 845 instance = new ScriptInstance(this, part,
779 m_AppDomains[appDomain], 846 itemID, assetID, assembly,
780 part.ParentGroup.RootPart.Name, 847 m_AppDomains[appDomain],
781 item.Name, startParam, postOnRez, 848 part.ParentGroup.RootPart.Name,
782 stateSource, m_MaxScriptQueue); 849 item.Name, startParam, postOnRez,
783 850 stateSource, m_MaxScriptQueue);
784 m_log.DebugFormat( 851
852 m_log.DebugFormat(
785 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 853 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
786 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 854 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
787 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 855 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
788 856
789 if (presence != null) 857 if (presence != null)
790 { 858 {
791 ShowScriptSaveResponse(item.OwnerID, 859 ShowScriptSaveResponse(item.OwnerID,
792 assetID, "Compile successful", true); 860 assetID, "Compile successful", true);
793 }
794
795 instance.AppDomain = appDomain;
796 instance.LineMap = linemap;
797
798 m_Scripts[itemID] = instance;
799 } 861 }
800 }
801 862
863 instance.AppDomain = appDomain;
864 instance.LineMap = linemap;
865 lockScriptsForWrite(true);
866 m_Scripts[itemID] = instance;
867 lockScriptsForWrite(false);
868 }
869 else
870 {
871 lockScriptsForRead(false);
872 }
802 lock (m_PrimObjects) 873 lock (m_PrimObjects)
803 { 874 {
804 if (!m_PrimObjects.ContainsKey(localID)) 875 if (!m_PrimObjects.ContainsKey(localID))
@@ -817,9 +888,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
817 m_AddingAssemblies[assembly]--; 888 m_AddingAssemblies[assembly]--;
818 } 889 }
819 890
820 if (instance != null) 891 if (instance!=null)
821 instance.Init(); 892 instance.Init();
822 893
823 return true; 894 return true;
824 } 895 }
825 896
@@ -832,20 +903,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
832 m_CompileDict.Remove(itemID); 903 m_CompileDict.Remove(itemID);
833 } 904 }
834 905
835 IScriptInstance instance = null; 906 lockScriptsForRead(true);
836 907 // Do we even have it?
837 lock (m_Scripts) 908 if (!m_Scripts.ContainsKey(itemID))
838 { 909 {
839 // Do we even have it? 910 lockScriptsForRead(false);
840 if (!m_Scripts.ContainsKey(itemID)) 911 return;
841 return;
842
843 instance=m_Scripts[itemID];
844 m_Scripts.Remove(itemID);
845 } 912 }
913
846 914
915 IScriptInstance instance=m_Scripts[itemID];
916 lockScriptsForRead(false);
917 lockScriptsForWrite(true);
918 m_Scripts.Remove(itemID);
919 lockScriptsForWrite(false);
847 instance.ClearQueue(); 920 instance.ClearQueue();
848 instance.Stop(0); 921 instance.Stop(0);
922
849// bool objectRemoved = false; 923// bool objectRemoved = false;
850 924
851 lock (m_PrimObjects) 925 lock (m_PrimObjects)
@@ -881,11 +955,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
881 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 955 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
882 if (handlerObjectRemoved != null) 956 if (handlerObjectRemoved != null)
883 { 957 {
884 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 958 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
885 handlerObjectRemoved(part.UUID); 959 handlerObjectRemoved(part.UUID);
886 } 960 }
887 961
888 962 CleanAssemblies();
963
889 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 964 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
890 if (handlerScriptRemoved != null) 965 if (handlerScriptRemoved != null)
891 handlerScriptRemoved(itemID); 966 handlerScriptRemoved(itemID);
@@ -1027,7 +1102,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1027 return false; 1102 return false;
1028 1103
1029 uuids = m_PrimObjects[localID]; 1104 uuids = m_PrimObjects[localID];
1030 } 1105
1031 1106
1032 foreach (UUID itemID in uuids) 1107 foreach (UUID itemID in uuids)
1033 { 1108 {
@@ -1045,6 +1120,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1045 result = true; 1120 result = true;
1046 } 1121 }
1047 } 1122 }
1123 }
1048 1124
1049 return result; 1125 return result;
1050 } 1126 }
@@ -1144,12 +1220,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1144 private IScriptInstance GetInstance(UUID itemID) 1220 private IScriptInstance GetInstance(UUID itemID)
1145 { 1221 {
1146 IScriptInstance instance; 1222 IScriptInstance instance;
1147 lock (m_Scripts) 1223 lockScriptsForRead(true);
1224 if (!m_Scripts.ContainsKey(itemID))
1148 { 1225 {
1149 if (!m_Scripts.ContainsKey(itemID)) 1226 lockScriptsForRead(false);
1150 return null; 1227 return null;
1151 instance = m_Scripts[itemID];
1152 } 1228 }
1229 instance = m_Scripts[itemID];
1230 lockScriptsForRead(false);
1153 return instance; 1231 return instance;
1154 } 1232 }
1155 1233
@@ -1173,6 +1251,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1173 return false; 1251 return false;
1174 } 1252 }
1175 1253
1254 [DebuggerNonUserCode]
1176 public void ApiResetScript(UUID itemID) 1255 public void ApiResetScript(UUID itemID)
1177 { 1256 {
1178 IScriptInstance instance = GetInstance(itemID); 1257 IScriptInstance instance = GetInstance(itemID);
@@ -1224,6 +1303,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1224 return UUID.Zero; 1303 return UUID.Zero;
1225 } 1304 }
1226 1305
1306 [DebuggerNonUserCode]
1227 public void SetState(UUID itemID, string newState) 1307 public void SetState(UUID itemID, string newState)
1228 { 1308 {
1229 IScriptInstance instance = GetInstance(itemID); 1309 IScriptInstance instance = GetInstance(itemID);
@@ -1244,11 +1324,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1244 { 1324 {
1245 List<IScriptInstance> instances = new List<IScriptInstance>(); 1325 List<IScriptInstance> instances = new List<IScriptInstance>();
1246 1326
1247 lock (m_Scripts) 1327 lockScriptsForRead(true);
1248 { 1328 foreach (IScriptInstance instance in m_Scripts.Values)
1249 foreach (IScriptInstance instance in m_Scripts.Values)
1250 instances.Add(instance); 1329 instances.Add(instance);
1251 } 1330 lockScriptsForRead(false);
1252 1331
1253 foreach (IScriptInstance i in instances) 1332 foreach (IScriptInstance i in instances)
1254 { 1333 {
@@ -1629,5 +1708,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1629 1708
1630 instance.Resume(); 1709 instance.Resume();
1631 } 1710 }
1711
1712 public bool HasScript(UUID itemID, out bool running)
1713 {
1714 running = true;
1715
1716 IScriptInstance instance = GetInstance(itemID);
1717 if (instance == null)
1718 return false;
1719
1720 running = instance.Running;
1721 return true;
1722 }
1632 } 1723 }
1633} 1724}