aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2245
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs90
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs359
19 files changed, 2131 insertions, 987 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 6c690e8..ebe276b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -275,40 +344,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
275 protected UUID InventorySelf() 344 protected UUID InventorySelf()
276 { 345 {
277 UUID invItemID = new UUID(); 346 UUID invItemID = new UUID();
278 347 bool unlock = false;
279 lock (m_host.TaskInventory) 348 if (!m_host.TaskInventory.IsReadLockedByMe())
349 {
350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
280 { 354 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
282 { 356 {
283 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 357 invItemID = inv.Key;
284 { 358 break;
285 invItemID = inv.Key;
286 break;
287 }
288 } 359 }
289 } 360 }
290 361 if (unlock)
362 {
363 m_host.TaskInventory.LockItemsForRead(false);
364 }
291 return invItemID; 365 return invItemID;
292 } 366 }
293 367
294 protected UUID InventoryKey(string name, int type) 368 protected UUID InventoryKey(string name, int type)
295 { 369 {
296 m_host.AddScriptLPS(1); 370 m_host.AddScriptLPS(1);
297 371 m_host.TaskInventory.LockItemsForRead(true);
298 lock (m_host.TaskInventory) 372
373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
299 { 374 {
300 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 375 if (inv.Value.Name == name)
301 { 376 {
302 if (inv.Value.Name == name) 377 m_host.TaskInventory.LockItemsForRead(false);
378
379 if (inv.Value.Type != type)
303 { 380 {
304 if (inv.Value.Type != type) 381 return UUID.Zero;
305 return UUID.Zero;
306
307 return inv.Value.AssetID;
308 } 382 }
383
384 return inv.Value.AssetID;
309 } 385 }
310 } 386 }
311 387
388 m_host.TaskInventory.LockItemsForRead(false);
312 return UUID.Zero; 389 return UUID.Zero;
313 } 390 }
314 391
@@ -316,17 +393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 { 393 {
317 m_host.AddScriptLPS(1); 394 m_host.AddScriptLPS(1);
318 395
319 lock (m_host.TaskInventory) 396
397 m_host.TaskInventory.LockItemsForRead(true);
398
399 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
320 { 400 {
321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 401 if (inv.Value.Name == name)
322 { 402 {
323 if (inv.Value.Name == name) 403 m_host.TaskInventory.LockItemsForRead(false);
324 { 404 return inv.Value.AssetID;
325 return inv.Value.AssetID;
326 }
327 } 405 }
328 } 406 }
329 407
408 m_host.TaskInventory.LockItemsForRead(false);
409
410
330 return UUID.Zero; 411 return UUID.Zero;
331 } 412 }
332 413
@@ -468,26 +549,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 549
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 550 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 551
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 552 // Utility function for llRot2Euler
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 553
554 // normalize an angle between -PI and PI (-180 to +180 degrees)
555 protected double NormalizeAngle(double angle)
556 {
557 if (angle > -Math.PI && angle < Math.PI)
558 return angle;
559
560 int numPis = (int)(Math.PI / angle);
561 double remainder = angle - Math.PI * numPis;
562 if (numPis % 2 == 1)
563 return Math.PI - angle;
564 return remainder;
565 }
473 566
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
475 { 568 {
476 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
479 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
480 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
481 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
482 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
483 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 577 double test = q1.x*q1.z + q1.y*q1.s;
485 Math.Atan2(n, Math.Sqrt(p)), 578 if (test > 0.4999*unit) { // singularity at north pole
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
487 else if (n > 0) 580 eul.y = Math.PI/2;
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 581 eul.x = 0;
489 else 582 return eul;
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
491 } 594 }
492 595
493 /* From wiki: 596 /* From wiki:
@@ -689,77 +792,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 792 {
690 //A and B should both be normalized 793 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 794 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 795 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 796 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 797
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 798 double dotProduct = LSL_Vector.Dot(a, b);
799 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
800 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
801 double angle = Math.Acos(dotProduct / magProduct);
802 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
803 double s = Math.Sin(angle / 2);
804
805 double x = axis.x * s;
806 double y = axis.y * s;
807 double z = axis.z * s;
808 double w = Math.Cos(angle / 2);
809
810 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812
813 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
814 */
815
816 // This method mimics the 180 errors found in SL
817 // See www.euclideanspace.com... angleBetween
818 LSL_Vector vec_a = a;
819 LSL_Vector vec_b = b;
820
821 // Eliminate zero length
822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
824 if (vec_a_mag < 0.00001 ||
825 vec_b_mag < 0.00001)
696 { 826 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 828 }
699 else 829
830 // Normalize
831 vec_a = llVecNorm(vec_a);
832 vec_b = llVecNorm(vec_b);
833
834 // Calculate axis and rotation angle
835 LSL_Vector axis = vec_a % vec_b;
836 LSL_Float cos_theta = vec_a * vec_b;
837
838 // Check if parallel
839 if (cos_theta > 0.99999)
700 { 840 {
701 a = LSL_Vector.Norm(a); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 842 }
703 double dotProduct = LSL_Vector.Dot(a, b); 843
704 // There are two degenerate cases possible. These are for vectors 180 or 844 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 845 else if (cos_theta < -0.99999)
706 // 846 {
707 // Check for vectors 180 degrees apart. 847 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 850 }
711 // First assume X axis is orthogonal to the vectors. 851 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 852 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 853 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 854 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 855 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 856 s = Math.Cos(theta);
717 { 857 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 858 x = axis.x * t;
719 } 859 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 860 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 861 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 862 }
760 return rotBetween;
761 } 863 }
762 864
763 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
764 { 866 {
765 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -779,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 881 {
780 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
781 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 891 {
784 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -801,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 909 {
802 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
803 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
804 if (text.Length > 1023) 918 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
806 920
@@ -1101,10 +1215,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1215 return detectedParams.TouchUV;
1102 } 1216 }
1103 1217
1218 [DebuggerNonUserCode]
1104 public virtual void llDie() 1219 public virtual void llDie()
1105 { 1220 {
1106 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1223 }
1109 1224
1110 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1292
1178 public void llSetStatus(int status, int value) 1293 public void llSetStatus(int status, int value)
1179 { 1294 {
1295 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1296 return;
1180 m_host.AddScriptLPS(1); 1297 m_host.AddScriptLPS(1);
1181 1298
1182 int statusrotationaxis = 0; 1299 int statusrotationaxis = 0;
@@ -1406,6 +1523,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1523 {
1407 m_host.AddScriptLPS(1); 1524 m_host.AddScriptLPS(1);
1408 1525
1526 SetColor(m_host, color, face);
1527 }
1528
1529 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1530 {
1531 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1532 return;
1533
1534 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part))
1537 {
1538 texcolor = tex.CreateFace((uint)face).RGBA;
1539 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1542 tex.FaceTextures[face].RGBA = texcolor;
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546 else if (face == ScriptBaseClass.ALL_SIDES)
1547 {
1548 for (uint i = 0; i < GetNumberOfSides(part); i++)
1549 {
1550 if (tex.FaceTextures[i] != null)
1551 {
1552 texcolor = tex.FaceTextures[i].RGBA;
1553 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1554 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1555 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1556 tex.FaceTextures[i].RGBA = texcolor;
1557 }
1558 texcolor = tex.DefaultTexture.RGBA;
1559 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1560 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1562 tex.DefaultTexture.RGBA = texcolor;
1563 }
1564 part.UpdateTexture(tex);
1565 return;
1566 }
1567
1409 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1411 1570
@@ -1414,6 +1573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1573
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1574 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1575 {
1576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1577 return;
1578
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1579 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1580 MappingType textype;
1419 textype = MappingType.Default; 1581 textype = MappingType.Default;
@@ -1444,6 +1606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1606
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1607 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1608 {
1609 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1610 return;
1611
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1612 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1613 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1614 {
@@ -1469,6 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1634
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1635 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1636 {
1637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1638 return;
1472 1639
1473 Shininess sval = new Shininess(); 1640 Shininess sval = new Shininess();
1474 1641
@@ -1519,6 +1686,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1686
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1687 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1688 {
1689 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1690 return;
1691
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1692 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1693 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1694 {
@@ -1579,13 +1749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1580 1750
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1752 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1753 {
1584 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1585 } 1765 }
1586 1766
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1773 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1640 { 1823 {
1641 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1825 return;
1643 1826
1644 if (flexi) 1827 if (flexi)
@@ -1673,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1673 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1674 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1675 { 1858 {
1676 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return; 1860 return;
1678 1861
1679 if (light) 1862 if (light)
@@ -1750,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1751 1934
1752 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1753 1936 if (parts.Count > 0)
1754 foreach (SceneObjectPart part in parts) 1937 {
1755 SetTexture(part, texture, face); 1938 try
1756 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1757 ScriptSleep(200); 1949 ScriptSleep(200);
1758 } 1950 }
1759 1951
1760 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1761 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1762 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1763 1958
1764 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1803,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1998
1804 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1805 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1806 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1807 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1808 { 2006 {
@@ -1839,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1839 2037
1840 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1841 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1842 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1843 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1844 { 2045 {
@@ -1875,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 2076
1876 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1877 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1878 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1879 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1880 { 2084 {
@@ -1958,10 +2162,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1958 return end; 2162 return end;
1959 } 2163 }
1960 2164
1961 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2165 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1962 { 2166 {
2167 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2168 return fromPos;
2169
1963 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2170 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1964 LSL_Vector currentPos = GetPartLocalPos(part); 2171
1965 2172
1966 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2173 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1967 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2174 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1970,14 +2177,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1970 { 2177 {
1971 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2178 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1972 targetPos.z = ground; 2179 targetPos.z = ground;
2180 }
2181 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2182
2183 return real_vec;
2184 }
2185
2186 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2187 {
2188 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2189 return;
2190
2191 LSL_Vector currentPos = GetPartLocalPos(part);
2192 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2193
2194 if (part.ParentGroup.RootPart == part)
2195 {
1973 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
1974 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2197 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1975 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1976 } 2198 }
1977 else 2199 else
1978 { 2200 {
1979 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2201 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1980 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1981 SceneObjectGroup parent = part.ParentGroup; 2202 SceneObjectGroup parent = part.ParentGroup;
1982 parent.HasGroupChanged = true; 2203 parent.HasGroupChanged = true;
1983 parent.ScheduleGroupForTerseUpdate(); 2204 parent.ScheduleGroupForTerseUpdate();
@@ -2028,9 +2249,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 m_host.AddScriptLPS(1); 2249 m_host.AddScriptLPS(1);
2029 2250
2030 // try to let this work as in SL... 2251 // try to let this work as in SL...
2031 if (m_host.ParentID == 0) 2252 if (m_host.LinkNum < 2)
2032 { 2253 {
2033 // special case: If we are root, rotate complete SOG to new rotation 2254 // Special case: If we are root, rotate complete SOG to new
2255 // rotation.
2256 // We are root if the link number is 0 (single prim) or 1
2257 // (root prim). ParentID may be nonzero in attachments and
2258 // using it would cause attachments and HUDs to rotate
2259 // to the wrong positions.
2034 SetRot(m_host, Rot2Quaternion(rot)); 2260 SetRot(m_host, Rot2Quaternion(rot));
2035 } 2261 }
2036 else 2262 else
@@ -2055,6 +2281,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 2281
2056 protected void SetRot(SceneObjectPart part, Quaternion rot) 2282 protected void SetRot(SceneObjectPart part, Quaternion rot)
2057 { 2283 {
2284 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2285 return;
2286
2058 part.UpdateRotation(rot); 2287 part.UpdateRotation(rot);
2059 // Update rotation does not move the object in the physics scene if it's a linkset. 2288 // Update rotation does not move the object in the physics scene if it's a linkset.
2060 2289
@@ -2678,12 +2907,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2678 2907
2679 m_host.AddScriptLPS(1); 2908 m_host.AddScriptLPS(1);
2680 2909
2910 m_host.TaskInventory.LockItemsForRead(true);
2681 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2911 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2682 2912 m_host.TaskInventory.LockItemsForRead(false);
2683 lock (m_host.TaskInventory)
2684 {
2685 item = m_host.TaskInventory[invItemID];
2686 }
2687 2913
2688 if (item.PermsGranter == UUID.Zero) 2914 if (item.PermsGranter == UUID.Zero)
2689 return 0; 2915 return 0;
@@ -2758,6 +2984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2758 if (dist > m_ScriptDistanceFactor * 10.0f) 2984 if (dist > m_ScriptDistanceFactor * 10.0f)
2759 return; 2985 return;
2760 2986
2987 //Clone is thread-safe
2761 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2988 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2762 2989
2763 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2990 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2818,6 +3045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2818 3045
2819 public void llLookAt(LSL_Vector target, double strength, double damping) 3046 public void llLookAt(LSL_Vector target, double strength, double damping)
2820 { 3047 {
3048 /*
2821 m_host.AddScriptLPS(1); 3049 m_host.AddScriptLPS(1);
2822 // Determine where we are looking from 3050 // Determine where we are looking from
2823 LSL_Vector from = llGetPos(); 3051 LSL_Vector from = llGetPos();
@@ -2837,10 +3065,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2837 // the angles of rotation in radians into rotation value 3065 // the angles of rotation in radians into rotation value
2838 3066
2839 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3067 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2840 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3068
2841 m_host.startLookAt(rotation, (float)damping, (float)strength); 3069 // This would only work if your physics system contains an APID controller:
3070 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3071 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3072
2842 // Orient the object to the angle calculated 3073 // Orient the object to the angle calculated
2843 //llSetRot(rot); 3074 llSetRot(rot);
3075 */
3076
3077 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3078 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3079 // http://bugs.meta7.com/view.php?id=28
3080 // - Tom
3081
3082 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3083 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3084 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3085 */
3086 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3087 {
3088 // Part is non-phys, convert this to a llSetRot()
3089 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3090 Vector3 dir = tgt - m_host.GroupPosition;
3091 dir.Normalize();
3092 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3093 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3094 float terot = (float)Math.Atan2(-dir.Z, txy);
3095 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3096 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3097 LSL_Types.Quaternion spin = llEuler2Rot(az);
3098 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3099 llSetRot(rot);
3100 }
3101 else
3102 {
3103 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3104 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3105 m_host.RotLookAt(q, (float)strength, (float)damping);
3106 }
3107
3108 }
3109
3110 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3111 {
3112 m_host.AddScriptLPS(1);
3113// NotImplemented("llRotLookAt");
3114 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3115
2844 } 3116 }
2845 3117
2846 public void llStopLookAt() 3118 public void llStopLookAt()
@@ -2889,13 +3161,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2889 { 3161 {
2890 TaskInventoryItem item; 3162 TaskInventoryItem item;
2891 3163
2892 lock (m_host.TaskInventory) 3164 m_host.TaskInventory.LockItemsForRead(true);
3165 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2893 { 3166 {
2894 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3167 m_host.TaskInventory.LockItemsForRead(false);
2895 return; 3168 return;
2896 else
2897 item = m_host.TaskInventory[InventorySelf()];
2898 } 3169 }
3170 else
3171 {
3172 item = m_host.TaskInventory[InventorySelf()];
3173 }
3174 m_host.TaskInventory.LockItemsForRead(false);
2899 3175
2900 if (item.PermsGranter != UUID.Zero) 3176 if (item.PermsGranter != UUID.Zero)
2901 { 3177 {
@@ -2917,13 +3193,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2917 { 3193 {
2918 TaskInventoryItem item; 3194 TaskInventoryItem item;
2919 3195
3196 m_host.TaskInventory.LockItemsForRead(true);
2920 lock (m_host.TaskInventory) 3197 lock (m_host.TaskInventory)
2921 { 3198 {
3199
2922 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3200 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3201 {
3202 m_host.TaskInventory.LockItemsForRead(false);
2923 return; 3203 return;
3204 }
2924 else 3205 else
3206 {
2925 item = m_host.TaskInventory[InventorySelf()]; 3207 item = m_host.TaskInventory[InventorySelf()];
3208 }
2926 } 3209 }
3210 m_host.TaskInventory.LockItemsForRead(false);
2927 3211
2928 m_host.AddScriptLPS(1); 3212 m_host.AddScriptLPS(1);
2929 3213
@@ -2955,18 +3239,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2955 { 3239 {
2956 m_host.AddScriptLPS(1); 3240 m_host.AddScriptLPS(1);
2957 3241
2958// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2959// return;
2960
2961 TaskInventoryItem item; 3242 TaskInventoryItem item;
2962 3243
2963 lock (m_host.TaskInventory) 3244 m_host.TaskInventory.LockItemsForRead(true);
3245
3246 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2964 { 3247 {
2965 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3248 m_host.TaskInventory.LockItemsForRead(false);
2966 return; 3249 return;
2967 else
2968 item = m_host.TaskInventory[InventorySelf()];
2969 } 3250 }
3251 else
3252 {
3253 item = m_host.TaskInventory[InventorySelf()];
3254 }
3255
3256 m_host.TaskInventory.LockItemsForRead(false);
2970 3257
2971 if (item.PermsGranter != m_host.OwnerID) 3258 if (item.PermsGranter != m_host.OwnerID)
2972 return; 3259 return;
@@ -2992,13 +3279,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2992 3279
2993 TaskInventoryItem item; 3280 TaskInventoryItem item;
2994 3281
2995 lock (m_host.TaskInventory) 3282 m_host.TaskInventory.LockItemsForRead(true);
3283
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2996 { 3285 {
2997 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3286 m_host.TaskInventory.LockItemsForRead(false);
2998 return; 3287 return;
2999 else
3000 item = m_host.TaskInventory[InventorySelf()];
3001 } 3288 }
3289 else
3290 {
3291 item = m_host.TaskInventory[InventorySelf()];
3292 }
3293 m_host.TaskInventory.LockItemsForRead(false);
3294
3002 3295
3003 if (item.PermsGranter != m_host.OwnerID) 3296 if (item.PermsGranter != m_host.OwnerID)
3004 return; 3297 return;
@@ -3045,6 +3338,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3045 3338
3046 public void llInstantMessage(string user, string message) 3339 public void llInstantMessage(string user, string message)
3047 { 3340 {
3341 UUID result;
3342 if (!UUID.TryParse(user, out result))
3343 {
3344 ShoutError("An invalid key was passed to llInstantMessage");
3345 ScriptSleep(2000);
3346 return;
3347 }
3348
3349
3048 m_host.AddScriptLPS(1); 3350 m_host.AddScriptLPS(1);
3049 3351
3050 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3352 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3059,14 +3361,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3059 UUID friendTransactionID = UUID.Random(); 3361 UUID friendTransactionID = UUID.Random();
3060 3362
3061 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3363 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3062 3364
3063 GridInstantMessage msg = new GridInstantMessage(); 3365 GridInstantMessage msg = new GridInstantMessage();
3064 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3366 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3065 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3367 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3066 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3368 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3067// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3369// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3068// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3370// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3069 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3371// DateTime dt = DateTime.UtcNow;
3372//
3373// // Ticks from UtcNow, but make it look like local. Evil, huh?
3374// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3375//
3376// try
3377// {
3378// // Convert that to the PST timezone
3379// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3380// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3381// }
3382// catch
3383// {
3384// // No logging here, as it could be VERY spammy
3385// }
3386//
3387// // And make it look local again to fool the unix time util
3388// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3389
3390 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3391
3070 //if (client != null) 3392 //if (client != null)
3071 //{ 3393 //{
3072 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3394 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3080,12 +3402,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3080 msg.message = message.Substring(0, 1024); 3402 msg.message = message.Substring(0, 1024);
3081 else 3403 else
3082 msg.message = message; 3404 msg.message = message;
3083 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3405 msg.dialog = (byte)19; // MessageFromObject
3084 msg.fromGroup = false;// fromGroup; 3406 msg.fromGroup = false;// fromGroup;
3085 msg.offline = (byte)0; //offline; 3407 msg.offline = (byte)0; //offline;
3086 msg.ParentEstateID = 0; //ParentEstateID; 3408 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3087 msg.Position = new Vector3(m_host.AbsolutePosition); 3409 msg.Position = new Vector3(m_host.AbsolutePosition);
3088 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3410 msg.RegionID = World.RegionInfo.RegionID.Guid;
3089 msg.binaryBucket 3411 msg.binaryBucket
3090 = Util.StringToBytes256( 3412 = Util.StringToBytes256(
3091 "{0}/{1}/{2}/{3}", 3413 "{0}/{1}/{2}/{3}",
@@ -3113,7 +3435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3113 } 3435 }
3114 3436
3115 emailModule.SendEmail(m_host.UUID, address, subject, message); 3437 emailModule.SendEmail(m_host.UUID, address, subject, message);
3116 ScriptSleep(20000); 3438 ScriptSleep(15000);
3117 } 3439 }
3118 3440
3119 public void llGetNextEmail(string address, string subject) 3441 public void llGetNextEmail(string address, string subject)
@@ -3213,13 +3535,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3213 m_host.AddScriptLPS(1); 3535 m_host.AddScriptLPS(1);
3214 } 3536 }
3215 3537
3216 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3217 {
3218 m_host.AddScriptLPS(1);
3219 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3220 m_host.RotLookAt(rot, (float)strength, (float)damping);
3221 }
3222
3223 public LSL_Integer llStringLength(string str) 3538 public LSL_Integer llStringLength(string str)
3224 { 3539 {
3225 m_host.AddScriptLPS(1); 3540 m_host.AddScriptLPS(1);
@@ -3243,14 +3558,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3243 3558
3244 TaskInventoryItem item; 3559 TaskInventoryItem item;
3245 3560
3246 lock (m_host.TaskInventory) 3561 m_host.TaskInventory.LockItemsForRead(true);
3562 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3247 { 3563 {
3248 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3564 m_host.TaskInventory.LockItemsForRead(false);
3249 return; 3565 return;
3250 else
3251 item = m_host.TaskInventory[InventorySelf()];
3252 } 3566 }
3253 3567 else
3568 {
3569 item = m_host.TaskInventory[InventorySelf()];
3570 }
3571 m_host.TaskInventory.LockItemsForRead(false);
3254 if (item.PermsGranter == UUID.Zero) 3572 if (item.PermsGranter == UUID.Zero)
3255 return; 3573 return;
3256 3574
@@ -3280,13 +3598,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3280 3598
3281 TaskInventoryItem item; 3599 TaskInventoryItem item;
3282 3600
3283 lock (m_host.TaskInventory) 3601 m_host.TaskInventory.LockItemsForRead(true);
3602 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3284 { 3603 {
3285 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3604 m_host.TaskInventory.LockItemsForRead(false);
3286 return; 3605 return;
3287 else
3288 item = m_host.TaskInventory[InventorySelf()];
3289 } 3606 }
3607 else
3608 {
3609 item = m_host.TaskInventory[InventorySelf()];
3610 }
3611 m_host.TaskInventory.LockItemsForRead(false);
3612
3290 3613
3291 if (item.PermsGranter == UUID.Zero) 3614 if (item.PermsGranter == UUID.Zero)
3292 return; 3615 return;
@@ -3356,10 +3679,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3356 3679
3357 TaskInventoryItem item; 3680 TaskInventoryItem item;
3358 3681
3359 lock (m_host.TaskInventory) 3682
3683 m_host.TaskInventory.LockItemsForRead(true);
3684 if (!m_host.TaskInventory.ContainsKey(invItemID))
3685 {
3686 m_host.TaskInventory.LockItemsForRead(false);
3687 return;
3688 }
3689 else
3360 { 3690 {
3361 item = m_host.TaskInventory[invItemID]; 3691 item = m_host.TaskInventory[invItemID];
3362 } 3692 }
3693 m_host.TaskInventory.LockItemsForRead(false);
3363 3694
3364 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3695 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3365 { 3696 {
@@ -3387,15 +3718,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3387 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3718 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3388 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3719 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3389 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3720 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3721 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3390 ScriptBaseClass.PERMISSION_ATTACH; 3722 ScriptBaseClass.PERMISSION_ATTACH;
3391 3723
3392 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3724 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3393 { 3725 {
3394 lock (m_host.TaskInventory) 3726 m_host.TaskInventory.LockItemsForWrite(true);
3395 { 3727 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3396 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3728 m_host.TaskInventory[invItemID].PermsMask = perm;
3397 m_host.TaskInventory[invItemID].PermsMask = perm; 3729 m_host.TaskInventory.LockItemsForWrite(false);
3398 }
3399 3730
3400 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3731 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3401 "run_time_permissions", new Object[] { 3732 "run_time_permissions", new Object[] {
@@ -3405,28 +3736,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3405 return; 3736 return;
3406 } 3737 }
3407 } 3738 }
3408 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3739 else
3409 { 3740 {
3410 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3741 bool sitting = false;
3411 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3742 if (m_host.SitTargetAvatar == agentID)
3412 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3743 {
3413 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3744 sitting = true;
3414 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3745 }
3746 else
3747 {
3748 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3749 {
3750 if (p.SitTargetAvatar == agentID)
3751 sitting = true;
3752 }
3753 }
3415 3754
3416 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3755 if (sitting)
3417 { 3756 {
3418 lock (m_host.TaskInventory) 3757 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3758 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3759 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3760 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3761 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3762
3763 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3419 { 3764 {
3765 m_host.TaskInventory.LockItemsForWrite(true);
3420 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3766 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3421 m_host.TaskInventory[invItemID].PermsMask = perm; 3767 m_host.TaskInventory[invItemID].PermsMask = perm;
3422 } 3768 m_host.TaskInventory.LockItemsForWrite(false);
3423 3769
3424 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3770 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3425 "run_time_permissions", new Object[] { 3771 "run_time_permissions", new Object[] {
3426 new LSL_Integer(perm) }, 3772 new LSL_Integer(perm) },
3427 new DetectParams[0])); 3773 new DetectParams[0]));
3428 3774
3429 return; 3775 return;
3776 }
3430 } 3777 }
3431 } 3778 }
3432 3779
@@ -3440,11 +3787,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3440 3787
3441 if (!m_waitingForScriptAnswer) 3788 if (!m_waitingForScriptAnswer)
3442 { 3789 {
3443 lock (m_host.TaskInventory) 3790 m_host.TaskInventory.LockItemsForWrite(true);
3444 { 3791 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3445 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3792 m_host.TaskInventory[invItemID].PermsMask = 0;
3446 m_host.TaskInventory[invItemID].PermsMask = 0; 3793 m_host.TaskInventory.LockItemsForWrite(false);
3447 }
3448 3794
3449 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3795 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3450 m_waitingForScriptAnswer=true; 3796 m_waitingForScriptAnswer=true;
@@ -3479,10 +3825,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3479 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3825 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3480 llReleaseControls(); 3826 llReleaseControls();
3481 3827
3482 lock (m_host.TaskInventory) 3828
3483 { 3829 m_host.TaskInventory.LockItemsForWrite(true);
3484 m_host.TaskInventory[invItemID].PermsMask = answer; 3830 m_host.TaskInventory[invItemID].PermsMask = answer;
3485 } 3831 m_host.TaskInventory.LockItemsForWrite(false);
3832
3486 3833
3487 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3834 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3488 "run_time_permissions", new Object[] { 3835 "run_time_permissions", new Object[] {
@@ -3494,16 +3841,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3494 { 3841 {
3495 m_host.AddScriptLPS(1); 3842 m_host.AddScriptLPS(1);
3496 3843
3497 lock (m_host.TaskInventory) 3844 m_host.TaskInventory.LockItemsForRead(true);
3845
3846 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3498 { 3847 {
3499 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3848 if (item.Type == 10 && item.ItemID == m_itemID)
3500 { 3849 {
3501 if (item.Type == 10 && item.ItemID == m_itemID) 3850 m_host.TaskInventory.LockItemsForRead(false);
3502 { 3851 return item.PermsGranter.ToString();
3503 return item.PermsGranter.ToString();
3504 }
3505 } 3852 }
3506 } 3853 }
3854 m_host.TaskInventory.LockItemsForRead(false);
3507 3855
3508 return UUID.Zero.ToString(); 3856 return UUID.Zero.ToString();
3509 } 3857 }
@@ -3512,19 +3860,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 { 3860 {
3513 m_host.AddScriptLPS(1); 3861 m_host.AddScriptLPS(1);
3514 3862
3515 lock (m_host.TaskInventory) 3863 m_host.TaskInventory.LockItemsForRead(true);
3864
3865 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3516 { 3866 {
3517 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3867 if (item.Type == 10 && item.ItemID == m_itemID)
3518 { 3868 {
3519 if (item.Type == 10 && item.ItemID == m_itemID) 3869 int perms = item.PermsMask;
3520 { 3870 if (m_automaticLinkPermission)
3521 int perms = item.PermsMask; 3871 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3522 if (m_automaticLinkPermission) 3872 m_host.TaskInventory.LockItemsForRead(false);
3523 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3873 return perms;
3524 return perms;
3525 }
3526 } 3874 }
3527 } 3875 }
3876 m_host.TaskInventory.LockItemsForRead(false);
3528 3877
3529 return 0; 3878 return 0;
3530 } 3879 }
@@ -3546,9 +3895,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3546 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3895 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3547 { 3896 {
3548 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3897 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3549 3898 if (parts.Count > 0)
3550 foreach (SceneObjectPart part in parts) 3899 {
3551 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3900 try
3901 {
3902 parts[0].ParentGroup.areUpdatesSuspended = true;
3903 foreach (SceneObjectPart part in parts)
3904 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3905 }
3906 finally
3907 {
3908 parts[0].ParentGroup.areUpdatesSuspended = false;
3909 }
3910 }
3552 } 3911 }
3553 3912
3554 public void llCreateLink(string target, int parent) 3913 public void llCreateLink(string target, int parent)
@@ -3561,11 +3920,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3561 return; 3920 return;
3562 3921
3563 TaskInventoryItem item; 3922 TaskInventoryItem item;
3564 lock (m_host.TaskInventory) 3923 m_host.TaskInventory.LockItemsForRead(true);
3565 { 3924 item = m_host.TaskInventory[invItemID];
3566 item = m_host.TaskInventory[invItemID]; 3925 m_host.TaskInventory.LockItemsForRead(false);
3567 } 3926
3568
3569 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3927 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3570 && !m_automaticLinkPermission) 3928 && !m_automaticLinkPermission)
3571 { 3929 {
@@ -3582,11 +3940,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3582 3940
3583 if (targetPart.ParentGroup.AttachmentPoint != 0) 3941 if (targetPart.ParentGroup.AttachmentPoint != 0)
3584 return; // Fail silently if attached 3942 return; // Fail silently if attached
3943
3944 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3945 return;
3946
3585 SceneObjectGroup parentPrim = null, childPrim = null; 3947 SceneObjectGroup parentPrim = null, childPrim = null;
3586 3948
3587 if (targetPart != null) 3949 if (targetPart != null)
3588 { 3950 {
3589 if (parent != 0) { 3951 if (parent != 0)
3952 {
3590 parentPrim = m_host.ParentGroup; 3953 parentPrim = m_host.ParentGroup;
3591 childPrim = targetPart.ParentGroup; 3954 childPrim = targetPart.ParentGroup;
3592 } 3955 }
@@ -3618,16 +3981,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3618 m_host.AddScriptLPS(1); 3981 m_host.AddScriptLPS(1);
3619 UUID invItemID = InventorySelf(); 3982 UUID invItemID = InventorySelf();
3620 3983
3621 lock (m_host.TaskInventory) 3984 m_host.TaskInventory.LockItemsForRead(true);
3622 {
3623 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3985 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3624 && !m_automaticLinkPermission) 3986 && !m_automaticLinkPermission)
3625 { 3987 {
3626 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3988 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3989 m_host.TaskInventory.LockItemsForRead(false);
3627 return; 3990 return;
3628 } 3991 }
3629 } 3992 m_host.TaskInventory.LockItemsForRead(false);
3630 3993
3631 if (linknum < ScriptBaseClass.LINK_THIS) 3994 if (linknum < ScriptBaseClass.LINK_THIS)
3632 return; 3995 return;
3633 3996
@@ -3666,10 +4029,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3666 // Restructuring Multiple Prims. 4029 // Restructuring Multiple Prims.
3667 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4030 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3668 parts.Remove(parentPrim.RootPart); 4031 parts.Remove(parentPrim.RootPart);
3669 foreach (SceneObjectPart part in parts) 4032 if (parts.Count > 0)
3670 { 4033 {
3671 parentPrim.DelinkFromGroup(part.LocalId, true); 4034 try
4035 {
4036 parts[0].ParentGroup.areUpdatesSuspended = true;
4037 foreach (SceneObjectPart part in parts)
4038 {
4039 parentPrim.DelinkFromGroup(part.LocalId, true);
4040 }
4041 }
4042 finally
4043 {
4044 parts[0].ParentGroup.areUpdatesSuspended = false;
4045 }
3672 } 4046 }
4047
3673 parentPrim.HasGroupChanged = true; 4048 parentPrim.HasGroupChanged = true;
3674 parentPrim.ScheduleGroupForFullUpdate(); 4049 parentPrim.ScheduleGroupForFullUpdate();
3675 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4050 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3678,11 +4053,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3678 { 4053 {
3679 SceneObjectPart newRoot = parts[0]; 4054 SceneObjectPart newRoot = parts[0];
3680 parts.Remove(newRoot); 4055 parts.Remove(newRoot);
3681 foreach (SceneObjectPart part in parts) 4056
4057 try
3682 { 4058 {
3683 part.UpdateFlag = 0; 4059 parts[0].ParentGroup.areUpdatesSuspended = true;
3684 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4060 foreach (SceneObjectPart part in parts)
4061 {
4062 part.UpdateFlag = 0;
4063 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4064 }
3685 } 4065 }
4066 finally
4067 {
4068 parts[0].ParentGroup.areUpdatesSuspended = false;
4069 }
4070
4071
3686 newRoot.ParentGroup.HasGroupChanged = true; 4072 newRoot.ParentGroup.HasGroupChanged = true;
3687 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4073 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3688 } 4074 }
@@ -3702,6 +4088,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3702 public void llBreakAllLinks() 4088 public void llBreakAllLinks()
3703 { 4089 {
3704 m_host.AddScriptLPS(1); 4090 m_host.AddScriptLPS(1);
4091
4092 UUID invItemID = InventorySelf();
4093
4094 TaskInventoryItem item;
4095 m_host.TaskInventory.LockItemsForRead(true);
4096 item = m_host.TaskInventory[invItemID];
4097 m_host.TaskInventory.LockItemsForRead(false);
4098
4099 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4100 && !m_automaticLinkPermission)
4101 {
4102 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4103 return;
4104 }
4105
3705 SceneObjectGroup parentPrim = m_host.ParentGroup; 4106 SceneObjectGroup parentPrim = m_host.ParentGroup;
3706 if (parentPrim.AttachmentPoint != 0) 4107 if (parentPrim.AttachmentPoint != 0)
3707 return; // Fail silently if attached 4108 return; // Fail silently if attached
@@ -3747,6 +4148,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3747 } 4148 }
3748 else 4149 else
3749 { 4150 {
4151 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4152 {
4153 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4154
4155 if (linknum < 0)
4156 return UUID.Zero.ToString();
4157
4158 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4159 if (avatars.Count > linknum)
4160 {
4161 return avatars[linknum].UUID.ToString();
4162 }
4163 }
3750 return UUID.Zero.ToString(); 4164 return UUID.Zero.ToString();
3751 } 4165 }
3752 } 4166 }
@@ -3845,17 +4259,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3845 m_host.AddScriptLPS(1); 4259 m_host.AddScriptLPS(1);
3846 int count = 0; 4260 int count = 0;
3847 4261
3848 lock (m_host.TaskInventory) 4262 m_host.TaskInventory.LockItemsForRead(true);
4263 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3849 { 4264 {
3850 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4265 if (inv.Value.Type == type || type == -1)
3851 { 4266 {
3852 if (inv.Value.Type == type || type == -1) 4267 count = count + 1;
3853 {
3854 count = count + 1;
3855 }
3856 } 4268 }
3857 } 4269 }
3858 4270
4271 m_host.TaskInventory.LockItemsForRead(false);
3859 return count; 4272 return count;
3860 } 4273 }
3861 4274
@@ -3864,16 +4277,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3864 m_host.AddScriptLPS(1); 4277 m_host.AddScriptLPS(1);
3865 ArrayList keys = new ArrayList(); 4278 ArrayList keys = new ArrayList();
3866 4279
3867 lock (m_host.TaskInventory) 4280 m_host.TaskInventory.LockItemsForRead(true);
4281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3868 { 4282 {
3869 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4283 if (inv.Value.Type == type || type == -1)
3870 { 4284 {
3871 if (inv.Value.Type == type || type == -1) 4285 keys.Add(inv.Value.Name);
3872 {
3873 keys.Add(inv.Value.Name);
3874 }
3875 } 4286 }
3876 } 4287 }
4288 m_host.TaskInventory.LockItemsForRead(false);
3877 4289
3878 if (keys.Count == 0) 4290 if (keys.Count == 0)
3879 { 4291 {
@@ -3910,25 +4322,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3910 } 4322 }
3911 4323
3912 // move the first object found with this inventory name 4324 // move the first object found with this inventory name
3913 lock (m_host.TaskInventory) 4325 m_host.TaskInventory.LockItemsForRead(true);
4326 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3914 { 4327 {
3915 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4328 if (inv.Value.Name == inventory)
3916 { 4329 {
3917 if (inv.Value.Name == inventory) 4330 found = true;
3918 { 4331 objId = inv.Key;
3919 found = true; 4332 assetType = inv.Value.Type;
3920 objId = inv.Key; 4333 objName = inv.Value.Name;
3921 assetType = inv.Value.Type; 4334 break;
3922 objName = inv.Value.Name;
3923 break;
3924 }
3925 } 4335 }
3926 } 4336 }
4337 m_host.TaskInventory.LockItemsForRead(false);
3927 4338
3928 if (!found) 4339 if (!found)
3929 { 4340 {
3930 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4341 llSay(0, String.Format("Could not find object '{0}'", inventory));
3931 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4342 return;
4343// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3932 } 4344 }
3933 4345
3934 // check if destination is an object 4346 // check if destination is an object
@@ -3954,6 +4366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3954 return; 4366 return;
3955 } 4367 }
3956 } 4368 }
4369
3957 // destination is an avatar 4370 // destination is an avatar
3958 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4371 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3959 4372
@@ -3976,26 +4389,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3976 bucket); 4389 bucket);
3977 if (m_TransferModule != null) 4390 if (m_TransferModule != null)
3978 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4391 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4392
4393 //This delay should only occur when giving inventory to avatars.
3979 ScriptSleep(3000); 4394 ScriptSleep(3000);
3980 } 4395 }
3981 } 4396 }
3982 4397
4398 [DebuggerNonUserCode]
3983 public void llRemoveInventory(string name) 4399 public void llRemoveInventory(string name)
3984 { 4400 {
3985 m_host.AddScriptLPS(1); 4401 m_host.AddScriptLPS(1);
3986 4402
3987 lock (m_host.TaskInventory) 4403 List<TaskInventoryItem> inv;
4404 try
3988 { 4405 {
3989 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4406 m_host.TaskInventory.LockItemsForRead(true);
4407 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4408 }
4409 finally
4410 {
4411 m_host.TaskInventory.LockItemsForRead(false);
4412 }
4413 foreach (TaskInventoryItem item in inv)
4414 {
4415 if (item.Name == name)
3990 { 4416 {
3991 if (item.Name == name) 4417 if (item.ItemID == m_itemID)
3992 { 4418 throw new ScriptDeleteException();
3993 if (item.ItemID == m_itemID) 4419 else
3994 throw new ScriptDeleteException(); 4420 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3995 else 4421 return;
3996 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3997 return;
3998 }
3999 } 4422 }
4000 } 4423 }
4001 } 4424 }
@@ -4030,112 +4453,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4453 {
4031 m_host.AddScriptLPS(1); 4454 m_host.AddScriptLPS(1);
4032 4455
4033 UUID uuid = (UUID)id; 4456 UUID uuid;
4034 PresenceInfo pinfo = null; 4457 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4458 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4459 PresenceInfo pinfo = null;
4041 if (account == null) 4460 UserAccount account;
4461
4462 UserInfoCacheEntry ce;
4463 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4464 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4465 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4466 if (account == null)
4045 } 4467 {
4468 m_userInfoCache[uuid] = null; // Cache negative
4469 return UUID.Zero.ToString();
4470 }
4046 4471
4047 4472
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4473 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4474 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4475 {
4053 if (p.RegionID != UUID.Zero) 4476 foreach (PresenceInfo p in pinfos)
4054 { 4477 {
4055 pinfo = p; 4478 if (p.RegionID != UUID.Zero)
4479 {
4480 pinfo = p;
4481 }
4056 } 4482 }
4057 } 4483 }
4058 }
4059 4484
4060 ce = new UserInfoCacheEntry(); 4485 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4486 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4487 ce.account = account;
4063 ce.pinfo = pinfo; 4488 ce.pinfo = pinfo;
4064 } 4489 m_userInfoCache[uuid] = ce;
4065 else 4490 }
4066 { 4491 else
4067 if (ce == null) 4492 {
4068 return UUID.Zero.ToString(); 4493 if (ce == null)
4494 return UUID.Zero.ToString();
4069 4495
4070 account = ce.account; 4496 account = ce.account;
4071 pinfo = ce.pinfo; 4497 pinfo = ce.pinfo;
4072 } 4498 }
4073 4499
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4500 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4075 {
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0)
4078 { 4501 {
4079 foreach (PresenceInfo p in pinfos) 4502 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4503 if (pinfos != null && pinfos.Length > 0)
4080 { 4504 {
4081 if (p.RegionID != UUID.Zero) 4505 foreach (PresenceInfo p in pinfos)
4082 { 4506 {
4083 pinfo = p; 4507 if (p.RegionID != UUID.Zero)
4508 {
4509 pinfo = p;
4510 }
4084 } 4511 }
4085 } 4512 }
4086 } 4513 else
4087 else 4514 pinfo = null;
4088 pinfo = null;
4089 4515
4090 ce.time = Util.EnvironmentTickCount(); 4516 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4517 ce.pinfo = pinfo;
4092 } 4518 }
4093 4519
4094 string reply = String.Empty; 4520 string reply = String.Empty;
4095 4521
4096 switch (data) 4522 switch (data)
4097 { 4523 {
4098 case 1: // DATA_ONLINE (0|1) 4524 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4525 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4526 reply = "1";
4101 else 4527 else
4102 reply = "0"; 4528 reply = "0";
4103 break; 4529 break;
4104 case 2: // DATA_NAME (First Last) 4530 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4531 reply = account.FirstName + " " + account.LastName;
4106 break; 4532 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4533 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4534 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4535 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4536 reply = born.ToString("yyyy-MM-dd");
4111 break; 4537 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4538 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4539 reply = "0,0,0,0,0,0";
4114 break; 4540 break;
4115 case 8: // DATA_PAYINFO (0|1|2|3) 4541 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = "0"; 4542 reply = "0";
4117 break; 4543 break;
4118 default: 4544 default:
4119 return UUID.Zero.ToString(); // Raise no event 4545 return UUID.Zero.ToString(); // Raise no event
4120 } 4546 }
4121 4547
4122 UUID rq = UUID.Random(); 4548 UUID rq = UUID.Random();
4123 4549
4124 UUID tid = AsyncCommands. 4550 UUID tid = AsyncCommands.
4125 DataserverPlugin.RegisterRequest(m_localID, 4551 DataserverPlugin.RegisterRequest(m_localID,
4126 m_itemID, rq.ToString()); 4552 m_itemID, rq.ToString());
4127 4553
4128 AsyncCommands. 4554 AsyncCommands.
4129 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4555 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4130 4556
4131 ScriptSleep(100); 4557 ScriptSleep(100);
4132 return tid.ToString(); 4558 return tid.ToString();
4559 }
4560 else
4561 {
4562 ShoutError("Invalid UUID passed to llRequestAgentData.");
4563 }
4564 return "";
4133 } 4565 }
4134 4566
4135 public LSL_String llRequestInventoryData(string name) 4567 public LSL_String llRequestInventoryData(string name)
4136 { 4568 {
4137 m_host.AddScriptLPS(1); 4569 m_host.AddScriptLPS(1);
4138 4570
4571 //Clone is thread safe
4139 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4572 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4140 4573
4141 foreach (TaskInventoryItem item in itemDictionary.Values) 4574 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4189,6 +4622,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 ScenePresence presence = World.GetScenePresence(agentId); 4622 ScenePresence presence = World.GetScenePresence(agentId);
4190 if (presence != null) 4623 if (presence != null)
4191 { 4624 {
4625 // agent must not be a god
4626 if (presence.UserLevel >= 200) return;
4627
4192 // agent must be over the owners land 4628 // agent must be over the owners land
4193 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4629 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4194 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4630 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4211,7 +4647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4211 UUID av = new UUID(); 4647 UUID av = new UUID();
4212 if (!UUID.TryParse(agent,out av)) 4648 if (!UUID.TryParse(agent,out av))
4213 { 4649 {
4214 LSLError("First parameter to llDialog needs to be a key"); 4650 //LSLError("First parameter to llDialog needs to be a key");
4215 return; 4651 return;
4216 } 4652 }
4217 4653
@@ -4248,17 +4684,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4248 UUID soundId = UUID.Zero; 4684 UUID soundId = UUID.Zero;
4249 if (!UUID.TryParse(impact_sound, out soundId)) 4685 if (!UUID.TryParse(impact_sound, out soundId))
4250 { 4686 {
4251 lock (m_host.TaskInventory) 4687 m_host.TaskInventory.LockItemsForRead(true);
4688 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4252 { 4689 {
4253 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4690 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4254 { 4691 {
4255 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4692 soundId = item.AssetID;
4256 { 4693 break;
4257 soundId = item.AssetID;
4258 break;
4259 }
4260 } 4694 }
4261 } 4695 }
4696 m_host.TaskInventory.LockItemsForRead(false);
4262 } 4697 }
4263 m_host.CollisionSound = soundId; 4698 m_host.CollisionSound = soundId;
4264 m_host.CollisionSoundVolume = (float)impact_volume; 4699 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4298,6 +4733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4298 UUID partItemID; 4733 UUID partItemID;
4299 foreach (SceneObjectPart part in parts) 4734 foreach (SceneObjectPart part in parts)
4300 { 4735 {
4736 //Clone is thread safe
4301 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4737 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4302 4738
4303 foreach (TaskInventoryItem item in itemsDictionary.Values) 4739 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4512,17 +4948,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4512 4948
4513 m_host.AddScriptLPS(1); 4949 m_host.AddScriptLPS(1);
4514 4950
4515 lock (m_host.TaskInventory) 4951 m_host.TaskInventory.LockItemsForRead(true);
4952 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4516 { 4953 {
4517 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4954 if (item.Type == 10 && item.ItemID == m_itemID)
4518 { 4955 {
4519 if (item.Type == 10 && item.ItemID == m_itemID) 4956 result = item.Name!=null?item.Name:String.Empty;
4520 { 4957 break;
4521 result = item.Name != null ? item.Name : String.Empty;
4522 break;
4523 }
4524 } 4958 }
4525 } 4959 }
4960 m_host.TaskInventory.LockItemsForRead(false);
4526 4961
4527 return result; 4962 return result;
4528 } 4963 }
@@ -4691,23 +5126,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4691 { 5126 {
4692 m_host.AddScriptLPS(1); 5127 m_host.AddScriptLPS(1);
4693 5128
4694 lock (m_host.TaskInventory) 5129 m_host.TaskInventory.LockItemsForRead(true);
5130 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4695 { 5131 {
4696 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5132 if (inv.Value.Name == name)
4697 { 5133 {
4698 if (inv.Value.Name == name) 5134 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4699 { 5135 {
4700 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5136 m_host.TaskInventory.LockItemsForRead(false);
4701 { 5137 return inv.Value.AssetID.ToString();
4702 return inv.Value.AssetID.ToString(); 5138 }
4703 } 5139 else
4704 else 5140 {
4705 { 5141 m_host.TaskInventory.LockItemsForRead(false);
4706 return UUID.Zero.ToString(); 5142 return UUID.Zero.ToString();
4707 }
4708 } 5143 }
4709 } 5144 }
4710 } 5145 }
5146 m_host.TaskInventory.LockItemsForRead(false);
4711 5147
4712 return UUID.Zero.ToString(); 5148 return UUID.Zero.ToString();
4713 } 5149 }
@@ -4860,14 +5296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4860 { 5296 {
4861 m_host.AddScriptLPS(1); 5297 m_host.AddScriptLPS(1);
4862 5298
4863 if (src == null) 5299 return src.Length;
4864 {
4865 return 0;
4866 }
4867 else
4868 {
4869 return src.Length;
4870 }
4871 } 5300 }
4872 5301
4873 public LSL_Integer llList2Integer(LSL_List src, int index) 5302 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4913,7 +5342,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4913 else if (src.Data[index] is LSL_Float) 5342 else if (src.Data[index] is LSL_Float)
4914 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5343 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4915 else if (src.Data[index] is LSL_String) 5344 else if (src.Data[index] is LSL_String)
4916 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5345 {
5346 string str = ((LSL_String) src.Data[index]).m_string;
5347 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5348 if (m != Match.Empty)
5349 {
5350 str = m.Value;
5351 double d = 0.0;
5352 if (!Double.TryParse(str, out d))
5353 return 0.0;
5354
5355 return d;
5356 }
5357 return 0.0;
5358 }
4917 return Convert.ToDouble(src.Data[index]); 5359 return Convert.ToDouble(src.Data[index]);
4918 } 5360 }
4919 catch (FormatException) 5361 catch (FormatException)
@@ -5186,7 +5628,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5186 } 5628 }
5187 } 5629 }
5188 } 5630 }
5189 else { 5631 else
5632 {
5190 object[] array = new object[src.Length]; 5633 object[] array = new object[src.Length];
5191 Array.Copy(src.Data, 0, array, 0, src.Length); 5634 Array.Copy(src.Data, 0, array, 0, src.Length);
5192 result = new LSL_List(array); 5635 result = new LSL_List(array);
@@ -5637,10 +6080,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5637 m_host.AddScriptLPS(1); 6080 m_host.AddScriptLPS(1);
5638 6081
5639 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6082 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5640 6083 if (parts.Count > 0)
5641 foreach (var part in parts)
5642 { 6084 {
5643 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6085 try
6086 {
6087 parts[0].ParentGroup.areUpdatesSuspended = true;
6088 foreach (var part in parts)
6089 {
6090 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6091 }
6092 }
6093 finally
6094 {
6095 parts[0].ParentGroup.areUpdatesSuspended = false;
6096 }
5644 } 6097 }
5645 } 6098 }
5646 6099
@@ -5694,6 +6147,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5694 ScriptSleep(5000); 6147 ScriptSleep(5000);
5695 } 6148 }
5696 6149
6150 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6151 {
6152 return ParseString2List(str, separators, in_spacers, false);
6153 }
6154
5697 public LSL_Integer llOverMyLand(string id) 6155 public LSL_Integer llOverMyLand(string id)
5698 { 6156 {
5699 m_host.AddScriptLPS(1); 6157 m_host.AddScriptLPS(1);
@@ -5894,7 +6352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5894 return m_host.ParentGroup.AttachmentPoint; 6352 return m_host.ParentGroup.AttachmentPoint;
5895 } 6353 }
5896 6354
5897 public LSL_Integer llGetFreeMemory() 6355 public virtual LSL_Integer llGetFreeMemory()
5898 { 6356 {
5899 m_host.AddScriptLPS(1); 6357 m_host.AddScriptLPS(1);
5900 // Make scripts designed for LSO happy 6358 // Make scripts designed for LSO happy
@@ -6011,7 +6469,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6011 SetParticleSystem(m_host, rules); 6469 SetParticleSystem(m_host, rules);
6012 } 6470 }
6013 6471
6014 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6472 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6473 {
6015 6474
6016 6475
6017 if (rules.Length == 0) 6476 if (rules.Length == 0)
@@ -6205,14 +6664,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6205 6664
6206 protected UUID GetTaskInventoryItem(string name) 6665 protected UUID GetTaskInventoryItem(string name)
6207 { 6666 {
6208 lock (m_host.TaskInventory) 6667 m_host.TaskInventory.LockItemsForRead(true);
6668 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6209 { 6669 {
6210 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6670 if (inv.Value.Name == name)
6211 { 6671 {
6212 if (inv.Value.Name == name) 6672 m_host.TaskInventory.LockItemsForRead(false);
6213 return inv.Key; 6673 return inv.Key;
6214 } 6674 }
6215 } 6675 }
6676 m_host.TaskInventory.LockItemsForRead(false);
6216 6677
6217 return UUID.Zero; 6678 return UUID.Zero;
6218 } 6679 }
@@ -6462,13 +6923,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6462 UUID av = new UUID(); 6923 UUID av = new UUID();
6463 if (!UUID.TryParse(avatar,out av)) 6924 if (!UUID.TryParse(avatar,out av))
6464 { 6925 {
6465 LSLError("First parameter to llDialog needs to be a key"); 6926 //LSLError("First parameter to llDialog needs to be a key");
6466 return; 6927 return;
6467 } 6928 }
6468 if (buttons.Length < 1) 6929 if (buttons.Length < 1)
6469 { 6930 {
6470 LSLError("No less than 1 button can be shown"); 6931 buttons.Add("OK");
6471 return;
6472 } 6932 }
6473 if (buttons.Length > 12) 6933 if (buttons.Length > 12)
6474 { 6934 {
@@ -6485,7 +6945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6485 } 6945 }
6486 if (buttons.Data[i].ToString().Length > 24) 6946 if (buttons.Data[i].ToString().Length > 24)
6487 { 6947 {
6488 LSLError("button label cannot be longer than 24 characters"); 6948 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6489 return; 6949 return;
6490 } 6950 }
6491 buts[i] = buttons.Data[i].ToString(); 6951 buts[i] = buttons.Data[i].ToString();
@@ -6544,22 +7004,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6544 } 7004 }
6545 7005
6546 // copy the first script found with this inventory name 7006 // copy the first script found with this inventory name
6547 lock (m_host.TaskInventory) 7007 TaskInventoryItem scriptItem = null;
7008 m_host.TaskInventory.LockItemsForRead(true);
7009 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6548 { 7010 {
6549 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7011 if (inv.Value.Name == name)
6550 { 7012 {
6551 if (inv.Value.Name == name) 7013 // make sure the object is a script
7014 if (10 == inv.Value.Type)
6552 { 7015 {
6553 // make sure the object is a script 7016 found = true;
6554 if (10 == inv.Value.Type) 7017 srcId = inv.Key;
6555 { 7018 scriptItem = inv.Value;
6556 found = true; 7019 break;
6557 srcId = inv.Key;
6558 break;
6559 }
6560 } 7020 }
6561 } 7021 }
6562 } 7022 }
7023 m_host.TaskInventory.LockItemsForRead(false);
6563 7024
6564 if (!found) 7025 if (!found)
6565 { 7026 {
@@ -6567,8 +7028,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6567 return; 7028 return;
6568 } 7029 }
6569 7030
6570 // the rest of the permission checks are done in RezScript, so check the pin there as well 7031 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6571 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7032 if (dest != null)
7033 {
7034 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7035 {
7036 // the rest of the permission checks are done in RezScript, so check the pin there as well
7037 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7038
7039 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7040 m_host.Inventory.RemoveInventoryItem(srcId);
7041 }
7042 }
6572 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7043 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6573 ScriptSleep(3000); 7044 ScriptSleep(3000);
6574 } 7045 }
@@ -6631,19 +7102,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6631 public LSL_String llMD5String(string src, int nonce) 7102 public LSL_String llMD5String(string src, int nonce)
6632 { 7103 {
6633 m_host.AddScriptLPS(1); 7104 m_host.AddScriptLPS(1);
6634 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7105 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6635 } 7106 }
6636 7107
6637 public LSL_String llSHA1String(string src) 7108 public LSL_String llSHA1String(string src)
6638 { 7109 {
6639 m_host.AddScriptLPS(1); 7110 m_host.AddScriptLPS(1);
6640 return Util.SHA1Hash(src).ToLower(); 7111 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6641 } 7112 }
6642 7113
6643 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7114 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6644 { 7115 {
6645 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7116 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6646 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7117 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7118 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7119 return shapeBlock;
6647 7120
6648 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7121 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6649 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7122 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6748,6 +7221,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6748 // Prim type box, cylinder and prism. 7221 // Prim type box, cylinder and prism.
6749 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) 7222 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)
6750 { 7223 {
7224 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7225 return;
7226
6751 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7227 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6752 ObjectShapePacket.ObjectDataBlock shapeBlock; 7228 ObjectShapePacket.ObjectDataBlock shapeBlock;
6753 7229
@@ -6801,6 +7277,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6801 // Prim type sphere. 7277 // Prim type sphere.
6802 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7278 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6803 { 7279 {
7280 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7281 return;
7282
6804 ObjectShapePacket.ObjectDataBlock shapeBlock; 7283 ObjectShapePacket.ObjectDataBlock shapeBlock;
6805 7284
6806 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7285 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6842,6 +7321,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6842 // Prim type torus, tube and ring. 7321 // Prim type torus, tube and ring.
6843 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) 7322 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)
6844 { 7323 {
7324 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7325 return;
7326
6845 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7327 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6846 ObjectShapePacket.ObjectDataBlock shapeBlock; 7328 ObjectShapePacket.ObjectDataBlock shapeBlock;
6847 7329
@@ -6977,6 +7459,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6977 // Prim type sculpt. 7459 // Prim type sculpt.
6978 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7460 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6979 { 7461 {
7462 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7463 return;
7464
6980 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7465 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6981 UUID sculptId; 7466 UUID sculptId;
6982 7467
@@ -6993,13 +7478,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6993 shapeBlock.PathScaleX = 100; 7478 shapeBlock.PathScaleX = 100;
6994 shapeBlock.PathScaleY = 150; 7479 shapeBlock.PathScaleY = 150;
6995 7480
6996 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7481 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6997 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7482 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6998 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7483 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6999 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7484 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7000 { 7485 {
7001 // default 7486 // default
7002 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7487 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7003 } 7488 }
7004 7489
7005 part.Shape.SetSculptProperties((byte)type, sculptId); 7490 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7015,34 +7500,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7015 ScriptSleep(200); 7500 ScriptSleep(200);
7016 } 7501 }
7017 7502
7018 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7503 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7019 { 7504 {
7020 m_host.AddScriptLPS(1); 7505 m_host.AddScriptLPS(1);
7021 7506
7022 setLinkPrimParams(linknumber, rules); 7507 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7508 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7509 if (parts.Count>0)
7510 {
7511 try
7512 {
7513 parts[0].ParentGroup.areUpdatesSuspended = true;
7514 foreach (SceneObjectPart part in parts)
7515 SetPrimParams(part, rules);
7516 }
7517 finally
7518 {
7519 parts[0].ParentGroup.areUpdatesSuspended = false;
7520 }
7521 }
7522 if (avatars.Count > 0)
7523 {
7524 foreach (ScenePresence avatar in avatars)
7525 SetPrimParams(avatar, rules);
7526 }
7527 }
7023 7528
7529 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7530 {
7531 llSetLinkPrimitiveParamsFast(linknumber, rules);
7024 ScriptSleep(200); 7532 ScriptSleep(200);
7025 } 7533 }
7026 7534
7027 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7535 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7028 { 7536 {
7029 m_host.AddScriptLPS(1); 7537 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7538 //We only support PRIM_POSITION and PRIM_ROTATION
7030 7539
7031 setLinkPrimParams(linknumber, rules); 7540 int idx = 0;
7032 }
7033 7541
7034 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7542 while (idx < rules.Length)
7035 { 7543 {
7036 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7544 int code = rules.GetLSLIntegerItem(idx++);
7037 7545
7038 foreach (SceneObjectPart part in parts) 7546 int remain = rules.Length - idx;
7039 SetPrimParams(part, rules); 7547
7548
7549
7550 switch (code)
7551 {
7552 case (int)ScriptBaseClass.PRIM_POSITION:
7553 if (remain < 1)
7554 return;
7555 LSL_Vector v;
7556 v = rules.GetVector3Item(idx++);
7557 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7558 av.SendAvatarDataToAllAgents();
7559
7560 break;
7561
7562 case (int)ScriptBaseClass.PRIM_ROTATION:
7563 if (remain < 1)
7564 return;
7565 LSL_Rotation r;
7566 r = rules.GetQuaternionItem(idx++);
7567 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7568 av.SendAvatarDataToAllAgents();
7569 break;
7570 }
7571 }
7040 } 7572 }
7041 7573
7042 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7574 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7043 { 7575 {
7576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7577 return;
7578
7044 int idx = 0; 7579 int idx = 0;
7045 7580
7581 bool positionChanged = false;
7582 LSL_Vector currentPosition = GetPartLocalPos(part);
7583
7046 while (idx < rules.Length) 7584 while (idx < rules.Length)
7047 { 7585 {
7048 int code = rules.GetLSLIntegerItem(idx++); 7586 int code = rules.GetLSLIntegerItem(idx++);
@@ -7051,7 +7589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7051 7589
7052 int face; 7590 int face;
7053 LSL_Vector v; 7591 LSL_Vector v;
7054 7592
7055 switch (code) 7593 switch (code)
7056 { 7594 {
7057 case (int)ScriptBaseClass.PRIM_POSITION: 7595 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -7059,7 +7597,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7059 return; 7597 return;
7060 7598
7061 v=rules.GetVector3Item(idx++); 7599 v=rules.GetVector3Item(idx++);
7062 SetPos(part, v); 7600 positionChanged = true;
7601 currentPosition = GetSetPosTarget(part, v, currentPosition);
7063 7602
7064 break; 7603 break;
7065 case (int)ScriptBaseClass.PRIM_SIZE: 7604 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7418,6 +7957,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7418 break; 7957 break;
7419 } 7958 }
7420 } 7959 }
7960
7961 if (positionChanged)
7962 {
7963 if (part.ParentGroup.RootPart == part)
7964 {
7965 SceneObjectGroup parent = part.ParentGroup;
7966 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7967 }
7968 else
7969 {
7970 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7971 SceneObjectGroup parent = part.ParentGroup;
7972 parent.HasGroupChanged = true;
7973 parent.ScheduleGroupForTerseUpdate();
7974 }
7975 }
7421 } 7976 }
7422 7977
7423 public LSL_String llStringToBase64(string str) 7978 public LSL_String llStringToBase64(string str)
@@ -7566,13 +8121,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7566 public LSL_Integer llGetNumberOfPrims() 8121 public LSL_Integer llGetNumberOfPrims()
7567 { 8122 {
7568 m_host.AddScriptLPS(1); 8123 m_host.AddScriptLPS(1);
7569 int avatarCount = 0; 8124 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7570 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8125
7571 {
7572 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7573 avatarCount++;
7574 });
7575
7576 return m_host.ParentGroup.PrimCount + avatarCount; 8126 return m_host.ParentGroup.PrimCount + avatarCount;
7577 } 8127 }
7578 8128
@@ -7588,55 +8138,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7588 m_host.AddScriptLPS(1); 8138 m_host.AddScriptLPS(1);
7589 UUID objID = UUID.Zero; 8139 UUID objID = UUID.Zero;
7590 LSL_List result = new LSL_List(); 8140 LSL_List result = new LSL_List();
8141
8142 // If the ID is not valid, return null result
7591 if (!UUID.TryParse(obj, out objID)) 8143 if (!UUID.TryParse(obj, out objID))
7592 { 8144 {
7593 result.Add(new LSL_Vector()); 8145 result.Add(new LSL_Vector());
7594 result.Add(new LSL_Vector()); 8146 result.Add(new LSL_Vector());
7595 return result; 8147 return result;
7596 } 8148 }
8149
8150 // Check if this is an attached prim. If so, replace
8151 // the UUID with the avatar UUID and report it's bounding box
8152 SceneObjectPart part = World.GetSceneObjectPart(objID);
8153 if (part != null && part.ParentGroup.IsAttachment)
8154 objID = part.ParentGroup.AttachedAvatar;
8155
8156 // Find out if this is an avatar ID. If so, return it's box
7597 ScenePresence presence = World.GetScenePresence(objID); 8157 ScenePresence presence = World.GetScenePresence(objID);
7598 if (presence != null) 8158 if (presence != null)
7599 { 8159 {
7600 if (presence.ParentID == 0) // not sat on an object 8160 // As per LSL Wiki, there is no difference between sitting
8161 // and standing avatar since server 1.36
8162 LSL_Vector lower;
8163 LSL_Vector upper;
8164 if (presence.Animator.Animations.DefaultAnimation.AnimID
8165 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7601 { 8166 {
7602 LSL_Vector lower; 8167 // This is for ground sitting avatars
7603 LSL_Vector upper; 8168 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7604 if (presence.Animator.Animations.DefaultAnimation.AnimID 8169 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7605 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8170 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7606 {
7607 // This is for ground sitting avatars
7608 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7609 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7610 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7611 }
7612 else
7613 {
7614 // This is for standing/flying avatars
7615 float height = presence.Appearance.AvatarHeight / 2.0f;
7616 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7617 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7618 }
7619 result.Add(lower);
7620 result.Add(upper);
7621 return result;
7622 } 8171 }
7623 else 8172 else
7624 { 8173 {
7625 // sitting on an object so we need the bounding box of that 8174 // This is for standing/flying avatars
7626 // which should include the avatar so set the UUID to the 8175 float height = presence.Appearance.AvatarHeight / 2.0f;
7627 // UUID of the object the avatar is sat on and allow it to fall through 8176 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7628 // to processing an object 8177 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7629 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7630 objID = p.UUID;
7631 } 8178 }
8179
8180 // Adjust to the documented error offsets (see LSL Wiki)
8181 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8182 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8183
8184 if (lower.x > upper.x)
8185 lower.x = upper.x;
8186 if (lower.y > upper.y)
8187 lower.y = upper.y;
8188 if (lower.z > upper.z)
8189 lower.z = upper.z;
8190
8191 result.Add(lower);
8192 result.Add(upper);
8193 return result;
7632 } 8194 }
7633 SceneObjectPart part = World.GetSceneObjectPart(objID); 8195
8196 part = World.GetSceneObjectPart(objID);
7634 // Currently only works for single prims without a sitting avatar 8197 // Currently only works for single prims without a sitting avatar
7635 if (part != null) 8198 if (part != null)
7636 { 8199 {
7637 Vector3 halfSize = part.Scale / 2.0f; 8200 float minX;
7638 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8201 float maxX;
7639 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8202 float minY;
8203 float maxY;
8204 float minZ;
8205 float maxZ;
8206
8207 // This BBox is in sim coordinates, with the offset being
8208 // a contained point.
8209 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8210 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8211
8212 minX -= offsets[0].X;
8213 maxX -= offsets[0].X;
8214 minY -= offsets[0].Y;
8215 maxY -= offsets[0].Y;
8216 minZ -= offsets[0].Z;
8217 maxZ -= offsets[0].Z;
8218
8219 LSL_Vector lower;
8220 LSL_Vector upper;
8221
8222 // Adjust to the documented error offsets (see LSL Wiki)
8223 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8224 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8225
8226 if (lower.x > upper.x)
8227 lower.x = upper.x;
8228 if (lower.y > upper.y)
8229 lower.y = upper.y;
8230 if (lower.z > upper.z)
8231 lower.z = upper.z;
8232
7640 result.Add(lower); 8233 result.Add(lower);
7641 result.Add(upper); 8234 result.Add(upper);
7642 return result; 8235 return result;
@@ -7716,13 +8309,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7716 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8309 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7717 part.AbsolutePosition.Y, 8310 part.AbsolutePosition.Y,
7718 part.AbsolutePosition.Z); 8311 part.AbsolutePosition.Z);
7719 // For some reason, the part.AbsolutePosition.* values do not change if the
7720 // linkset is rotated; they always reflect the child prim's world position
7721 // as though the linkset is unrotated. This is incompatible behavior with SL's
7722 // implementation, so will break scripts imported from there (not to mention it
7723 // makes it more difficult to determine a child prim's actual inworld position).
7724 if (part.ParentID != 0)
7725 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7726 res.Add(v); 8312 res.Add(v);
7727 break; 8313 break;
7728 8314
@@ -7893,56 +8479,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7893 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8479 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7894 if (remain < 1) 8480 if (remain < 1)
7895 return res; 8481 return res;
7896 8482 face = (int)rules.GetLSLIntegerItem(idx++);
7897 face=(int)rules.GetLSLIntegerItem(idx++);
7898 8483
7899 tex = part.Shape.Textures; 8484 tex = part.Shape.Textures;
8485 int shiny;
7900 if (face == ScriptBaseClass.ALL_SIDES) 8486 if (face == ScriptBaseClass.ALL_SIDES)
7901 { 8487 {
7902 for (face = 0; face < GetNumberOfSides(part); face++) 8488 for (face = 0; face < GetNumberOfSides(part); face++)
7903 { 8489 {
7904 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8490 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7905 // Convert Shininess to PRIM_SHINY_* 8491 if (shinyness == Shininess.High)
7906 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8492 {
7907 // PRIM_BUMP_* 8493 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7908 res.Add(new LSL_Integer((int)texface.Bump)); 8494 }
8495 else if (shinyness == Shininess.Medium)
8496 {
8497 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8498 }
8499 else if (shinyness == Shininess.Low)
8500 {
8501 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8502 }
8503 else
8504 {
8505 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8506 }
8507 res.Add(new LSL_Integer(shiny));
8508 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7909 } 8509 }
7910 } 8510 }
7911 else 8511 else
7912 { 8512 {
7913 if (face >= 0 && face < GetNumberOfSides(part)) 8513 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8514 if (shinyness == Shininess.High)
7914 { 8515 {
7915 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8516 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7916 // Convert Shininess to PRIM_SHINY_* 8517 }
7917 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8518 else if (shinyness == Shininess.Medium)
7918 // PRIM_BUMP_* 8519 {
7919 res.Add(new LSL_Integer((int)texface.Bump)); 8520 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
7920 } 8521 }
8522 else if (shinyness == Shininess.Low)
8523 {
8524 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8525 }
8526 else
8527 {
8528 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8529 }
8530 res.Add(new LSL_Integer(shiny));
8531 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7921 } 8532 }
7922 break; 8533 break;
7923 8534
7924 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8535 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7925 if (remain < 1) 8536 if (remain < 1)
7926 return res; 8537 return res;
7927 8538 face = (int)rules.GetLSLIntegerItem(idx++);
7928 face=(int)rules.GetLSLIntegerItem(idx++);
7929 8539
7930 tex = part.Shape.Textures; 8540 tex = part.Shape.Textures;
8541 int fullbright;
7931 if (face == ScriptBaseClass.ALL_SIDES) 8542 if (face == ScriptBaseClass.ALL_SIDES)
7932 { 8543 {
7933 for (face = 0; face < GetNumberOfSides(part); face++) 8544 for (face = 0; face < GetNumberOfSides(part); face++)
7934 { 8545 {
7935 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8546 if (tex.GetFace((uint)face).Fullbright == true)
7936 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8547 {
8548 fullbright = ScriptBaseClass.TRUE;
8549 }
8550 else
8551 {
8552 fullbright = ScriptBaseClass.FALSE;
8553 }
8554 res.Add(new LSL_Integer(fullbright));
7937 } 8555 }
7938 } 8556 }
7939 else 8557 else
7940 { 8558 {
7941 if (face >= 0 && face < GetNumberOfSides(part)) 8559 if (tex.GetFace((uint)face).Fullbright == true)
7942 { 8560 {
7943 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8561 fullbright = ScriptBaseClass.TRUE;
7944 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8562 }
8563 else
8564 {
8565 fullbright = ScriptBaseClass.FALSE;
7945 } 8566 }
8567 res.Add(new LSL_Integer(fullbright));
7946 } 8568 }
7947 break; 8569 break;
7948 8570
@@ -7964,27 +8586,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7964 break; 8586 break;
7965 8587
7966 case (int)ScriptBaseClass.PRIM_TEXGEN: 8588 case (int)ScriptBaseClass.PRIM_TEXGEN:
8589 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7967 if (remain < 1) 8590 if (remain < 1)
7968 return res; 8591 return res;
7969 8592 face = (int)rules.GetLSLIntegerItem(idx++);
7970 face=(int)rules.GetLSLIntegerItem(idx++);
7971 8593
7972 tex = part.Shape.Textures; 8594 tex = part.Shape.Textures;
7973 if (face == ScriptBaseClass.ALL_SIDES) 8595 if (face == ScriptBaseClass.ALL_SIDES)
7974 { 8596 {
7975 for (face = 0; face < GetNumberOfSides(part); face++) 8597 for (face = 0; face < GetNumberOfSides(part); face++)
7976 { 8598 {
7977 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8599 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7978 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8600 {
7979 res.Add(new LSL_Integer((uint)texgen >> 1)); 8601 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8602 }
8603 else
8604 {
8605 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8606 }
7980 } 8607 }
7981 } 8608 }
7982 else 8609 else
7983 { 8610 {
7984 if (face >= 0 && face < GetNumberOfSides(part)) 8611 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8612 {
8613 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8614 }
8615 else
7985 { 8616 {
7986 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8617 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7987 res.Add(new LSL_Integer((uint)texgen >> 1));
7988 } 8618 }
7989 } 8619 }
7990 break; 8620 break;
@@ -8007,28 +8637,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8007 case (int)ScriptBaseClass.PRIM_GLOW: 8637 case (int)ScriptBaseClass.PRIM_GLOW:
8008 if (remain < 1) 8638 if (remain < 1)
8009 return res; 8639 return res;
8010 8640 face = (int)rules.GetLSLIntegerItem(idx++);
8011 face=(int)rules.GetLSLIntegerItem(idx++);
8012 8641
8013 tex = part.Shape.Textures; 8642 tex = part.Shape.Textures;
8643 float primglow;
8014 if (face == ScriptBaseClass.ALL_SIDES) 8644 if (face == ScriptBaseClass.ALL_SIDES)
8015 { 8645 {
8016 for (face = 0; face < GetNumberOfSides(part); face++) 8646 for (face = 0; face < GetNumberOfSides(part); face++)
8017 { 8647 {
8018 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8648 primglow = tex.GetFace((uint)face).Glow;
8019 res.Add(new LSL_Float(texface.Glow)); 8649 res.Add(new LSL_Float(primglow));
8020 } 8650 }
8021 } 8651 }
8022 else 8652 else
8023 { 8653 {
8024 if (face >= 0 && face < GetNumberOfSides(part)) 8654 primglow = tex.GetFace((uint)face).Glow;
8025 { 8655 res.Add(new LSL_Float(primglow));
8026 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8027 res.Add(new LSL_Float(texface.Glow));
8028 }
8029 } 8656 }
8030 break; 8657 break;
8031
8032 case (int)ScriptBaseClass.PRIM_TEXT: 8658 case (int)ScriptBaseClass.PRIM_TEXT:
8033 Color4 textColor = part.GetTextColor(); 8659 Color4 textColor = part.GetTextColor();
8034 res.Add(new LSL_String(part.Text)); 8660 res.Add(new LSL_String(part.Text));
@@ -8577,8 +9203,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8577 // The function returns an ordered list 9203 // The function returns an ordered list
8578 // representing the tokens found in the supplied 9204 // representing the tokens found in the supplied
8579 // sources string. If two successive tokenizers 9205 // sources string. If two successive tokenizers
8580 // are encountered, then a NULL entry is added 9206 // are encountered, then a null-string entry is
8581 // to the list. 9207 // added to the list.
8582 // 9208 //
8583 // It is a precondition that the source and 9209 // It is a precondition that the source and
8584 // toekizer lisst are non-null. If they are null, 9210 // toekizer lisst are non-null. If they are null,
@@ -8586,7 +9212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8586 // while their lengths are being determined. 9212 // while their lengths are being determined.
8587 // 9213 //
8588 // A small amount of working memoryis required 9214 // A small amount of working memoryis required
8589 // of approximately 8*#tokenizers. 9215 // of approximately 8*#tokenizers + 8*srcstrlen.
8590 // 9216 //
8591 // There are many ways in which this function 9217 // There are many ways in which this function
8592 // can be implemented, this implementation is 9218 // can be implemented, this implementation is
@@ -8602,155 +9228,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8602 // and eliminates redundant tokenizers as soon 9228 // and eliminates redundant tokenizers as soon
8603 // as is possible. 9229 // as is possible.
8604 // 9230 //
8605 // The implementation tries to avoid any copying 9231 // The implementation tries to minimize temporary
8606 // of arrays or other objects. 9232 // garbage generation.
8607 // </remarks> 9233 // </remarks>
8608 9234
8609 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9235 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8610 { 9236 {
8611 int beginning = 0; 9237 return ParseString2List(src, separators, spacers, true);
8612 int srclen = src.Length; 9238 }
8613 int seplen = separators.Length;
8614 object[] separray = separators.Data;
8615 int spclen = spacers.Length;
8616 object[] spcarray = spacers.Data;
8617 int mlen = seplen+spclen;
8618
8619 int[] offset = new int[mlen+1];
8620 bool[] active = new bool[mlen];
8621
8622 int best;
8623 int j;
8624
8625 // Initial capacity reduces resize cost
8626 9239
8627 LSL_List tokens = new LSL_List(); 9240 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9241 {
9242 int srclen = src.Length;
9243 int seplen = separators.Length;
9244 object[] separray = separators.Data;
9245 int spclen = spacers.Length;
9246 object[] spcarray = spacers.Data;
9247 int dellen = 0;
9248 string[] delarray = new string[seplen+spclen];
8628 9249
8629 // All entries are initially valid 9250 int outlen = 0;
9251 string[] outarray = new string[srclen*2+1];
8630 9252
8631 for (int i = 0; i < mlen; i++) 9253 int i, j;
8632 active[i] = true; 9254 string d;
8633 9255
8634 offset[mlen] = srclen; 9256 m_host.AddScriptLPS(1);
8635 9257
8636 while (beginning < srclen) 9258 /*
9259 * Convert separator and spacer lists to C# strings.
9260 * Also filter out null strings so we don't hang.
9261 */
9262 for (i = 0; i < seplen; i ++)
8637 { 9263 {
9264 d = separray[i].ToString();
9265 if (d.Length > 0)
9266 {
9267 delarray[dellen++] = d;
9268 }
9269 }
9270 seplen = dellen;
8638 9271
8639 best = mlen; // as bad as it gets 9272 for (i = 0; i < spclen; i ++)
9273 {
9274 d = spcarray[i].ToString();
9275 if (d.Length > 0)
9276 {
9277 delarray[dellen++] = d;
9278 }
9279 }
8640 9280
8641 // Scan for separators 9281 /*
9282 * Scan through source string from beginning to end.
9283 */
9284 for (i = 0;;)
9285 {
8642 9286
8643 for (j = 0; j < seplen; j++) 9287 /*
9288 * Find earliest delimeter in src starting at i (if any).
9289 */
9290 int earliestDel = -1;
9291 int earliestSrc = srclen;
9292 string earliestStr = null;
9293 for (j = 0; j < dellen; j ++)
8644 { 9294 {
8645 if (separray[j].ToString() == String.Empty) 9295 d = delarray[j];
8646 active[j] = false; 9296 if (d != null)
8647
8648 if (active[j])
8649 { 9297 {
8650 // scan all of the markers 9298 int index = src.IndexOf(d, i);
8651 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9299 if (index < 0)
8652 { 9300 {
8653 // not present at all 9301 delarray[j] = null; // delim nowhere in src, don't check it anymore
8654 active[j] = false;
8655 } 9302 }
8656 else 9303 else if (index < earliestSrc)
8657 { 9304 {
8658 // present and correct 9305 earliestSrc = index; // where delimeter starts in source string
8659 if (offset[j] < offset[best]) 9306 earliestDel = j; // where delimeter is in delarray[]
8660 { 9307 earliestStr = d; // the delimeter string from delarray[]
8661 // closest so far 9308 if (index == i) break; // can't do any better than found at beg of string
8662 best = j;
8663 if (offset[best] == beginning)
8664 break;
8665 }
8666 } 9309 }
8667 } 9310 }
8668 } 9311 }
8669 9312
8670 // Scan for spacers 9313 /*
8671 9314 * Output source string starting at i through start of earliest delimeter.
8672 if (offset[best] != beginning) 9315 */
9316 if (keepNulls || (earliestSrc > i))
8673 { 9317 {
8674 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9318 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8675 {
8676 if (spcarray[j-seplen].ToString() == String.Empty)
8677 active[j] = false;
8678
8679 if (active[j])
8680 {
8681 // scan all of the markers
8682 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8683 {
8684 // not present at all
8685 active[j] = false;
8686 }
8687 else
8688 {
8689 // present and correct
8690 if (offset[j] < offset[best])
8691 {
8692 // closest so far
8693 best = j;
8694 }
8695 }
8696 }
8697 }
8698 } 9319 }
8699 9320
8700 // This is the normal exit from the scanning loop 9321 /*
9322 * If no delimeter found at or after i, we're done scanning.
9323 */
9324 if (earliestDel < 0) break;
8701 9325
8702 if (best == mlen) 9326 /*
9327 * If delimeter was a spacer, output the spacer.
9328 */
9329 if (earliestDel >= seplen)
8703 { 9330 {
8704 // no markers were found on this pass 9331 outarray[outlen++] = earliestStr;
8705 // so we're pretty much done
8706 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8707 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8708 break;
8709 } 9332 }
8710 9333
8711 // Otherwise we just add the newly delimited token 9334 /*
8712 // and recalculate where the search should continue. 9335 * Look at rest of src string following delimeter.
8713 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9336 */
8714 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9337 i = earliestSrc + earliestStr.Length;
8715
8716 if (best < seplen)
8717 {
8718 beginning = offset[best] + (separray[best].ToString()).Length;
8719 }
8720 else
8721 {
8722 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8723 string str = spcarray[best - seplen].ToString();
8724 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8725 tokens.Add(new LSL_String(str));
8726 }
8727 } 9338 }
8728 9339
8729 // This an awkward an not very intuitive boundary case. If the 9340 /*
8730 // last substring is a tokenizer, then there is an implied trailing 9341 * Make up an exact-sized output array suitable for an LSL_List object.
8731 // null list entry. Hopefully the single comparison will not be too 9342 */
8732 // arduous. Alternatively the 'break' could be replced with a return 9343 object[] outlist = new object[outlen];
8733 // but that's shabby programming. 9344 for (i = 0; i < outlen; i ++)
8734
8735 if ((beginning == srclen) && (keepNulls))
8736 { 9345 {
8737 if (srclen != 0) 9346 outlist[i] = new LSL_String(outarray[i]);
8738 tokens.Add(new LSL_String(""));
8739 } 9347 }
8740 9348 return new LSL_List(outlist);
8741 return tokens;
8742 }
8743
8744 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8745 {
8746 m_host.AddScriptLPS(1);
8747 return this.ParseString(src, separators, spacers, false);
8748 }
8749
8750 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8751 {
8752 m_host.AddScriptLPS(1);
8753 return this.ParseString(src, separators, spacers, true);
8754 } 9349 }
8755 9350
8756 public LSL_Integer llGetObjectPermMask(int mask) 9351 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8827,28 +9422,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8827 { 9422 {
8828 m_host.AddScriptLPS(1); 9423 m_host.AddScriptLPS(1);
8829 9424
8830 lock (m_host.TaskInventory) 9425 m_host.TaskInventory.LockItemsForRead(true);
9426 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8831 { 9427 {
8832 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9428 if (inv.Value.Name == item)
8833 { 9429 {
8834 if (inv.Value.Name == item) 9430 m_host.TaskInventory.LockItemsForRead(false);
9431 switch (mask)
8835 { 9432 {
8836 switch (mask) 9433 case 0:
8837 { 9434 return (int)inv.Value.BasePermissions;
8838 case 0: 9435 case 1:
8839 return (int)inv.Value.BasePermissions; 9436 return (int)inv.Value.CurrentPermissions;
8840 case 1: 9437 case 2:
8841 return (int)inv.Value.CurrentPermissions; 9438 return (int)inv.Value.GroupPermissions;
8842 case 2: 9439 case 3:
8843 return (int)inv.Value.GroupPermissions; 9440 return (int)inv.Value.EveryonePermissions;
8844 case 3: 9441 case 4:
8845 return (int)inv.Value.EveryonePermissions; 9442 return (int)inv.Value.NextPermissions;
8846 case 4:
8847 return (int)inv.Value.NextPermissions;
8848 }
8849 } 9443 }
8850 } 9444 }
8851 } 9445 }
9446 m_host.TaskInventory.LockItemsForRead(false);
8852 9447
8853 return -1; 9448 return -1;
8854 } 9449 }
@@ -8895,16 +9490,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8895 { 9490 {
8896 m_host.AddScriptLPS(1); 9491 m_host.AddScriptLPS(1);
8897 9492
8898 lock (m_host.TaskInventory) 9493 m_host.TaskInventory.LockItemsForRead(true);
9494 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8899 { 9495 {
8900 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9496 if (inv.Value.Name == item)
8901 { 9497 {
8902 if (inv.Value.Name == item) 9498 m_host.TaskInventory.LockItemsForRead(false);
8903 { 9499 return inv.Value.CreatorID.ToString();
8904 return inv.Value.CreatorID.ToString();
8905 }
8906 } 9500 }
8907 } 9501 }
9502 m_host.TaskInventory.LockItemsForRead(false);
8908 9503
8909 llSay(0, "No item name '" + item + "'"); 9504 llSay(0, "No item name '" + item + "'");
8910 9505
@@ -9052,7 +9647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 } 9647 }
9053 9648
9054 /// <summary> 9649 /// <summary>
9055 /// illListReplaceList removes the sub-list defined by the inclusive indices 9650 /// llListReplaceList removes the sub-list defined by the inclusive indices
9056 /// start and end and inserts the src list in its place. The inclusive 9651 /// start and end and inserts the src list in its place. The inclusive
9057 /// nature of the indices means that at least one element must be deleted 9652 /// nature of the indices means that at least one element must be deleted
9058 /// if the indices are within the bounds of the existing list. I.e. 2,2 9653 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9109,16 +9704,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9109 // based upon end. Note that if end exceeds the upper 9704 // based upon end. Note that if end exceeds the upper
9110 // bound in this case, the entire destination list 9705 // bound in this case, the entire destination list
9111 // is removed. 9706 // is removed.
9112 else 9707 else if (start == 0)
9113 { 9708 {
9114 if (end + 1 < dest.Length) 9709 if (end + 1 < dest.Length)
9115 {
9116 return src + dest.GetSublist(end + 1, -1); 9710 return src + dest.GetSublist(end + 1, -1);
9117 }
9118 else 9711 else
9119 {
9120 return src; 9712 return src;
9121 } 9713 }
9714 else // Start < 0
9715 {
9716 if (end + 1 < dest.Length)
9717 return dest.GetSublist(end + 1, -1);
9718 else
9719 return new LSL_List();
9122 } 9720 }
9123 } 9721 }
9124 // Finally, if start > end, we strip away a prefix and 9722 // Finally, if start > end, we strip away a prefix and
@@ -9169,17 +9767,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9169 int width = 0; 9767 int width = 0;
9170 int height = 0; 9768 int height = 0;
9171 9769
9172 ParcelMediaCommandEnum? commandToSend = null; 9770 uint commandToSend = 0;
9173 float time = 0.0f; // default is from start 9771 float time = 0.0f; // default is from start
9174 9772
9175 ScenePresence presence = null; 9773 ScenePresence presence = null;
9176 9774
9177 for (int i = 0; i < commandList.Data.Length; i++) 9775 for (int i = 0; i < commandList.Data.Length; i++)
9178 { 9776 {
9179 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9777 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9180 switch (command) 9778 switch (command)
9181 { 9779 {
9182 case ParcelMediaCommandEnum.Agent: 9780 case (uint)ParcelMediaCommandEnum.Agent:
9183 // we send only to one agent 9781 // we send only to one agent
9184 if ((i + 1) < commandList.Length) 9782 if ((i + 1) < commandList.Length)
9185 { 9783 {
@@ -9196,25 +9794,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9196 } 9794 }
9197 break; 9795 break;
9198 9796
9199 case ParcelMediaCommandEnum.Loop: 9797 case (uint)ParcelMediaCommandEnum.Loop:
9200 loop = 1; 9798 loop = 1;
9201 commandToSend = command; 9799 commandToSend = command;
9202 update = true; //need to send the media update packet to set looping 9800 update = true; //need to send the media update packet to set looping
9203 break; 9801 break;
9204 9802
9205 case ParcelMediaCommandEnum.Play: 9803 case (uint)ParcelMediaCommandEnum.Play:
9206 loop = 0; 9804 loop = 0;
9207 commandToSend = command; 9805 commandToSend = command;
9208 update = true; //need to send the media update packet to make sure it doesn't loop 9806 update = true; //need to send the media update packet to make sure it doesn't loop
9209 break; 9807 break;
9210 9808
9211 case ParcelMediaCommandEnum.Pause: 9809 case (uint)ParcelMediaCommandEnum.Pause:
9212 case ParcelMediaCommandEnum.Stop: 9810 case (uint)ParcelMediaCommandEnum.Stop:
9213 case ParcelMediaCommandEnum.Unload: 9811 case (uint)ParcelMediaCommandEnum.Unload:
9214 commandToSend = command; 9812 commandToSend = command;
9215 break; 9813 break;
9216 9814
9217 case ParcelMediaCommandEnum.Url: 9815 case (uint)ParcelMediaCommandEnum.Url:
9218 if ((i + 1) < commandList.Length) 9816 if ((i + 1) < commandList.Length)
9219 { 9817 {
9220 if (commandList.Data[i + 1] is LSL_String) 9818 if (commandList.Data[i + 1] is LSL_String)
@@ -9227,7 +9825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9227 } 9825 }
9228 break; 9826 break;
9229 9827
9230 case ParcelMediaCommandEnum.Texture: 9828 case (uint)ParcelMediaCommandEnum.Texture:
9231 if ((i + 1) < commandList.Length) 9829 if ((i + 1) < commandList.Length)
9232 { 9830 {
9233 if (commandList.Data[i + 1] is LSL_String) 9831 if (commandList.Data[i + 1] is LSL_String)
@@ -9240,7 +9838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9240 } 9838 }
9241 break; 9839 break;
9242 9840
9243 case ParcelMediaCommandEnum.Time: 9841 case (uint)ParcelMediaCommandEnum.Time:
9244 if ((i + 1) < commandList.Length) 9842 if ((i + 1) < commandList.Length)
9245 { 9843 {
9246 if (commandList.Data[i + 1] is LSL_Float) 9844 if (commandList.Data[i + 1] is LSL_Float)
@@ -9252,7 +9850,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9252 } 9850 }
9253 break; 9851 break;
9254 9852
9255 case ParcelMediaCommandEnum.AutoAlign: 9853 case (uint)ParcelMediaCommandEnum.AutoAlign:
9256 if ((i + 1) < commandList.Length) 9854 if ((i + 1) < commandList.Length)
9257 { 9855 {
9258 if (commandList.Data[i + 1] is LSL_Integer) 9856 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9266,7 +9864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 } 9864 }
9267 break; 9865 break;
9268 9866
9269 case ParcelMediaCommandEnum.Type: 9867 case (uint)ParcelMediaCommandEnum.Type:
9270 if ((i + 1) < commandList.Length) 9868 if ((i + 1) < commandList.Length)
9271 { 9869 {
9272 if (commandList.Data[i + 1] is LSL_String) 9870 if (commandList.Data[i + 1] is LSL_String)
@@ -9279,7 +9877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9279 } 9877 }
9280 break; 9878 break;
9281 9879
9282 case ParcelMediaCommandEnum.Desc: 9880 case (uint)ParcelMediaCommandEnum.Desc:
9283 if ((i + 1) < commandList.Length) 9881 if ((i + 1) < commandList.Length)
9284 { 9882 {
9285 if (commandList.Data[i + 1] is LSL_String) 9883 if (commandList.Data[i + 1] is LSL_String)
@@ -9292,7 +9890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9890 }
9293 break; 9891 break;
9294 9892
9295 case ParcelMediaCommandEnum.Size: 9893 case (uint)ParcelMediaCommandEnum.Size:
9296 if ((i + 2) < commandList.Length) 9894 if ((i + 2) < commandList.Length)
9297 { 9895 {
9298 if (commandList.Data[i + 1] is LSL_Integer) 9896 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9362,7 +9960,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9362 } 9960 }
9363 } 9961 }
9364 9962
9365 if (commandToSend != null) 9963 if (commandToSend != 0)
9366 { 9964 {
9367 // the commandList contained a start/stop/... command, too 9965 // the commandList contained a start/stop/... command, too
9368 if (presence == null) 9966 if (presence == null)
@@ -9399,7 +9997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9399 9997
9400 if (aList.Data[i] != null) 9998 if (aList.Data[i] != null)
9401 { 9999 {
9402 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10000 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9403 { 10001 {
9404 case ParcelMediaCommandEnum.Url: 10002 case ParcelMediaCommandEnum.Url:
9405 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10003 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9442,16 +10040,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9442 { 10040 {
9443 m_host.AddScriptLPS(1); 10041 m_host.AddScriptLPS(1);
9444 10042
9445 lock (m_host.TaskInventory) 10043 m_host.TaskInventory.LockItemsForRead(true);
10044 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9446 { 10045 {
9447 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10046 if (inv.Value.Name == name)
9448 { 10047 {
9449 if (inv.Value.Name == name) 10048 m_host.TaskInventory.LockItemsForRead(false);
9450 { 10049 return inv.Value.Type;
9451 return inv.Value.Type;
9452 }
9453 } 10050 }
9454 } 10051 }
10052 m_host.TaskInventory.LockItemsForRead(false);
9455 10053
9456 return -1; 10054 return -1;
9457 } 10055 }
@@ -9462,15 +10060,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9462 10060
9463 if (quick_pay_buttons.Data.Length < 4) 10061 if (quick_pay_buttons.Data.Length < 4)
9464 { 10062 {
9465 LSLError("List must have at least 4 elements"); 10063 int x;
9466 return; 10064 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10065 {
10066 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10067 }
9467 } 10068 }
9468 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10069 int[] nPrice = new int[5];
9469 10070 nPrice[0] = price;
9470 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10071 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9471 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10072 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9472 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10073 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9473 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10074 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10075 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9474 m_host.ParentGroup.HasGroupChanged = true; 10076 m_host.ParentGroup.HasGroupChanged = true;
9475 } 10077 }
9476 10078
@@ -9482,17 +10084,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9482 if (invItemID == UUID.Zero) 10084 if (invItemID == UUID.Zero)
9483 return new LSL_Vector(); 10085 return new LSL_Vector();
9484 10086
9485 lock (m_host.TaskInventory) 10087 m_host.TaskInventory.LockItemsForRead(true);
10088 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9486 { 10089 {
9487 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10090 m_host.TaskInventory.LockItemsForRead(false);
9488 return new LSL_Vector(); 10091 return new LSL_Vector();
10092 }
9489 10093
9490 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10094 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9491 { 10095 {
9492 ShoutError("No permissions to track the camera"); 10096 ShoutError("No permissions to track the camera");
9493 return new LSL_Vector(); 10097 m_host.TaskInventory.LockItemsForRead(false);
9494 } 10098 return new LSL_Vector();
9495 } 10099 }
10100 m_host.TaskInventory.LockItemsForRead(false);
9496 10101
9497 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10102 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9498 if (presence != null) 10103 if (presence != null)
@@ -9510,17 +10115,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9510 if (invItemID == UUID.Zero) 10115 if (invItemID == UUID.Zero)
9511 return new LSL_Rotation(); 10116 return new LSL_Rotation();
9512 10117
9513 lock (m_host.TaskInventory) 10118 m_host.TaskInventory.LockItemsForRead(true);
10119 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9514 { 10120 {
9515 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10121 m_host.TaskInventory.LockItemsForRead(false);
9516 return new LSL_Rotation(); 10122 return new LSL_Rotation();
9517 10123 }
9518 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10124 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9519 { 10125 {
9520 ShoutError("No permissions to track the camera"); 10126 ShoutError("No permissions to track the camera");
9521 return new LSL_Rotation(); 10127 m_host.TaskInventory.LockItemsForRead(false);
9522 } 10128 return new LSL_Rotation();
9523 } 10129 }
10130 m_host.TaskInventory.LockItemsForRead(false);
9524 10131
9525 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10132 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9526 if (presence != null) 10133 if (presence != null)
@@ -9582,8 +10189,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 { 10189 {
9583 m_host.AddScriptLPS(1); 10190 m_host.AddScriptLPS(1);
9584 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10191 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9585 if (detectedParams == null) return; // only works on the first detected avatar 10192 if (detectedParams == null)
9586 10193 {
10194 if (m_host.ParentGroup.IsAttachment == true)
10195 {
10196 detectedParams = new DetectParams();
10197 detectedParams.Key = m_host.OwnerID;
10198 }
10199 else
10200 {
10201 return;
10202 }
10203 }
10204
9587 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10205 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9588 if (avatar != null) 10206 if (avatar != null)
9589 { 10207 {
@@ -9591,6 +10209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9591 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10209 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9592 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10210 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9593 } 10211 }
10212
9594 ScriptSleep(1000); 10213 ScriptSleep(1000);
9595 } 10214 }
9596 10215
@@ -9683,14 +10302,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9683 if (objectID == UUID.Zero) return; 10302 if (objectID == UUID.Zero) return;
9684 10303
9685 UUID agentID; 10304 UUID agentID;
9686 lock (m_host.TaskInventory) 10305 m_host.TaskInventory.LockItemsForRead(true);
9687 { 10306 // we need the permission first, to know which avatar we want to set the camera for
9688 // we need the permission first, to know which avatar we want to set the camera for 10307 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9689 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9690 10308
9691 if (agentID == UUID.Zero) return; 10309 if (agentID == UUID.Zero)
9692 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10310 {
10311 m_host.TaskInventory.LockItemsForRead(false);
10312 return;
9693 } 10313 }
10314 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10315 {
10316 m_host.TaskInventory.LockItemsForRead(false);
10317 return;
10318 }
10319 m_host.TaskInventory.LockItemsForRead(false);
9694 10320
9695 ScenePresence presence = World.GetScenePresence(agentID); 10321 ScenePresence presence = World.GetScenePresence(agentID);
9696 10322
@@ -9699,12 +10325,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9699 10325
9700 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10326 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9701 object[] data = rules.Data; 10327 object[] data = rules.Data;
9702 for (int i = 0; i < data.Length; ++i) { 10328 for (int i = 0; i < data.Length; ++i)
10329 {
9703 int type = Convert.ToInt32(data[i++].ToString()); 10330 int type = Convert.ToInt32(data[i++].ToString());
9704 if (i >= data.Length) break; // odd number of entries => ignore the last 10331 if (i >= data.Length) break; // odd number of entries => ignore the last
9705 10332
9706 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10333 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9707 switch (type) { 10334 switch (type)
10335 {
9708 case ScriptBaseClass.CAMERA_FOCUS: 10336 case ScriptBaseClass.CAMERA_FOCUS:
9709 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10337 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9710 case ScriptBaseClass.CAMERA_POSITION: 10338 case ScriptBaseClass.CAMERA_POSITION:
@@ -9740,12 +10368,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9740 10368
9741 // we need the permission first, to know which avatar we want to clear the camera for 10369 // we need the permission first, to know which avatar we want to clear the camera for
9742 UUID agentID; 10370 UUID agentID;
9743 lock (m_host.TaskInventory) 10371 m_host.TaskInventory.LockItemsForRead(true);
10372 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10373 if (agentID == UUID.Zero)
9744 { 10374 {
9745 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10375 m_host.TaskInventory.LockItemsForRead(false);
9746 if (agentID == UUID.Zero) return; 10376 return;
9747 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10377 }
10378 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10379 {
10380 m_host.TaskInventory.LockItemsForRead(false);
10381 return;
9748 } 10382 }
10383 m_host.TaskInventory.LockItemsForRead(false);
9749 10384
9750 ScenePresence presence = World.GetScenePresence(agentID); 10385 ScenePresence presence = World.GetScenePresence(agentID);
9751 10386
@@ -9812,19 +10447,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9812 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10447 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9813 { 10448 {
9814 m_host.AddScriptLPS(1); 10449 m_host.AddScriptLPS(1);
9815 string ret = String.Empty; 10450
9816 string src1 = llBase64ToString(str1); 10451 if (str1 == String.Empty)
9817 string src2 = llBase64ToString(str2); 10452 return String.Empty;
9818 int c = 0; 10453 if (str2 == String.Empty)
9819 for (int i = 0; i < src1.Length; i++) 10454 return str1;
10455
10456 int len = str2.Length;
10457 if ((len % 4) != 0) // LL is EVIL!!!!
10458 {
10459 while (str2.EndsWith("="))
10460 str2 = str2.Substring(0, str2.Length - 1);
10461
10462 len = str2.Length;
10463 int mod = len % 4;
10464
10465 if (mod == 1)
10466 str2 = str2.Substring(0, str2.Length - 1);
10467 else if (mod == 2)
10468 str2 += "==";
10469 else if (mod == 3)
10470 str2 += "=";
10471 }
10472
10473 byte[] data1;
10474 byte[] data2;
10475 try
10476 {
10477 data1 = Convert.FromBase64String(str1);
10478 data2 = Convert.FromBase64String(str2);
10479 }
10480 catch (Exception)
10481 {
10482 return new LSL_String(String.Empty);
10483 }
10484
10485 byte[] d2 = new Byte[data1.Length];
10486 int pos = 0;
10487
10488 if (data1.Length <= data2.Length)
9820 { 10489 {
9821 ret += (char) (src1[i] ^ src2[c]); 10490 Array.Copy(data2, 0, d2, 0, data1.Length);
10491 }
10492 else
10493 {
10494 while (pos < data1.Length)
10495 {
10496 len = data1.Length - pos;
10497 if (len > data2.Length)
10498 len = data2.Length;
9822 10499
9823 c++; 10500 Array.Copy(data2, 0, d2, pos, len);
9824 if (c >= src2.Length) 10501 pos += len;
9825 c = 0; 10502 }
9826 } 10503 }
9827 return llStringToBase64(ret); 10504
10505 for (pos = 0 ; pos < data1.Length ; pos++ )
10506 data1[pos] ^= d2[pos];
10507
10508 return Convert.ToBase64String(data1);
9828 } 10509 }
9829 10510
9830 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10511 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9881,12 +10562,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9881 Regex r = new Regex(authregex); 10562 Regex r = new Regex(authregex);
9882 int[] gnums = r.GetGroupNumbers(); 10563 int[] gnums = r.GetGroupNumbers();
9883 Match m = r.Match(url); 10564 Match m = r.Match(url);
9884 if (m.Success) { 10565 if (m.Success)
9885 for (int i = 1; i < gnums.Length; i++) { 10566 {
10567 for (int i = 1; i < gnums.Length; i++)
10568 {
9886 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10569 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9887 //CaptureCollection cc = g.Captures; 10570 //CaptureCollection cc = g.Captures;
9888 } 10571 }
9889 if (m.Groups.Count == 5) { 10572 if (m.Groups.Count == 5)
10573 {
9890 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10574 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9891 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10575 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9892 } 10576 }
@@ -10172,15 +10856,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10172 10856
10173 internal UUID ScriptByName(string name) 10857 internal UUID ScriptByName(string name)
10174 { 10858 {
10175 lock (m_host.TaskInventory) 10859 m_host.TaskInventory.LockItemsForRead(true);
10860
10861 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10176 { 10862 {
10177 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10863 if (item.Type == 10 && item.Name == name)
10178 { 10864 {
10179 if (item.Type == 10 && item.Name == name) 10865 m_host.TaskInventory.LockItemsForRead(false);
10180 return item.ItemID; 10866 return item.ItemID;
10181 } 10867 }
10182 } 10868 }
10183 10869
10870 m_host.TaskInventory.LockItemsForRead(false);
10871
10184 return UUID.Zero; 10872 return UUID.Zero;
10185 } 10873 }
10186 10874
@@ -10221,6 +10909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10221 { 10909 {
10222 m_host.AddScriptLPS(1); 10910 m_host.AddScriptLPS(1);
10223 10911
10912 //Clone is thread safe
10224 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10913 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10225 10914
10226 UUID assetID = UUID.Zero; 10915 UUID assetID = UUID.Zero;
@@ -10283,6 +10972,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10283 { 10972 {
10284 m_host.AddScriptLPS(1); 10973 m_host.AddScriptLPS(1);
10285 10974
10975 //Clone is thread safe
10286 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10976 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10287 10977
10288 UUID assetID = UUID.Zero; 10978 UUID assetID = UUID.Zero;
@@ -10363,15 +11053,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10363 return GetLinkPrimitiveParams(obj, rules); 11053 return GetLinkPrimitiveParams(obj, rules);
10364 } 11054 }
10365 11055
10366 public void print(string str) 11056 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10367 { 11057 {
10368 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11058 List<SceneObjectPart> parts = GetLinkParts(link);
10369 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11059 if (parts.Count < 1)
10370 if (ossl != null) 11060 return 0;
10371 { 11061
10372 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11062 return GetNumberOfSides(parts[0]);
10373 m_log.Info("LSL print():" + str);
10374 }
10375 } 11063 }
10376 11064
10377 private string Name2Username(string name) 11065 private string Name2Username(string name)
@@ -10417,6 +11105,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10417 return rq.ToString(); 11105 return rq.ToString();
10418 } 11106 }
10419 11107
11108 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11109 {
11110 m_SayShoutCount = 0;
11111 }
10420 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11112 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10421 { 11113 {
10422 m_host.AddScriptLPS(1); 11114 m_host.AddScriptLPS(1);
@@ -10586,22 +11278,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10586 NotImplemented("llGetSPMaxMemory"); 11278 NotImplemented("llGetSPMaxMemory");
10587 } 11279 }
10588 11280
10589 public void llGetUsedMemory() 11281 public virtual LSL_Integer llGetUsedMemory()
10590 { 11282 {
10591 m_host.AddScriptLPS(1); 11283 m_host.AddScriptLPS(1);
10592 NotImplemented("llGetUsedMemory"); 11284 NotImplemented("llGetUsedMemory");
11285 return 0;
10593 } 11286 }
10594 11287
10595 public void llScriptProfiler(LSL_Integer flags) 11288 public void llScriptProfiler(LSL_Integer flags)
10596 { 11289 {
10597 m_host.AddScriptLPS(1); 11290 m_host.AddScriptLPS(1);
10598 NotImplemented("llScriptProfiler"); 11291 //NotImplemented("llScriptProfiler");
10599 } 11292 }
10600 11293
10601 public void llSetSoundQueueing(int queue) 11294 public void llSetSoundQueueing(int queue)
10602 { 11295 {
10603 m_host.AddScriptLPS(1); 11296 m_host.AddScriptLPS(1);
10604 NotImplemented("llSetSoundQueueing");
10605 } 11297 }
10606 11298
10607 public void llCollisionSprite(string impact_sprite) 11299 public void llCollisionSprite(string impact_sprite)
@@ -10613,7 +11305,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10613 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11305 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10614 { 11306 {
10615 m_host.AddScriptLPS(1); 11307 m_host.AddScriptLPS(1);
10616 NotImplemented("llGodLikeRezObject"); 11308
11309 if (!World.Permissions.IsGod(m_host.OwnerID))
11310 NotImplemented("llGodLikeRezObject");
11311
11312 AssetBase rezAsset = World.AssetService.Get(inventory);
11313 if (rezAsset == null)
11314 {
11315 llSay(0, "Asset not found");
11316 return;
11317 }
11318
11319 SceneObjectGroup group = null;
11320
11321 try
11322 {
11323 string xmlData = Utils.BytesToString(rezAsset.Data);
11324 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11325 }
11326 catch
11327 {
11328 llSay(0, "Asset not found");
11329 return;
11330 }
11331
11332 if (group == null)
11333 {
11334 llSay(0, "Asset not found");
11335 return;
11336 }
11337
11338 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11339 group.RootPart.AttachOffset = group.AbsolutePosition;
11340
11341 group.ResetIDs();
11342
11343 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11344 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11345 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11346 group.ScheduleGroupForFullUpdate();
11347
11348 // objects rezzed with this method are die_at_edge by default.
11349 group.RootPart.SetDieAtEdge(true);
11350
11351 group.ResumeScripts();
11352
11353 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11354 "object_rez", new Object[] {
11355 new LSL_String(
11356 group.RootPart.UUID.ToString()) },
11357 new DetectParams[0]));
10617 } 11358 }
10618 11359
10619 #endregion 11360 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index f3206ac..c0d2f38 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -203,7 +205,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
203 205
204 internal void OSSLError(string msg) 206 internal void OSSLError(string msg)
205 { 207 {
206 throw new Exception("OSSL Runtime Error: " + msg); 208 if (m_debuggerSafe)
209 {
210 OSSLShoutError(msg);
211 }
212 else
213 {
214 throw new Exception("OSSL Runtime Error: " + msg);
215 }
207 } 216 }
208 217
209 private void InitLSL() 218 private void InitLSL()
@@ -894,18 +903,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
894 if (target != null) 903 if (target != null)
895 { 904 {
896 UUID animID=UUID.Zero; 905 UUID animID=UUID.Zero;
897 lock (m_host.TaskInventory) 906 m_host.TaskInventory.LockItemsForRead(true);
907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
898 { 908 {
899 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 909 if (inv.Value.Name == animation)
900 { 910 {
901 if (inv.Value.Name == animation) 911 if (inv.Value.Type == (int)AssetType.Animation)
902 { 912 animID = inv.Value.AssetID;
903 if (inv.Value.Type == (int)AssetType.Animation) 913 continue;
904 animID = inv.Value.AssetID;
905 continue;
906 }
907 } 914 }
908 } 915 }
916 m_host.TaskInventory.LockItemsForRead(false);
909 if (animID == UUID.Zero) 917 if (animID == UUID.Zero)
910 target.Animator.AddAnimation(animation, m_host.UUID); 918 target.Animator.AddAnimation(animation, m_host.UUID);
911 else 919 else
@@ -927,18 +935,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
927 if (target != null) 935 if (target != null)
928 { 936 {
929 UUID animID = UUID.Zero; 937 UUID animID = UUID.Zero;
930 lock (m_host.TaskInventory) 938 m_host.TaskInventory.LockItemsForRead(true);
939 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
931 { 940 {
932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 941 if (inv.Value.Name == animation)
933 { 942 {
934 if (inv.Value.Name == animation) 943 if (inv.Value.Type == (int)AssetType.Animation)
935 { 944 animID = inv.Value.AssetID;
936 if (inv.Value.Type == (int)AssetType.Animation) 945 continue;
937 animID = inv.Value.AssetID;
938 continue;
939 }
940 } 946 }
941 } 947 }
948 m_host.TaskInventory.LockItemsForRead(false);
942 949
943 if (animID == UUID.Zero) 950 if (animID == UUID.Zero)
944 target.Animator.RemoveAnimation(animation); 951 target.Animator.RemoveAnimation(animation);
@@ -1895,6 +1902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1895 1902
1896 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1903 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1897 { 1904 {
1905 m_host.TaskInventory.LockItemsForRead(true);
1898 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1899 { 1907 {
1900 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1908 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1902,6 +1910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1902 assetID = item.AssetID; 1910 assetID = item.AssetID;
1903 } 1911 }
1904 } 1912 }
1913 m_host.TaskInventory.LockItemsForRead(false);
1905 } 1914 }
1906 1915
1907 if (assetID == UUID.Zero) 1916 if (assetID == UUID.Zero)
@@ -2225,8 +2234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2225 UUID x = module.CreateNPC(firstname, 2234 UUID x = module.CreateNPC(firstname,
2226 lastname, 2235 lastname,
2227 new Vector3((float) position.x, (float) position.y, (float) position.z), 2236 new Vector3((float) position.x, (float) position.y, (float) position.z),
2228 World, 2237 World,appearance);
2229 appearance);
2230 2238
2231 return new LSL_Key(x.ToString()); 2239 return new LSL_Key(x.ToString());
2232 } 2240 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 4ac7f8b..6de0773 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -429,6 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 435 q = avatar.Rotation;
433 } 436 }
434 437
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..4ad4123 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -405,7 +406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 406 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 407 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 408 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 409 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 410
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 3221833..a61d553 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index ce4661c..a1cf3df 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -376,6 +377,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
376 public const int PRIM_SCULPT_TYPE_TORUS = 2; 377 public const int PRIM_SCULPT_TYPE_TORUS = 2;
377 public const int PRIM_SCULPT_TYPE_PLANE = 3; 378 public const int PRIM_SCULPT_TYPE_PLANE = 3;
378 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 379 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
380 public const int PRIM_SCULPT_FLAG_INVERT = 64;
381 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
379 382
380 public const int MASK_BASE = 0; 383 public const int MASK_BASE = 0;
381 public const int MASK_OWNER = 1; 384 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..a88a1f4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -464,6 +466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 466 return m_LSL_Functions.llGetFreeMemory();
465 } 467 }
466 468
469 public LSL_Integer llGetUsedMemory()
470 {
471 return m_LSL_Functions.llGetUsedMemory();
472 }
473
467 public LSL_Integer llGetFreeURLs() 474 public LSL_Integer llGetFreeURLs()
468 { 475 {
469 return m_LSL_Functions.llGetFreeURLs(); 476 return m_LSL_Functions.llGetFreeURLs();
@@ -1878,9 +1885,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1885 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1886 }
1880 1887
1881 public void print(string str) 1888 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1889 {
1883 m_LSL_Functions.print(str); 1890 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1891 }
1885 } 1892 }
1886} 1893}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f9af9c1..9ff2e4d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -263,13 +264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
263 264
264 if (part != null) 265 if (part != null)
265 { 266 {
266 lock (part.TaskInventory) 267 part.TaskInventory.LockItemsForRead(true);
268 if (part.TaskInventory.ContainsKey(m_ItemID))
267 { 269 {
268 if (part.TaskInventory.ContainsKey(m_ItemID)) 270 m_thisScriptTask = part.TaskInventory[m_ItemID];
269 {
270 m_thisScriptTask = part.TaskInventory[m_ItemID];
271 }
272 } 271 }
272 part.TaskInventory.LockItemsForRead(false);
273 } 273 }
274 274
275 ApiManager am = new ApiManager(); 275 ApiManager am = new ApiManager();
@@ -296,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 297// lease.Register(this);
298 } 298 }
299 catch (Exception) 299 catch (Exception e)
300 { 300 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
302 } 303 }
303 304
304 try 305 try
@@ -459,14 +460,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
459 { 460 {
460 int permsMask; 461 int permsMask;
461 UUID permsGranter; 462 UUID permsGranter;
462 lock (part.TaskInventory) 463 part.TaskInventory.LockItemsForRead(true);
464 if (!part.TaskInventory.ContainsKey(m_ItemID))
463 { 465 {
464 if (!part.TaskInventory.ContainsKey(m_ItemID)) 466 part.TaskInventory.LockItemsForRead(false);
465 return; 467 return;
466
467 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
468 permsMask = part.TaskInventory[m_ItemID].PermsMask;
469 } 468 }
469 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
470 permsMask = part.TaskInventory[m_ItemID].PermsMask;
471 part.TaskInventory.LockItemsForRead(false);
470 472
471 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 473 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 { 474 {
@@ -575,6 +577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 return true; 577 return true;
576 } 578 }
577 579
580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
578 public void SetState(string state) 581 public void SetState(string state)
579 { 582 {
580 if (state == State) 583 if (state == State)
@@ -586,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
586 new DetectParams[0])); 589 new DetectParams[0]));
587 PostEvent(new EventParams("state_entry", new Object[0], 590 PostEvent(new EventParams("state_entry", new Object[0],
588 new DetectParams[0])); 591 new DetectParams[0]));
589 592
590 throw new EventAbortException(); 593 throw new EventAbortException();
591 } 594 }
592 595
@@ -669,41 +672,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
669 /// <returns></returns> 672 /// <returns></returns>
670 public object EventProcessor() 673 public object EventProcessor()
671 { 674 {
672 lock (m_Script) 675 EventParams data = null;
673 {
674// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
675 676
676 if (Suspended) 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
677 return 0;
678 678
679 EventParams data = null; 679 if (Suspended)
680 return 0;
680 681
681 lock (m_EventQueue) 682 lock (m_EventQueue)
683 {
684 data = (EventParams) m_EventQueue.Dequeue();
685 if (data == null) // Shouldn't happen
682 { 686 {
683 data = (EventParams) m_EventQueue.Dequeue(); 687 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
684 if (data == null) // Shouldn't happen
685 { 688 {
686 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 689 m_CurrentResult = m_Engine.QueueEventHandler(this);
687 {
688 m_CurrentResult = m_Engine.QueueEventHandler(this);
689 }
690 else
691 {
692 m_CurrentResult = null;
693 }
694 return 0;
695 } 690 }
696 691 else
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 { 692 {
701 if (m_ControlEventsInQueue > 0) 693 m_CurrentResult = null;
702 m_ControlEventsInQueue--;
703 } 694 }
704 if (data.EventName == "collision") 695 return 0;
705 m_CollisionInQueue = false; 696 }
697
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 {
702 if (m_ControlEventsInQueue > 0)
703 m_ControlEventsInQueue--;
706 } 704 }
705 if (data.EventName == "collision")
706 m_CollisionInQueue = false;
707 }
708
709 lock(m_Script)
710 {
707 711
708// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 713
@@ -860,6 +864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 864 new Object[0], new DetectParams[0]));
861 } 865 }
862 866
867 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 868 public void ApiResetScript()
864 { 869 {
865 // bool running = Running; 870 // bool running = Running;
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 1c16c87..402377d 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
103 private Dictionary<UUID, IScriptInstance> m_Scripts = 104 private Dictionary<UUID, IScriptInstance> m_Scripts =
104 new Dictionary<UUID, IScriptInstance>(); 105 new Dictionary<UUID, IScriptInstance>();
105 106
107 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
108
106 // Maps the asset ID to the assembly 109 // Maps the asset ID to the assembly
107 110
108 private Dictionary<UUID, string> m_Assemblies = 111 private Dictionary<UUID, string> m_Assemblies =
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
125 IWorkItemResult m_CurrentCompile = null; 128 IWorkItemResult m_CurrentCompile = null;
126 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 129 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
127 130
131 private void lockScriptsForRead(bool locked)
132 {
133 if (locked)
134 {
135 if (m_scriptsLock.RecursiveReadCount > 0)
136 {
137 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
138 m_scriptsLock.ExitReadLock();
139 }
140 if (m_scriptsLock.RecursiveWriteCount > 0)
141 {
142 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
143 m_scriptsLock.ExitWriteLock();
144 }
145
146 while (!m_scriptsLock.TryEnterReadLock(60000))
147 {
148 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
149 if (m_scriptsLock.IsWriteLockHeld)
150 {
151 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152 }
153 }
154 }
155 else
156 {
157 if (m_scriptsLock.RecursiveReadCount > 0)
158 {
159 m_scriptsLock.ExitReadLock();
160 }
161 }
162 }
163 private void lockScriptsForWrite(bool locked)
164 {
165 if (locked)
166 {
167 if (m_scriptsLock.RecursiveReadCount > 0)
168 {
169 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
170 m_scriptsLock.ExitReadLock();
171 }
172 if (m_scriptsLock.RecursiveWriteCount > 0)
173 {
174 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
175 m_scriptsLock.ExitWriteLock();
176 }
177
178 while (!m_scriptsLock.TryEnterWriteLock(60000))
179 {
180 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
181 if (m_scriptsLock.IsWriteLockHeld)
182 {
183 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
184 }
185 }
186 }
187 else
188 {
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_scriptsLock.ExitWriteLock();
192 }
193 }
194 }
195
128 public string ScriptEngineName 196 public string ScriptEngineName
129 { 197 {
130 get { return "XEngine"; } 198 get { return "XEngine"; }
@@ -445,47 +513,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
445 { 513 {
446 if (!m_Enabled) 514 if (!m_Enabled)
447 return; 515 return;
448 516 lockScriptsForRead(true);
449 lock (m_Scripts) 517 foreach (IScriptInstance instance in m_Scripts.Values)
450 { 518 {
451 m_log.InfoFormat( 519 // Force a final state save
452 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 520 //
453 521 if (m_Assemblies.ContainsKey(instance.AssetID))
454 foreach (IScriptInstance instance in m_Scripts.Values)
455 { 522 {
456 // Force a final state save 523 string assembly = m_Assemblies[instance.AssetID];
457 // 524 instance.SaveState(assembly);
458 if (m_Assemblies.ContainsKey(instance.AssetID)) 525 }
459 {
460 string assembly = m_Assemblies[instance.AssetID];
461 instance.SaveState(assembly);
462 }
463 526
464 // Clear the event queue and abort the instance thread 527 // Clear the event queue and abort the instance thread
465 // 528 //
466 instance.ClearQueue(); 529 instance.ClearQueue();
467 instance.Stop(0); 530 instance.Stop(0);
468 531
469 // Release events, timer, etc 532 // Release events, timer, etc
470 // 533 //
471 instance.DestroyScriptInstance(); 534 instance.DestroyScriptInstance();
472 535
473 // Unload scripts and app domains 536 // Unload scripts and app domains
474 // Must be done explicitly because they have infinite 537 // Must be done explicitly because they have infinite
475 // lifetime 538 // lifetime
476 // 539 //
477 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 540 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
478 if (m_DomainScripts[instance.AppDomain].Count == 0) 541 if (m_DomainScripts[instance.AppDomain].Count == 0)
479 { 542 {
480 m_DomainScripts.Remove(instance.AppDomain); 543 m_DomainScripts.Remove(instance.AppDomain);
481 UnloadAppDomain(instance.AppDomain); 544 UnloadAppDomain(instance.AppDomain);
482 }
483 } 545 }
484 m_Scripts.Clear();
485 m_PrimObjects.Clear();
486 m_Assemblies.Clear();
487 m_DomainScripts.Clear();
488 } 546 }
547 lockScriptsForRead(false);
548 lockScriptsForWrite(true);
549 m_Scripts.Clear();
550 lockScriptsForWrite(false);
551 m_PrimObjects.Clear();
552 m_Assemblies.Clear();
553 m_DomainScripts.Clear();
554
489 lock (m_ScriptEngines) 555 lock (m_ScriptEngines)
490 { 556 {
491 m_ScriptEngines.Remove(this); 557 m_ScriptEngines.Remove(this);
@@ -550,22 +616,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
550 616
551 List<IScriptInstance> instances = new List<IScriptInstance>(); 617 List<IScriptInstance> instances = new List<IScriptInstance>();
552 618
553 lock (m_Scripts) 619 lockScriptsForRead(true);
554 { 620 foreach (IScriptInstance instance in m_Scripts.Values)
555 foreach (IScriptInstance instance in m_Scripts.Values)
556 instances.Add(instance); 621 instances.Add(instance);
557 } 622 lockScriptsForRead(false);
558 623
559 foreach (IScriptInstance i in instances) 624 foreach (IScriptInstance i in instances)
560 { 625 {
561 string assembly = String.Empty; 626 string assembly = String.Empty;
562 627
563 lock (m_Scripts) 628
564 {
565 if (!m_Assemblies.ContainsKey(i.AssetID)) 629 if (!m_Assemblies.ContainsKey(i.AssetID))
566 continue; 630 continue;
567 assembly = m_Assemblies[i.AssetID]; 631 assembly = m_Assemblies[i.AssetID];
568 } 632
569 633
570 i.SaveState(assembly); 634 i.SaveState(assembly);
571 } 635 }
@@ -899,92 +963,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
899 } 963 }
900 964
901 ScriptInstance instance = null; 965 ScriptInstance instance = null;
902 lock (m_Scripts) 966 // Create the object record
967 lockScriptsForRead(true);
968 if ((!m_Scripts.ContainsKey(itemID)) ||
969 (m_Scripts[itemID].AssetID != assetID))
903 { 970 {
904 // Create the object record 971 lockScriptsForRead(false);
905 972
906 if ((!m_Scripts.ContainsKey(itemID)) || 973 UUID appDomain = assetID;
907 (m_Scripts[itemID].AssetID != assetID))
908 {
909 UUID appDomain = assetID;
910 974
911 if (part.ParentGroup.IsAttachment) 975 if (part.ParentGroup.IsAttachment)
912 appDomain = part.ParentGroup.RootPart.UUID; 976 appDomain = part.ParentGroup.RootPart.UUID;
913 977
914 if (!m_AppDomains.ContainsKey(appDomain)) 978 if (!m_AppDomains.ContainsKey(appDomain))
979 {
980 try
915 { 981 {
916 try 982 AppDomainSetup appSetup = new AppDomainSetup();
917 { 983 appSetup.PrivateBinPath = Path.Combine(
918 AppDomainSetup appSetup = new AppDomainSetup(); 984 m_ScriptEnginesPath,
919 appSetup.PrivateBinPath = Path.Combine( 985 m_Scene.RegionInfo.RegionID.ToString());
920 m_ScriptEnginesPath, 986
921 m_Scene.RegionInfo.RegionID.ToString()); 987 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
922 988 Evidence evidence = new Evidence(baseEvidence);
923 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 989
924 Evidence evidence = new Evidence(baseEvidence); 990 AppDomain sandbox;
925 991 if (m_AppDomainLoading)
926 AppDomain sandbox; 992 sandbox = AppDomain.CreateDomain(
927 if (m_AppDomainLoading) 993 m_Scene.RegionInfo.RegionID.ToString(),
928 sandbox = AppDomain.CreateDomain( 994 evidence, appSetup);
929 m_Scene.RegionInfo.RegionID.ToString(), 995 else
930 evidence, appSetup); 996 sandbox = AppDomain.CurrentDomain;
931 else 997
932 sandbox = AppDomain.CurrentDomain; 998 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
933 999 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
934 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1000 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
935 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1001 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
936 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 1002 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
937 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 1003 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
938 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 1004 //sandbox.SetAppDomainPolicy(sandboxPolicy);
939 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 1005
940 //sandbox.SetAppDomainPolicy(sandboxPolicy); 1006 m_AppDomains[appDomain] = sandbox;
941 1007
942 m_AppDomains[appDomain] = sandbox; 1008 m_AppDomains[appDomain].AssemblyResolve +=
943 1009 new ResolveEventHandler(
944 m_AppDomains[appDomain].AssemblyResolve += 1010 AssemblyResolver.OnAssemblyResolve);
945 new ResolveEventHandler( 1011 m_DomainScripts[appDomain] = new List<UUID>();
946 AssemblyResolver.OnAssemblyResolve); 1012 }
947 m_DomainScripts[appDomain] = new List<UUID>(); 1013 catch (Exception e)
948 } 1014 {
949 catch (Exception e) 1015 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1016 m_ScriptErrorMessage += "Exception creating app domain:\n";
1017 m_ScriptFailCount++;
1018 lock (m_AddingAssemblies)
950 { 1019 {
951 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1020 m_AddingAssemblies[assembly]--;
952 m_ScriptErrorMessage += "Exception creating app domain:\n";
953 m_ScriptFailCount++;
954 lock (m_AddingAssemblies)
955 {
956 m_AddingAssemblies[assembly]--;
957 }
958 return false;
959 } 1021 }
1022 return false;
960 } 1023 }
961 m_DomainScripts[appDomain].Add(itemID); 1024 }
962 1025 m_DomainScripts[appDomain].Add(itemID);
963 instance = new ScriptInstance(this, part, 1026
964 itemID, assetID, assembly, 1027 instance = new ScriptInstance(this, part,
965 m_AppDomains[appDomain], 1028 itemID, assetID, assembly,
966 part.ParentGroup.RootPart.Name, 1029 m_AppDomains[appDomain],
967 item.Name, startParam, postOnRez, 1030 part.ParentGroup.RootPart.Name,
968 stateSource, m_MaxScriptQueue); 1031 item.Name, startParam, postOnRez,
969 1032 stateSource, m_MaxScriptQueue);
970 m_log.DebugFormat( 1033
971 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1034 m_log.DebugFormat(
972 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1035 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1036 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
973 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1037 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
974 1038
975 if (presence != null) 1039 if (presence != null)
976 { 1040 {
977 ShowScriptSaveResponse(item.OwnerID, 1041 ShowScriptSaveResponse(item.OwnerID,
978 assetID, "Compile successful", true); 1042 assetID, "Compile successful", true);
979 }
980
981 instance.AppDomain = appDomain;
982 instance.LineMap = linemap;
983
984 m_Scripts[itemID] = instance;
985 } 1043 }
986 }
987 1044
1045 instance.AppDomain = appDomain;
1046 instance.LineMap = linemap;
1047 lockScriptsForWrite(true);
1048 m_Scripts[itemID] = instance;
1049 lockScriptsForWrite(false);
1050 }
1051 else
1052 {
1053 lockScriptsForRead(false);
1054 }
988 lock (m_PrimObjects) 1055 lock (m_PrimObjects)
989 { 1056 {
990 if (!m_PrimObjects.ContainsKey(localID)) 1057 if (!m_PrimObjects.ContainsKey(localID))
@@ -1003,9 +1070,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1003 m_AddingAssemblies[assembly]--; 1070 m_AddingAssemblies[assembly]--;
1004 } 1071 }
1005 1072
1006 if (instance != null) 1073 if (instance!=null)
1007 instance.Init(); 1074 instance.Init();
1008 1075
1009 return true; 1076 return true;
1010 } 1077 }
1011 1078
@@ -1018,20 +1085,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1018 m_CompileDict.Remove(itemID); 1085 m_CompileDict.Remove(itemID);
1019 } 1086 }
1020 1087
1021 IScriptInstance instance = null; 1088 lockScriptsForRead(true);
1022 1089 // Do we even have it?
1023 lock (m_Scripts) 1090 if (!m_Scripts.ContainsKey(itemID))
1024 { 1091 {
1025 // Do we even have it? 1092 // Do we even have it?
1026 if (!m_Scripts.ContainsKey(itemID)) 1093 if (!m_Scripts.ContainsKey(itemID))
1027 return; 1094 return;
1028 1095
1029 instance = m_Scripts[itemID]; 1096 lockScriptsForRead(false);
1097 lockScriptsForWrite(true);
1030 m_Scripts.Remove(itemID); 1098 m_Scripts.Remove(itemID);
1099 lockScriptsForWrite(false);
1100
1101 return;
1031 } 1102 }
1103
1032 1104
1105 IScriptInstance instance=m_Scripts[itemID];
1106 lockScriptsForRead(false);
1107 lockScriptsForWrite(true);
1108 m_Scripts.Remove(itemID);
1109 lockScriptsForWrite(false);
1033 instance.ClearQueue(); 1110 instance.ClearQueue();
1034 instance.Stop(0); 1111 instance.Stop(0);
1112
1035// bool objectRemoved = false; 1113// bool objectRemoved = false;
1036 1114
1037 lock (m_PrimObjects) 1115 lock (m_PrimObjects)
@@ -1067,11 +1145,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1067 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1145 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1068 if (handlerObjectRemoved != null) 1146 if (handlerObjectRemoved != null)
1069 { 1147 {
1070 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1148 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1071 handlerObjectRemoved(part.UUID); 1149 handlerObjectRemoved(part.UUID);
1072 } 1150 }
1073 1151
1074 1152 CleanAssemblies();
1153
1075 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1154 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1076 if (handlerScriptRemoved != null) 1155 if (handlerScriptRemoved != null)
1077 handlerScriptRemoved(itemID); 1156 handlerScriptRemoved(itemID);
@@ -1213,7 +1292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return false; 1292 return false;
1214 1293
1215 uuids = m_PrimObjects[localID]; 1294 uuids = m_PrimObjects[localID];
1216 } 1295
1217 1296
1218 foreach (UUID itemID in uuids) 1297 foreach (UUID itemID in uuids)
1219 { 1298 {
@@ -1231,6 +1310,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1231 result = true; 1310 result = true;
1232 } 1311 }
1233 } 1312 }
1313 }
1234 1314
1235 return result; 1315 return result;
1236 } 1316 }
@@ -1330,12 +1410,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1330 private IScriptInstance GetInstance(UUID itemID) 1410 private IScriptInstance GetInstance(UUID itemID)
1331 { 1411 {
1332 IScriptInstance instance; 1412 IScriptInstance instance;
1333 lock (m_Scripts) 1413 lockScriptsForRead(true);
1414 if (!m_Scripts.ContainsKey(itemID))
1334 { 1415 {
1335 if (!m_Scripts.ContainsKey(itemID)) 1416 lockScriptsForRead(false);
1336 return null; 1417 return null;
1337 instance = m_Scripts[itemID];
1338 } 1418 }
1419 instance = m_Scripts[itemID];
1420 lockScriptsForRead(false);
1339 return instance; 1421 return instance;
1340 } 1422 }
1341 1423
@@ -1359,6 +1441,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1359 return false; 1441 return false;
1360 } 1442 }
1361 1443
1444 [DebuggerNonUserCode]
1362 public void ApiResetScript(UUID itemID) 1445 public void ApiResetScript(UUID itemID)
1363 { 1446 {
1364 IScriptInstance instance = GetInstance(itemID); 1447 IScriptInstance instance = GetInstance(itemID);
@@ -1410,6 +1493,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1410 return UUID.Zero; 1493 return UUID.Zero;
1411 } 1494 }
1412 1495
1496 [DebuggerNonUserCode]
1413 public void SetState(UUID itemID, string newState) 1497 public void SetState(UUID itemID, string newState)
1414 { 1498 {
1415 IScriptInstance instance = GetInstance(itemID); 1499 IScriptInstance instance = GetInstance(itemID);
@@ -1430,11 +1514,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1430 { 1514 {
1431 List<IScriptInstance> instances = new List<IScriptInstance>(); 1515 List<IScriptInstance> instances = new List<IScriptInstance>();
1432 1516
1433 lock (m_Scripts) 1517 lockScriptsForRead(true);
1434 { 1518 foreach (IScriptInstance instance in m_Scripts.Values)
1435 foreach (IScriptInstance instance in m_Scripts.Values)
1436 instances.Add(instance); 1519 instances.Add(instance);
1437 } 1520 lockScriptsForRead(false);
1438 1521
1439 foreach (IScriptInstance i in instances) 1522 foreach (IScriptInstance i in instances)
1440 { 1523 {
@@ -1811,5 +1894,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1811 if (instance != null) 1894 if (instance != null)
1812 instance.Resume(); 1895 instance.Resume();
1813 } 1896 }
1897
1898 public bool HasScript(UUID itemID, out bool running)
1899 {
1900 running = true;
1901
1902 IScriptInstance instance = GetInstance(itemID);
1903 if (instance == null)
1904 return false;
1905
1906 running = instance.Running;
1907 return true;
1908 }
1814 } 1909 }
1815} \ No newline at end of file 1910} \ No newline at end of file