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.cs2243
-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, 985 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 b8e9878..0e0c2b7 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;
@@ -3351,10 +3674,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3351 3674
3352 TaskInventoryItem item; 3675 TaskInventoryItem item;
3353 3676
3354 lock (m_host.TaskInventory) 3677
3678 m_host.TaskInventory.LockItemsForRead(true);
3679 if (!m_host.TaskInventory.ContainsKey(invItemID))
3680 {
3681 m_host.TaskInventory.LockItemsForRead(false);
3682 return;
3683 }
3684 else
3355 { 3685 {
3356 item = m_host.TaskInventory[invItemID]; 3686 item = m_host.TaskInventory[invItemID];
3357 } 3687 }
3688 m_host.TaskInventory.LockItemsForRead(false);
3358 3689
3359 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3690 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3360 { 3691 {
@@ -3382,15 +3713,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3382 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3713 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3383 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3714 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3384 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3715 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3716 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3385 ScriptBaseClass.PERMISSION_ATTACH; 3717 ScriptBaseClass.PERMISSION_ATTACH;
3386 3718
3387 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3719 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3388 { 3720 {
3389 lock (m_host.TaskInventory) 3721 m_host.TaskInventory.LockItemsForWrite(true);
3390 { 3722 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3391 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3723 m_host.TaskInventory[invItemID].PermsMask = perm;
3392 m_host.TaskInventory[invItemID].PermsMask = perm; 3724 m_host.TaskInventory.LockItemsForWrite(false);
3393 }
3394 3725
3395 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3726 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3396 "run_time_permissions", new Object[] { 3727 "run_time_permissions", new Object[] {
@@ -3400,28 +3731,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3400 return; 3731 return;
3401 } 3732 }
3402 } 3733 }
3403 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3734 else
3404 { 3735 {
3405 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3736 bool sitting = false;
3406 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3737 if (m_host.SitTargetAvatar == agentID)
3407 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3738 {
3408 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3739 sitting = true;
3409 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3740 }
3741 else
3742 {
3743 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3744 {
3745 if (p.SitTargetAvatar == agentID)
3746 sitting = true;
3747 }
3748 }
3410 3749
3411 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3750 if (sitting)
3412 { 3751 {
3413 lock (m_host.TaskInventory) 3752 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3753 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3754 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3755 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3756 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3757
3758 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3414 { 3759 {
3760 m_host.TaskInventory.LockItemsForWrite(true);
3415 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3761 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3416 m_host.TaskInventory[invItemID].PermsMask = perm; 3762 m_host.TaskInventory[invItemID].PermsMask = perm;
3417 } 3763 m_host.TaskInventory.LockItemsForWrite(false);
3418 3764
3419 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3765 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3420 "run_time_permissions", new Object[] { 3766 "run_time_permissions", new Object[] {
3421 new LSL_Integer(perm) }, 3767 new LSL_Integer(perm) },
3422 new DetectParams[0])); 3768 new DetectParams[0]));
3423 3769
3424 return; 3770 return;
3771 }
3425 } 3772 }
3426 } 3773 }
3427 3774
@@ -3435,11 +3782,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3435 3782
3436 if (!m_waitingForScriptAnswer) 3783 if (!m_waitingForScriptAnswer)
3437 { 3784 {
3438 lock (m_host.TaskInventory) 3785 m_host.TaskInventory.LockItemsForWrite(true);
3439 { 3786 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3440 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3787 m_host.TaskInventory[invItemID].PermsMask = 0;
3441 m_host.TaskInventory[invItemID].PermsMask = 0; 3788 m_host.TaskInventory.LockItemsForWrite(false);
3442 }
3443 3789
3444 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3790 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3445 m_waitingForScriptAnswer=true; 3791 m_waitingForScriptAnswer=true;
@@ -3474,10 +3820,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3474 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3820 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3475 llReleaseControls(); 3821 llReleaseControls();
3476 3822
3477 lock (m_host.TaskInventory) 3823
3478 { 3824 m_host.TaskInventory.LockItemsForWrite(true);
3479 m_host.TaskInventory[invItemID].PermsMask = answer; 3825 m_host.TaskInventory[invItemID].PermsMask = answer;
3480 } 3826 m_host.TaskInventory.LockItemsForWrite(false);
3827
3481 3828
3482 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3829 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3483 "run_time_permissions", new Object[] { 3830 "run_time_permissions", new Object[] {
@@ -3489,16 +3836,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3489 { 3836 {
3490 m_host.AddScriptLPS(1); 3837 m_host.AddScriptLPS(1);
3491 3838
3492 lock (m_host.TaskInventory) 3839 m_host.TaskInventory.LockItemsForRead(true);
3840
3841 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3493 { 3842 {
3494 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3843 if (item.Type == 10 && item.ItemID == m_itemID)
3495 { 3844 {
3496 if (item.Type == 10 && item.ItemID == m_itemID) 3845 m_host.TaskInventory.LockItemsForRead(false);
3497 { 3846 return item.PermsGranter.ToString();
3498 return item.PermsGranter.ToString();
3499 }
3500 } 3847 }
3501 } 3848 }
3849 m_host.TaskInventory.LockItemsForRead(false);
3502 3850
3503 return UUID.Zero.ToString(); 3851 return UUID.Zero.ToString();
3504 } 3852 }
@@ -3507,19 +3855,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3507 { 3855 {
3508 m_host.AddScriptLPS(1); 3856 m_host.AddScriptLPS(1);
3509 3857
3510 lock (m_host.TaskInventory) 3858 m_host.TaskInventory.LockItemsForRead(true);
3859
3860 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3511 { 3861 {
3512 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3862 if (item.Type == 10 && item.ItemID == m_itemID)
3513 { 3863 {
3514 if (item.Type == 10 && item.ItemID == m_itemID) 3864 int perms = item.PermsMask;
3515 { 3865 if (m_automaticLinkPermission)
3516 int perms = item.PermsMask; 3866 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3517 if (m_automaticLinkPermission) 3867 m_host.TaskInventory.LockItemsForRead(false);
3518 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3868 return perms;
3519 return perms;
3520 }
3521 } 3869 }
3522 } 3870 }
3871 m_host.TaskInventory.LockItemsForRead(false);
3523 3872
3524 return 0; 3873 return 0;
3525 } 3874 }
@@ -3541,9 +3890,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3541 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3890 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3542 { 3891 {
3543 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3892 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3544 3893 if (parts.Count > 0)
3545 foreach (SceneObjectPart part in parts) 3894 {
3546 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3895 try
3896 {
3897 parts[0].ParentGroup.areUpdatesSuspended = true;
3898 foreach (SceneObjectPart part in parts)
3899 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3900 }
3901 finally
3902 {
3903 parts[0].ParentGroup.areUpdatesSuspended = false;
3904 }
3905 }
3547 } 3906 }
3548 3907
3549 public void llCreateLink(string target, int parent) 3908 public void llCreateLink(string target, int parent)
@@ -3556,11 +3915,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 return; 3915 return;
3557 3916
3558 TaskInventoryItem item; 3917 TaskInventoryItem item;
3559 lock (m_host.TaskInventory) 3918 m_host.TaskInventory.LockItemsForRead(true);
3560 { 3919 item = m_host.TaskInventory[invItemID];
3561 item = m_host.TaskInventory[invItemID]; 3920 m_host.TaskInventory.LockItemsForRead(false);
3562 } 3921
3563
3564 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3922 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3565 && !m_automaticLinkPermission) 3923 && !m_automaticLinkPermission)
3566 { 3924 {
@@ -3577,11 +3935,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3577 3935
3578 if (targetPart.ParentGroup.AttachmentPoint != 0) 3936 if (targetPart.ParentGroup.AttachmentPoint != 0)
3579 return; // Fail silently if attached 3937 return; // Fail silently if attached
3938
3939 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3940 return;
3941
3580 SceneObjectGroup parentPrim = null, childPrim = null; 3942 SceneObjectGroup parentPrim = null, childPrim = null;
3581 3943
3582 if (targetPart != null) 3944 if (targetPart != null)
3583 { 3945 {
3584 if (parent != 0) { 3946 if (parent != 0)
3947 {
3585 parentPrim = m_host.ParentGroup; 3948 parentPrim = m_host.ParentGroup;
3586 childPrim = targetPart.ParentGroup; 3949 childPrim = targetPart.ParentGroup;
3587 } 3950 }
@@ -3613,16 +3976,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3613 m_host.AddScriptLPS(1); 3976 m_host.AddScriptLPS(1);
3614 UUID invItemID = InventorySelf(); 3977 UUID invItemID = InventorySelf();
3615 3978
3616 lock (m_host.TaskInventory) 3979 m_host.TaskInventory.LockItemsForRead(true);
3617 {
3618 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3619 && !m_automaticLinkPermission) 3981 && !m_automaticLinkPermission)
3620 { 3982 {
3621 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3983 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3984 m_host.TaskInventory.LockItemsForRead(false);
3622 return; 3985 return;
3623 } 3986 }
3624 } 3987 m_host.TaskInventory.LockItemsForRead(false);
3625 3988
3626 if (linknum < ScriptBaseClass.LINK_THIS) 3989 if (linknum < ScriptBaseClass.LINK_THIS)
3627 return; 3990 return;
3628 3991
@@ -3661,10 +4024,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 // Restructuring Multiple Prims. 4024 // Restructuring Multiple Prims.
3662 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4025 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3663 parts.Remove(parentPrim.RootPart); 4026 parts.Remove(parentPrim.RootPart);
3664 foreach (SceneObjectPart part in parts) 4027 if (parts.Count > 0)
3665 { 4028 {
3666 parentPrim.DelinkFromGroup(part.LocalId, true); 4029 try
4030 {
4031 parts[0].ParentGroup.areUpdatesSuspended = true;
4032 foreach (SceneObjectPart part in parts)
4033 {
4034 parentPrim.DelinkFromGroup(part.LocalId, true);
4035 }
4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
3667 } 4041 }
4042
3668 parentPrim.HasGroupChanged = true; 4043 parentPrim.HasGroupChanged = true;
3669 parentPrim.ScheduleGroupForFullUpdate(); 4044 parentPrim.ScheduleGroupForFullUpdate();
3670 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4045 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3673,11 +4048,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3673 { 4048 {
3674 SceneObjectPart newRoot = parts[0]; 4049 SceneObjectPart newRoot = parts[0];
3675 parts.Remove(newRoot); 4050 parts.Remove(newRoot);
3676 foreach (SceneObjectPart part in parts) 4051
4052 try
3677 { 4053 {
3678 part.UpdateFlag = 0; 4054 parts[0].ParentGroup.areUpdatesSuspended = true;
3679 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4055 foreach (SceneObjectPart part in parts)
4056 {
4057 part.UpdateFlag = 0;
4058 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4059 }
3680 } 4060 }
4061 finally
4062 {
4063 parts[0].ParentGroup.areUpdatesSuspended = false;
4064 }
4065
4066
3681 newRoot.ParentGroup.HasGroupChanged = true; 4067 newRoot.ParentGroup.HasGroupChanged = true;
3682 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4068 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3683 } 4069 }
@@ -3697,6 +4083,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 public void llBreakAllLinks() 4083 public void llBreakAllLinks()
3698 { 4084 {
3699 m_host.AddScriptLPS(1); 4085 m_host.AddScriptLPS(1);
4086
4087 UUID invItemID = InventorySelf();
4088
4089 TaskInventoryItem item;
4090 m_host.TaskInventory.LockItemsForRead(true);
4091 item = m_host.TaskInventory[invItemID];
4092 m_host.TaskInventory.LockItemsForRead(false);
4093
4094 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4095 && !m_automaticLinkPermission)
4096 {
4097 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4098 return;
4099 }
4100
3700 SceneObjectGroup parentPrim = m_host.ParentGroup; 4101 SceneObjectGroup parentPrim = m_host.ParentGroup;
3701 if (parentPrim.AttachmentPoint != 0) 4102 if (parentPrim.AttachmentPoint != 0)
3702 return; // Fail silently if attached 4103 return; // Fail silently if attached
@@ -3742,6 +4143,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 } 4143 }
3743 else 4144 else
3744 { 4145 {
4146 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4147 {
4148 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4149
4150 if (linknum < 0)
4151 return UUID.Zero.ToString();
4152
4153 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4154 if (avatars.Count > linknum)
4155 {
4156 return avatars[linknum].UUID.ToString();
4157 }
4158 }
3745 return UUID.Zero.ToString(); 4159 return UUID.Zero.ToString();
3746 } 4160 }
3747 } 4161 }
@@ -3840,17 +4254,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3840 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3841 int count = 0; 4255 int count = 0;
3842 4256
3843 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3844 { 4259 {
3845 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3846 { 4261 {
3847 if (inv.Value.Type == type || type == -1) 4262 count = count + 1;
3848 {
3849 count = count + 1;
3850 }
3851 } 4263 }
3852 } 4264 }
3853 4265
4266 m_host.TaskInventory.LockItemsForRead(false);
3854 return count; 4267 return count;
3855 } 4268 }
3856 4269
@@ -3859,16 +4272,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3859 m_host.AddScriptLPS(1); 4272 m_host.AddScriptLPS(1);
3860 ArrayList keys = new ArrayList(); 4273 ArrayList keys = new ArrayList();
3861 4274
3862 lock (m_host.TaskInventory) 4275 m_host.TaskInventory.LockItemsForRead(true);
4276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3863 { 4277 {
3864 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4278 if (inv.Value.Type == type || type == -1)
3865 { 4279 {
3866 if (inv.Value.Type == type || type == -1) 4280 keys.Add(inv.Value.Name);
3867 {
3868 keys.Add(inv.Value.Name);
3869 }
3870 } 4281 }
3871 } 4282 }
4283 m_host.TaskInventory.LockItemsForRead(false);
3872 4284
3873 if (keys.Count == 0) 4285 if (keys.Count == 0)
3874 { 4286 {
@@ -3905,25 +4317,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3905 } 4317 }
3906 4318
3907 // move the first object found with this inventory name 4319 // move the first object found with this inventory name
3908 lock (m_host.TaskInventory) 4320 m_host.TaskInventory.LockItemsForRead(true);
4321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3909 { 4322 {
3910 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4323 if (inv.Value.Name == inventory)
3911 { 4324 {
3912 if (inv.Value.Name == inventory) 4325 found = true;
3913 { 4326 objId = inv.Key;
3914 found = true; 4327 assetType = inv.Value.Type;
3915 objId = inv.Key; 4328 objName = inv.Value.Name;
3916 assetType = inv.Value.Type; 4329 break;
3917 objName = inv.Value.Name;
3918 break;
3919 }
3920 } 4330 }
3921 } 4331 }
4332 m_host.TaskInventory.LockItemsForRead(false);
3922 4333
3923 if (!found) 4334 if (!found)
3924 { 4335 {
3925 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4336 llSay(0, String.Format("Could not find object '{0}'", inventory));
3926 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4337 return;
4338// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3927 } 4339 }
3928 4340
3929 // check if destination is an object 4341 // check if destination is an object
@@ -3949,6 +4361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3949 return; 4361 return;
3950 } 4362 }
3951 } 4363 }
4364
3952 // destination is an avatar 4365 // destination is an avatar
3953 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4366 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3954 4367
@@ -3971,26 +4384,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 bucket); 4384 bucket);
3972 if (m_TransferModule != null) 4385 if (m_TransferModule != null)
3973 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4386 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4387
4388 //This delay should only occur when giving inventory to avatars.
3974 ScriptSleep(3000); 4389 ScriptSleep(3000);
3975 } 4390 }
3976 } 4391 }
3977 4392
4393 [DebuggerNonUserCode]
3978 public void llRemoveInventory(string name) 4394 public void llRemoveInventory(string name)
3979 { 4395 {
3980 m_host.AddScriptLPS(1); 4396 m_host.AddScriptLPS(1);
3981 4397
3982 lock (m_host.TaskInventory) 4398 List<TaskInventoryItem> inv;
4399 try
3983 { 4400 {
3984 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4401 m_host.TaskInventory.LockItemsForRead(true);
4402 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4403 }
4404 finally
4405 {
4406 m_host.TaskInventory.LockItemsForRead(false);
4407 }
4408 foreach (TaskInventoryItem item in inv)
4409 {
4410 if (item.Name == name)
3985 { 4411 {
3986 if (item.Name == name) 4412 if (item.ItemID == m_itemID)
3987 { 4413 throw new ScriptDeleteException();
3988 if (item.ItemID == m_itemID) 4414 else
3989 throw new ScriptDeleteException(); 4415 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3990 else 4416 return;
3991 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3992 return;
3993 }
3994 } 4417 }
3995 } 4418 }
3996 } 4419 }
@@ -4025,112 +4448,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4025 { 4448 {
4026 m_host.AddScriptLPS(1); 4449 m_host.AddScriptLPS(1);
4027 4450
4028 UUID uuid = (UUID)id; 4451 UUID uuid;
4029 PresenceInfo pinfo = null; 4452 if (UUID.TryParse(id, out uuid))
4030 UserAccount account;
4031
4032 UserInfoCacheEntry ce;
4033 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4034 { 4453 {
4035 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4454 PresenceInfo pinfo = null;
4036 if (account == null) 4455 UserAccount account;
4456
4457 UserInfoCacheEntry ce;
4458 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4037 { 4459 {
4038 m_userInfoCache[uuid] = null; // Cache negative 4460 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4039 return UUID.Zero.ToString(); 4461 if (account == null)
4040 } 4462 {
4463 m_userInfoCache[uuid] = null; // Cache negative
4464 return UUID.Zero.ToString();
4465 }
4041 4466
4042 4467
4043 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4468 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4044 if (pinfos != null && pinfos.Length > 0) 4469 if (pinfos != null && pinfos.Length > 0)
4045 {
4046 foreach (PresenceInfo p in pinfos)
4047 { 4470 {
4048 if (p.RegionID != UUID.Zero) 4471 foreach (PresenceInfo p in pinfos)
4049 { 4472 {
4050 pinfo = p; 4473 if (p.RegionID != UUID.Zero)
4474 {
4475 pinfo = p;
4476 }
4051 } 4477 }
4052 } 4478 }
4053 }
4054 4479
4055 ce = new UserInfoCacheEntry(); 4480 ce = new UserInfoCacheEntry();
4056 ce.time = Util.EnvironmentTickCount(); 4481 ce.time = Util.EnvironmentTickCount();
4057 ce.account = account; 4482 ce.account = account;
4058 ce.pinfo = pinfo; 4483 ce.pinfo = pinfo;
4059 } 4484 m_userInfoCache[uuid] = ce;
4060 else 4485 }
4061 { 4486 else
4062 if (ce == null) 4487 {
4063 return UUID.Zero.ToString(); 4488 if (ce == null)
4489 return UUID.Zero.ToString();
4064 4490
4065 account = ce.account; 4491 account = ce.account;
4066 pinfo = ce.pinfo; 4492 pinfo = ce.pinfo;
4067 } 4493 }
4068 4494
4069 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4495 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4070 {
4071 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4072 if (pinfos != null && pinfos.Length > 0)
4073 { 4496 {
4074 foreach (PresenceInfo p in pinfos) 4497 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4498 if (pinfos != null && pinfos.Length > 0)
4075 { 4499 {
4076 if (p.RegionID != UUID.Zero) 4500 foreach (PresenceInfo p in pinfos)
4077 { 4501 {
4078 pinfo = p; 4502 if (p.RegionID != UUID.Zero)
4503 {
4504 pinfo = p;
4505 }
4079 } 4506 }
4080 } 4507 }
4081 } 4508 else
4082 else 4509 pinfo = null;
4083 pinfo = null;
4084 4510
4085 ce.time = Util.EnvironmentTickCount(); 4511 ce.time = Util.EnvironmentTickCount();
4086 ce.pinfo = pinfo; 4512 ce.pinfo = pinfo;
4087 } 4513 }
4088 4514
4089 string reply = String.Empty; 4515 string reply = String.Empty;
4090 4516
4091 switch (data) 4517 switch (data)
4092 { 4518 {
4093 case 1: // DATA_ONLINE (0|1) 4519 case 1: // DATA_ONLINE (0|1)
4094 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4520 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4095 reply = "1"; 4521 reply = "1";
4096 else 4522 else
4097 reply = "0"; 4523 reply = "0";
4098 break; 4524 break;
4099 case 2: // DATA_NAME (First Last) 4525 case 2: // DATA_NAME (First Last)
4100 reply = account.FirstName + " " + account.LastName; 4526 reply = account.FirstName + " " + account.LastName;
4101 break; 4527 break;
4102 case 3: // DATA_BORN (YYYY-MM-DD) 4528 case 3: // DATA_BORN (YYYY-MM-DD)
4103 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4529 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4104 born = born.AddSeconds(account.Created); 4530 born = born.AddSeconds(account.Created);
4105 reply = born.ToString("yyyy-MM-dd"); 4531 reply = born.ToString("yyyy-MM-dd");
4106 break; 4532 break;
4107 case 4: // DATA_RATING (0,0,0,0,0,0) 4533 case 4: // DATA_RATING (0,0,0,0,0,0)
4108 reply = "0,0,0,0,0,0"; 4534 reply = "0,0,0,0,0,0";
4109 break; 4535 break;
4110 case 8: // DATA_PAYINFO (0|1|2|3) 4536 case 8: // DATA_PAYINFO (0|1|2|3)
4111 reply = "0"; 4537 reply = "0";
4112 break; 4538 break;
4113 default: 4539 default:
4114 return UUID.Zero.ToString(); // Raise no event 4540 return UUID.Zero.ToString(); // Raise no event
4115 } 4541 }
4116 4542
4117 UUID rq = UUID.Random(); 4543 UUID rq = UUID.Random();
4118 4544
4119 UUID tid = AsyncCommands. 4545 UUID tid = AsyncCommands.
4120 DataserverPlugin.RegisterRequest(m_localID, 4546 DataserverPlugin.RegisterRequest(m_localID,
4121 m_itemID, rq.ToString()); 4547 m_itemID, rq.ToString());
4122 4548
4123 AsyncCommands. 4549 AsyncCommands.
4124 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4550 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4125 4551
4126 ScriptSleep(100); 4552 ScriptSleep(100);
4127 return tid.ToString(); 4553 return tid.ToString();
4554 }
4555 else
4556 {
4557 ShoutError("Invalid UUID passed to llRequestAgentData.");
4558 }
4559 return "";
4128 } 4560 }
4129 4561
4130 public LSL_String llRequestInventoryData(string name) 4562 public LSL_String llRequestInventoryData(string name)
4131 { 4563 {
4132 m_host.AddScriptLPS(1); 4564 m_host.AddScriptLPS(1);
4133 4565
4566 //Clone is thread safe
4134 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4567 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4135 4568
4136 foreach (TaskInventoryItem item in itemDictionary.Values) 4569 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4184,6 +4617,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4184 ScenePresence presence = World.GetScenePresence(agentId); 4617 ScenePresence presence = World.GetScenePresence(agentId);
4185 if (presence != null) 4618 if (presence != null)
4186 { 4619 {
4620 // agent must not be a god
4621 if (presence.UserLevel >= 200) return;
4622
4187 // agent must be over the owners land 4623 // agent must be over the owners land
4188 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4624 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4189 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4625 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4206,7 +4642,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4206 UUID av = new UUID(); 4642 UUID av = new UUID();
4207 if (!UUID.TryParse(agent,out av)) 4643 if (!UUID.TryParse(agent,out av))
4208 { 4644 {
4209 LSLError("First parameter to llDialog needs to be a key"); 4645 //LSLError("First parameter to llDialog needs to be a key");
4210 return; 4646 return;
4211 } 4647 }
4212 4648
@@ -4243,17 +4679,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4243 UUID soundId = UUID.Zero; 4679 UUID soundId = UUID.Zero;
4244 if (!UUID.TryParse(impact_sound, out soundId)) 4680 if (!UUID.TryParse(impact_sound, out soundId))
4245 { 4681 {
4246 lock (m_host.TaskInventory) 4682 m_host.TaskInventory.LockItemsForRead(true);
4683 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4247 { 4684 {
4248 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4685 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4249 { 4686 {
4250 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4687 soundId = item.AssetID;
4251 { 4688 break;
4252 soundId = item.AssetID;
4253 break;
4254 }
4255 } 4689 }
4256 } 4690 }
4691 m_host.TaskInventory.LockItemsForRead(false);
4257 } 4692 }
4258 m_host.CollisionSound = soundId; 4693 m_host.CollisionSound = soundId;
4259 m_host.CollisionSoundVolume = (float)impact_volume; 4694 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4293,6 +4728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4293 UUID partItemID; 4728 UUID partItemID;
4294 foreach (SceneObjectPart part in parts) 4729 foreach (SceneObjectPart part in parts)
4295 { 4730 {
4731 //Clone is thread safe
4296 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4732 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4297 4733
4298 foreach (TaskInventoryItem item in itemsDictionary.Values) 4734 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4507,17 +4943,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4507 4943
4508 m_host.AddScriptLPS(1); 4944 m_host.AddScriptLPS(1);
4509 4945
4510 lock (m_host.TaskInventory) 4946 m_host.TaskInventory.LockItemsForRead(true);
4947 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4511 { 4948 {
4512 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4949 if (item.Type == 10 && item.ItemID == m_itemID)
4513 { 4950 {
4514 if (item.Type == 10 && item.ItemID == m_itemID) 4951 result = item.Name!=null?item.Name:String.Empty;
4515 { 4952 break;
4516 result = item.Name != null ? item.Name : String.Empty;
4517 break;
4518 }
4519 } 4953 }
4520 } 4954 }
4955 m_host.TaskInventory.LockItemsForRead(false);
4521 4956
4522 return result; 4957 return result;
4523 } 4958 }
@@ -4686,23 +5121,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4686 { 5121 {
4687 m_host.AddScriptLPS(1); 5122 m_host.AddScriptLPS(1);
4688 5123
4689 lock (m_host.TaskInventory) 5124 m_host.TaskInventory.LockItemsForRead(true);
5125 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4690 { 5126 {
4691 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5127 if (inv.Value.Name == name)
4692 { 5128 {
4693 if (inv.Value.Name == name) 5129 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4694 { 5130 {
4695 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5131 m_host.TaskInventory.LockItemsForRead(false);
4696 { 5132 return inv.Value.AssetID.ToString();
4697 return inv.Value.AssetID.ToString(); 5133 }
4698 } 5134 else
4699 else 5135 {
4700 { 5136 m_host.TaskInventory.LockItemsForRead(false);
4701 return UUID.Zero.ToString(); 5137 return UUID.Zero.ToString();
4702 }
4703 } 5138 }
4704 } 5139 }
4705 } 5140 }
5141 m_host.TaskInventory.LockItemsForRead(false);
4706 5142
4707 return UUID.Zero.ToString(); 5143 return UUID.Zero.ToString();
4708 } 5144 }
@@ -4855,14 +5291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4855 { 5291 {
4856 m_host.AddScriptLPS(1); 5292 m_host.AddScriptLPS(1);
4857 5293
4858 if (src == null) 5294 return src.Length;
4859 {
4860 return 0;
4861 }
4862 else
4863 {
4864 return src.Length;
4865 }
4866 } 5295 }
4867 5296
4868 public LSL_Integer llList2Integer(LSL_List src, int index) 5297 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4908,7 +5337,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4908 else if (src.Data[index] is LSL_Float) 5337 else if (src.Data[index] is LSL_Float)
4909 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5338 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4910 else if (src.Data[index] is LSL_String) 5339 else if (src.Data[index] is LSL_String)
4911 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5340 {
5341 string str = ((LSL_String) src.Data[index]).m_string;
5342 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5343 if (m != Match.Empty)
5344 {
5345 str = m.Value;
5346 double d = 0.0;
5347 if (!Double.TryParse(str, out d))
5348 return 0.0;
5349
5350 return d;
5351 }
5352 return 0.0;
5353 }
4912 return Convert.ToDouble(src.Data[index]); 5354 return Convert.ToDouble(src.Data[index]);
4913 } 5355 }
4914 catch (FormatException) 5356 catch (FormatException)
@@ -5181,7 +5623,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5181 } 5623 }
5182 } 5624 }
5183 } 5625 }
5184 else { 5626 else
5627 {
5185 object[] array = new object[src.Length]; 5628 object[] array = new object[src.Length];
5186 Array.Copy(src.Data, 0, array, 0, src.Length); 5629 Array.Copy(src.Data, 0, array, 0, src.Length);
5187 result = new LSL_List(array); 5630 result = new LSL_List(array);
@@ -5632,10 +6075,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5632 m_host.AddScriptLPS(1); 6075 m_host.AddScriptLPS(1);
5633 6076
5634 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6077 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5635 6078 if (parts.Count > 0)
5636 foreach (var part in parts)
5637 { 6079 {
5638 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6080 try
6081 {
6082 parts[0].ParentGroup.areUpdatesSuspended = true;
6083 foreach (var part in parts)
6084 {
6085 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6086 }
6087 }
6088 finally
6089 {
6090 parts[0].ParentGroup.areUpdatesSuspended = false;
6091 }
5639 } 6092 }
5640 } 6093 }
5641 6094
@@ -5689,6 +6142,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5689 ScriptSleep(5000); 6142 ScriptSleep(5000);
5690 } 6143 }
5691 6144
6145 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6146 {
6147 return ParseString2List(str, separators, in_spacers, false);
6148 }
6149
5692 public LSL_Integer llOverMyLand(string id) 6150 public LSL_Integer llOverMyLand(string id)
5693 { 6151 {
5694 m_host.AddScriptLPS(1); 6152 m_host.AddScriptLPS(1);
@@ -5889,7 +6347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5889 return m_host.ParentGroup.AttachmentPoint; 6347 return m_host.ParentGroup.AttachmentPoint;
5890 } 6348 }
5891 6349
5892 public LSL_Integer llGetFreeMemory() 6350 public virtual LSL_Integer llGetFreeMemory()
5893 { 6351 {
5894 m_host.AddScriptLPS(1); 6352 m_host.AddScriptLPS(1);
5895 // Make scripts designed for LSO happy 6353 // Make scripts designed for LSO happy
@@ -6006,7 +6464,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6006 SetParticleSystem(m_host, rules); 6464 SetParticleSystem(m_host, rules);
6007 } 6465 }
6008 6466
6009 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6467 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6468 {
6010 6469
6011 6470
6012 if (rules.Length == 0) 6471 if (rules.Length == 0)
@@ -6200,14 +6659,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6200 6659
6201 protected UUID GetTaskInventoryItem(string name) 6660 protected UUID GetTaskInventoryItem(string name)
6202 { 6661 {
6203 lock (m_host.TaskInventory) 6662 m_host.TaskInventory.LockItemsForRead(true);
6663 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6204 { 6664 {
6205 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6665 if (inv.Value.Name == name)
6206 { 6666 {
6207 if (inv.Value.Name == name) 6667 m_host.TaskInventory.LockItemsForRead(false);
6208 return inv.Key; 6668 return inv.Key;
6209 } 6669 }
6210 } 6670 }
6671 m_host.TaskInventory.LockItemsForRead(false);
6211 6672
6212 return UUID.Zero; 6673 return UUID.Zero;
6213 } 6674 }
@@ -6457,13 +6918,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6457 UUID av = new UUID(); 6918 UUID av = new UUID();
6458 if (!UUID.TryParse(avatar,out av)) 6919 if (!UUID.TryParse(avatar,out av))
6459 { 6920 {
6460 LSLError("First parameter to llDialog needs to be a key"); 6921 //LSLError("First parameter to llDialog needs to be a key");
6461 return; 6922 return;
6462 } 6923 }
6463 if (buttons.Length < 1) 6924 if (buttons.Length < 1)
6464 { 6925 {
6465 LSLError("No less than 1 button can be shown"); 6926 buttons.Add("OK");
6466 return;
6467 } 6927 }
6468 if (buttons.Length > 12) 6928 if (buttons.Length > 12)
6469 { 6929 {
@@ -6480,7 +6940,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6480 } 6940 }
6481 if (buttons.Data[i].ToString().Length > 24) 6941 if (buttons.Data[i].ToString().Length > 24)
6482 { 6942 {
6483 LSLError("button label cannot be longer than 24 characters"); 6943 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6484 return; 6944 return;
6485 } 6945 }
6486 buts[i] = buttons.Data[i].ToString(); 6946 buts[i] = buttons.Data[i].ToString();
@@ -6539,22 +6999,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6539 } 6999 }
6540 7000
6541 // copy the first script found with this inventory name 7001 // copy the first script found with this inventory name
6542 lock (m_host.TaskInventory) 7002 TaskInventoryItem scriptItem = null;
7003 m_host.TaskInventory.LockItemsForRead(true);
7004 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6543 { 7005 {
6544 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7006 if (inv.Value.Name == name)
6545 { 7007 {
6546 if (inv.Value.Name == name) 7008 // make sure the object is a script
7009 if (10 == inv.Value.Type)
6547 { 7010 {
6548 // make sure the object is a script 7011 found = true;
6549 if (10 == inv.Value.Type) 7012 srcId = inv.Key;
6550 { 7013 scriptItem = inv.Value;
6551 found = true; 7014 break;
6552 srcId = inv.Key;
6553 break;
6554 }
6555 } 7015 }
6556 } 7016 }
6557 } 7017 }
7018 m_host.TaskInventory.LockItemsForRead(false);
6558 7019
6559 if (!found) 7020 if (!found)
6560 { 7021 {
@@ -6562,8 +7023,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6562 return; 7023 return;
6563 } 7024 }
6564 7025
6565 // the rest of the permission checks are done in RezScript, so check the pin there as well 7026 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6566 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7027 if (dest != null)
7028 {
7029 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7030 {
7031 // the rest of the permission checks are done in RezScript, so check the pin there as well
7032 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7033
7034 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7035 m_host.Inventory.RemoveInventoryItem(srcId);
7036 }
7037 }
6567 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7038 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6568 ScriptSleep(3000); 7039 ScriptSleep(3000);
6569 } 7040 }
@@ -6626,19 +7097,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6626 public LSL_String llMD5String(string src, int nonce) 7097 public LSL_String llMD5String(string src, int nonce)
6627 { 7098 {
6628 m_host.AddScriptLPS(1); 7099 m_host.AddScriptLPS(1);
6629 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7100 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6630 } 7101 }
6631 7102
6632 public LSL_String llSHA1String(string src) 7103 public LSL_String llSHA1String(string src)
6633 { 7104 {
6634 m_host.AddScriptLPS(1); 7105 m_host.AddScriptLPS(1);
6635 return Util.SHA1Hash(src).ToLower(); 7106 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6636 } 7107 }
6637 7108
6638 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7109 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6639 { 7110 {
6640 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7111 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6641 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7112 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7113 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7114 return shapeBlock;
6642 7115
6643 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7116 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6644 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7117 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6743,6 +7216,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6743 // Prim type box, cylinder and prism. 7216 // Prim type box, cylinder and prism.
6744 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7217 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6745 { 7218 {
7219 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7220 return;
7221
6746 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7222 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6747 ObjectShapePacket.ObjectDataBlock shapeBlock; 7223 ObjectShapePacket.ObjectDataBlock shapeBlock;
6748 7224
@@ -6796,6 +7272,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6796 // Prim type sphere. 7272 // Prim type sphere.
6797 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7273 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6798 { 7274 {
7275 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7276 return;
7277
6799 ObjectShapePacket.ObjectDataBlock shapeBlock; 7278 ObjectShapePacket.ObjectDataBlock shapeBlock;
6800 7279
6801 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7280 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6837,6 +7316,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6837 // Prim type torus, tube and ring. 7316 // Prim type torus, tube and ring.
6838 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7317 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
6839 { 7318 {
7319 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7320 return;
7321
6840 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7322 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6841 ObjectShapePacket.ObjectDataBlock shapeBlock; 7323 ObjectShapePacket.ObjectDataBlock shapeBlock;
6842 7324
@@ -6972,6 +7454,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6972 // Prim type sculpt. 7454 // Prim type sculpt.
6973 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7455 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6974 { 7456 {
7457 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7458 return;
7459
6975 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7460 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6976 UUID sculptId; 7461 UUID sculptId;
6977 7462
@@ -6988,13 +7473,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6988 shapeBlock.PathScaleX = 100; 7473 shapeBlock.PathScaleX = 100;
6989 shapeBlock.PathScaleY = 150; 7474 shapeBlock.PathScaleY = 150;
6990 7475
6991 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7476 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6992 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7477 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6993 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7478 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6994 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7479 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6995 { 7480 {
6996 // default 7481 // default
6997 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7482 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6998 } 7483 }
6999 7484
7000 part.Shape.SetSculptProperties((byte)type, sculptId); 7485 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7010,32 +7495,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7010 ScriptSleep(200); 7495 ScriptSleep(200);
7011 } 7496 }
7012 7497
7013 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7498 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7014 { 7499 {
7015 m_host.AddScriptLPS(1); 7500 m_host.AddScriptLPS(1);
7016 7501
7017 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7502 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7503 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7504 if (parts.Count>0)
7505 {
7506 try
7507 {
7508 parts[0].ParentGroup.areUpdatesSuspended = true;
7509 foreach (SceneObjectPart part in parts)
7510 SetPrimParams(part, rules);
7511 }
7512 finally
7513 {
7514 parts[0].ParentGroup.areUpdatesSuspended = false;
7515 }
7516 }
7517 if (avatars.Count > 0)
7518 {
7519 foreach (ScenePresence avatar in avatars)
7520 SetPrimParams(avatar, rules);
7521 }
7522 }
7018 7523
7019 foreach (SceneObjectPart part in parts) 7524 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7020 SetPrimParams(part, rules); 7525 {
7021 7526 llSetLinkPrimitiveParamsFast(linknumber, rules);
7022 ScriptSleep(200); 7527 ScriptSleep(200);
7023 } 7528 }
7024 7529
7025 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7530 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7026 { 7531 {
7027 m_host.AddScriptLPS(1); 7532 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7533 //We only support PRIM_POSITION and PRIM_ROTATION
7028 7534
7029 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7535 int idx = 0;
7030 7536
7031 foreach (SceneObjectPart part in parts) 7537 while (idx < rules.Length)
7032 SetPrimParams(part, rules); 7538 {
7539 int code = rules.GetLSLIntegerItem(idx++);
7540
7541 int remain = rules.Length - idx;
7542
7543
7544
7545 switch (code)
7546 {
7547 case (int)ScriptBaseClass.PRIM_POSITION:
7548 if (remain < 1)
7549 return;
7550 LSL_Vector v;
7551 v = rules.GetVector3Item(idx++);
7552 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7553 av.SendAvatarDataToAllAgents();
7554
7555 break;
7556
7557 case (int)ScriptBaseClass.PRIM_ROTATION:
7558 if (remain < 1)
7559 return;
7560 LSL_Rotation r;
7561 r = rules.GetQuaternionItem(idx++);
7562 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7563 av.SendAvatarDataToAllAgents();
7564 break;
7565 }
7566 }
7033 } 7567 }
7034 7568
7035 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7569 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7036 { 7570 {
7571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7572 return;
7573
7037 int idx = 0; 7574 int idx = 0;
7038 7575
7576 bool positionChanged = false;
7577 LSL_Vector currentPosition = GetPartLocalPos(part);
7578
7039 while (idx < rules.Length) 7579 while (idx < rules.Length)
7040 { 7580 {
7041 int code = rules.GetLSLIntegerItem(idx++); 7581 int code = rules.GetLSLIntegerItem(idx++);
@@ -7044,7 +7584,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7044 7584
7045 int face; 7585 int face;
7046 LSL_Vector v; 7586 LSL_Vector v;
7047 7587
7048 switch (code) 7588 switch (code)
7049 { 7589 {
7050 case (int)ScriptBaseClass.PRIM_POSITION: 7590 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -7052,7 +7592,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7052 return; 7592 return;
7053 7593
7054 v=rules.GetVector3Item(idx++); 7594 v=rules.GetVector3Item(idx++);
7055 SetPos(part, v); 7595 positionChanged = true;
7596 currentPosition = GetSetPosTarget(part, v, currentPosition);
7056 7597
7057 break; 7598 break;
7058 case (int)ScriptBaseClass.PRIM_SIZE: 7599 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7397,6 +7938,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7397 break; 7938 break;
7398 } 7939 }
7399 } 7940 }
7941
7942 if (positionChanged)
7943 {
7944 if (part.ParentGroup.RootPart == part)
7945 {
7946 SceneObjectGroup parent = part.ParentGroup;
7947 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7948 }
7949 else
7950 {
7951 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7952 SceneObjectGroup parent = part.ParentGroup;
7953 parent.HasGroupChanged = true;
7954 parent.ScheduleGroupForTerseUpdate();
7955 }
7956 }
7400 } 7957 }
7401 7958
7402 public LSL_String llStringToBase64(string str) 7959 public LSL_String llStringToBase64(string str)
@@ -7545,13 +8102,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7545 public LSL_Integer llGetNumberOfPrims() 8102 public LSL_Integer llGetNumberOfPrims()
7546 { 8103 {
7547 m_host.AddScriptLPS(1); 8104 m_host.AddScriptLPS(1);
7548 int avatarCount = 0; 8105 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7549 World.ForEachScenePresence(delegate(ScenePresence presence) 8106
7550 {
7551 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7552 avatarCount++;
7553 });
7554
7555 return m_host.ParentGroup.PrimCount + avatarCount; 8107 return m_host.ParentGroup.PrimCount + avatarCount;
7556 } 8108 }
7557 8109
@@ -7567,55 +8119,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7567 m_host.AddScriptLPS(1); 8119 m_host.AddScriptLPS(1);
7568 UUID objID = UUID.Zero; 8120 UUID objID = UUID.Zero;
7569 LSL_List result = new LSL_List(); 8121 LSL_List result = new LSL_List();
8122
8123 // If the ID is not valid, return null result
7570 if (!UUID.TryParse(obj, out objID)) 8124 if (!UUID.TryParse(obj, out objID))
7571 { 8125 {
7572 result.Add(new LSL_Vector()); 8126 result.Add(new LSL_Vector());
7573 result.Add(new LSL_Vector()); 8127 result.Add(new LSL_Vector());
7574 return result; 8128 return result;
7575 } 8129 }
8130
8131 // Check if this is an attached prim. If so, replace
8132 // the UUID with the avatar UUID and report it's bounding box
8133 SceneObjectPart part = World.GetSceneObjectPart(objID);
8134 if (part != null && part.ParentGroup.IsAttachment)
8135 objID = part.ParentGroup.AttachedAvatar;
8136
8137 // Find out if this is an avatar ID. If so, return it's box
7576 ScenePresence presence = World.GetScenePresence(objID); 8138 ScenePresence presence = World.GetScenePresence(objID);
7577 if (presence != null) 8139 if (presence != null)
7578 { 8140 {
7579 if (presence.ParentID == 0) // not sat on an object 8141 // As per LSL Wiki, there is no difference between sitting
8142 // and standing avatar since server 1.36
8143 LSL_Vector lower;
8144 LSL_Vector upper;
8145 if (presence.Animator.Animations.DefaultAnimation.AnimID
8146 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7580 { 8147 {
7581 LSL_Vector lower; 8148 // This is for ground sitting avatars
7582 LSL_Vector upper; 8149 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7583 if (presence.Animator.Animations.DefaultAnimation.AnimID 8150 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7584 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8151 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7585 {
7586 // This is for ground sitting avatars
7587 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7588 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7589 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7590 }
7591 else
7592 {
7593 // This is for standing/flying avatars
7594 float height = presence.Appearance.AvatarHeight / 2.0f;
7595 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7596 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7597 }
7598 result.Add(lower);
7599 result.Add(upper);
7600 return result;
7601 } 8152 }
7602 else 8153 else
7603 { 8154 {
7604 // sitting on an object so we need the bounding box of that 8155 // This is for standing/flying avatars
7605 // which should include the avatar so set the UUID to the 8156 float height = presence.Appearance.AvatarHeight / 2.0f;
7606 // UUID of the object the avatar is sat on and allow it to fall through 8157 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7607 // to processing an object 8158 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7608 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7609 objID = p.UUID;
7610 } 8159 }
8160
8161 // Adjust to the documented error offsets (see LSL Wiki)
8162 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8163 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8164
8165 if (lower.x > upper.x)
8166 lower.x = upper.x;
8167 if (lower.y > upper.y)
8168 lower.y = upper.y;
8169 if (lower.z > upper.z)
8170 lower.z = upper.z;
8171
8172 result.Add(lower);
8173 result.Add(upper);
8174 return result;
7611 } 8175 }
7612 SceneObjectPart part = World.GetSceneObjectPart(objID); 8176
8177 part = World.GetSceneObjectPart(objID);
7613 // Currently only works for single prims without a sitting avatar 8178 // Currently only works for single prims without a sitting avatar
7614 if (part != null) 8179 if (part != null)
7615 { 8180 {
7616 Vector3 halfSize = part.Scale / 2.0f; 8181 float minX;
7617 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8182 float maxX;
7618 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8183 float minY;
8184 float maxY;
8185 float minZ;
8186 float maxZ;
8187
8188 // This BBox is in sim coordinates, with the offset being
8189 // a contained point.
8190 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8191 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8192
8193 minX -= offsets[0].X;
8194 maxX -= offsets[0].X;
8195 minY -= offsets[0].Y;
8196 maxY -= offsets[0].Y;
8197 minZ -= offsets[0].Z;
8198 maxZ -= offsets[0].Z;
8199
8200 LSL_Vector lower;
8201 LSL_Vector upper;
8202
8203 // Adjust to the documented error offsets (see LSL Wiki)
8204 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8205 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8206
8207 if (lower.x > upper.x)
8208 lower.x = upper.x;
8209 if (lower.y > upper.y)
8210 lower.y = upper.y;
8211 if (lower.z > upper.z)
8212 lower.z = upper.z;
8213
7619 result.Add(lower); 8214 result.Add(lower);
7620 result.Add(upper); 8215 result.Add(upper);
7621 return result; 8216 return result;
@@ -7695,13 +8290,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7695 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8290 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7696 part.AbsolutePosition.Y, 8291 part.AbsolutePosition.Y,
7697 part.AbsolutePosition.Z); 8292 part.AbsolutePosition.Z);
7698 // For some reason, the part.AbsolutePosition.* values do not change if the
7699 // linkset is rotated; they always reflect the child prim's world position
7700 // as though the linkset is unrotated. This is incompatible behavior with SL's
7701 // implementation, so will break scripts imported from there (not to mention it
7702 // makes it more difficult to determine a child prim's actual inworld position).
7703 if (part.ParentID != 0)
7704 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7705 res.Add(v); 8293 res.Add(v);
7706 break; 8294 break;
7707 8295
@@ -7872,56 +8460,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7872 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8460 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7873 if (remain < 1) 8461 if (remain < 1)
7874 return res; 8462 return res;
7875 8463 face = (int)rules.GetLSLIntegerItem(idx++);
7876 face=(int)rules.GetLSLIntegerItem(idx++);
7877 8464
7878 tex = part.Shape.Textures; 8465 tex = part.Shape.Textures;
8466 int shiny;
7879 if (face == ScriptBaseClass.ALL_SIDES) 8467 if (face == ScriptBaseClass.ALL_SIDES)
7880 { 8468 {
7881 for (face = 0; face < GetNumberOfSides(part); face++) 8469 for (face = 0; face < GetNumberOfSides(part); face++)
7882 { 8470 {
7883 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8471 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7884 // Convert Shininess to PRIM_SHINY_* 8472 if (shinyness == Shininess.High)
7885 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8473 {
7886 // PRIM_BUMP_* 8474 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7887 res.Add(new LSL_Integer((int)texface.Bump)); 8475 }
8476 else if (shinyness == Shininess.Medium)
8477 {
8478 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8479 }
8480 else if (shinyness == Shininess.Low)
8481 {
8482 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8483 }
8484 else
8485 {
8486 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8487 }
8488 res.Add(new LSL_Integer(shiny));
8489 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7888 } 8490 }
7889 } 8491 }
7890 else 8492 else
7891 { 8493 {
7892 if (face >= 0 && face < GetNumberOfSides(part)) 8494 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8495 if (shinyness == Shininess.High)
7893 { 8496 {
7894 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8497 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7895 // Convert Shininess to PRIM_SHINY_* 8498 }
7896 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8499 else if (shinyness == Shininess.Medium)
7897 // PRIM_BUMP_* 8500 {
7898 res.Add(new LSL_Integer((int)texface.Bump)); 8501 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
7899 } 8502 }
8503 else if (shinyness == Shininess.Low)
8504 {
8505 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8506 }
8507 else
8508 {
8509 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8510 }
8511 res.Add(new LSL_Integer(shiny));
8512 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7900 } 8513 }
7901 break; 8514 break;
7902 8515
7903 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8516 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7904 if (remain < 1) 8517 if (remain < 1)
7905 return res; 8518 return res;
7906 8519 face = (int)rules.GetLSLIntegerItem(idx++);
7907 face=(int)rules.GetLSLIntegerItem(idx++);
7908 8520
7909 tex = part.Shape.Textures; 8521 tex = part.Shape.Textures;
8522 int fullbright;
7910 if (face == ScriptBaseClass.ALL_SIDES) 8523 if (face == ScriptBaseClass.ALL_SIDES)
7911 { 8524 {
7912 for (face = 0; face < GetNumberOfSides(part); face++) 8525 for (face = 0; face < GetNumberOfSides(part); face++)
7913 { 8526 {
7914 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8527 if (tex.GetFace((uint)face).Fullbright == true)
7915 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8528 {
8529 fullbright = ScriptBaseClass.TRUE;
8530 }
8531 else
8532 {
8533 fullbright = ScriptBaseClass.FALSE;
8534 }
8535 res.Add(new LSL_Integer(fullbright));
7916 } 8536 }
7917 } 8537 }
7918 else 8538 else
7919 { 8539 {
7920 if (face >= 0 && face < GetNumberOfSides(part)) 8540 if (tex.GetFace((uint)face).Fullbright == true)
7921 { 8541 {
7922 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8542 fullbright = ScriptBaseClass.TRUE;
7923 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8543 }
8544 else
8545 {
8546 fullbright = ScriptBaseClass.FALSE;
7924 } 8547 }
8548 res.Add(new LSL_Integer(fullbright));
7925 } 8549 }
7926 break; 8550 break;
7927 8551
@@ -7943,27 +8567,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7943 break; 8567 break;
7944 8568
7945 case (int)ScriptBaseClass.PRIM_TEXGEN: 8569 case (int)ScriptBaseClass.PRIM_TEXGEN:
8570 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7946 if (remain < 1) 8571 if (remain < 1)
7947 return res; 8572 return res;
7948 8573 face = (int)rules.GetLSLIntegerItem(idx++);
7949 face=(int)rules.GetLSLIntegerItem(idx++);
7950 8574
7951 tex = part.Shape.Textures; 8575 tex = part.Shape.Textures;
7952 if (face == ScriptBaseClass.ALL_SIDES) 8576 if (face == ScriptBaseClass.ALL_SIDES)
7953 { 8577 {
7954 for (face = 0; face < GetNumberOfSides(part); face++) 8578 for (face = 0; face < GetNumberOfSides(part); face++)
7955 { 8579 {
7956 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8580 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7957 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8581 {
7958 res.Add(new LSL_Integer((uint)texgen >> 1)); 8582 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8583 }
8584 else
8585 {
8586 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8587 }
7959 } 8588 }
7960 } 8589 }
7961 else 8590 else
7962 { 8591 {
7963 if (face >= 0 && face < GetNumberOfSides(part)) 8592 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8593 {
8594 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8595 }
8596 else
7964 { 8597 {
7965 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8598 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7966 res.Add(new LSL_Integer((uint)texgen >> 1));
7967 } 8599 }
7968 } 8600 }
7969 break; 8601 break;
@@ -7986,28 +8618,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7986 case (int)ScriptBaseClass.PRIM_GLOW: 8618 case (int)ScriptBaseClass.PRIM_GLOW:
7987 if (remain < 1) 8619 if (remain < 1)
7988 return res; 8620 return res;
7989 8621 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8622
7992 tex = part.Shape.Textures; 8623 tex = part.Shape.Textures;
8624 float primglow;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8625 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8626 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8627 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8628 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8629 primglow = tex.GetFace((uint)face).Glow;
7998 res.Add(new LSL_Float(texface.Glow)); 8630 res.Add(new LSL_Float(primglow));
7999 } 8631 }
8000 } 8632 }
8001 else 8633 else
8002 { 8634 {
8003 if (face >= 0 && face < GetNumberOfSides(part)) 8635 primglow = tex.GetFace((uint)face).Glow;
8004 { 8636 res.Add(new LSL_Float(primglow));
8005 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8006 res.Add(new LSL_Float(texface.Glow));
8007 }
8008 } 8637 }
8009 break; 8638 break;
8010
8011 case (int)ScriptBaseClass.PRIM_TEXT: 8639 case (int)ScriptBaseClass.PRIM_TEXT:
8012 Color4 textColor = part.GetTextColor(); 8640 Color4 textColor = part.GetTextColor();
8013 res.Add(new LSL_String(part.Text)); 8641 res.Add(new LSL_String(part.Text));
@@ -8556,8 +9184,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8556 // The function returns an ordered list 9184 // The function returns an ordered list
8557 // representing the tokens found in the supplied 9185 // representing the tokens found in the supplied
8558 // sources string. If two successive tokenizers 9186 // sources string. If two successive tokenizers
8559 // are encountered, then a NULL entry is added 9187 // are encountered, then a null-string entry is
8560 // to the list. 9188 // added to the list.
8561 // 9189 //
8562 // It is a precondition that the source and 9190 // It is a precondition that the source and
8563 // toekizer lisst are non-null. If they are null, 9191 // toekizer lisst are non-null. If they are null,
@@ -8565,7 +9193,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8565 // while their lengths are being determined. 9193 // while their lengths are being determined.
8566 // 9194 //
8567 // A small amount of working memoryis required 9195 // A small amount of working memoryis required
8568 // of approximately 8*#tokenizers. 9196 // of approximately 8*#tokenizers + 8*srcstrlen.
8569 // 9197 //
8570 // There are many ways in which this function 9198 // There are many ways in which this function
8571 // can be implemented, this implementation is 9199 // can be implemented, this implementation is
@@ -8581,155 +9209,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8581 // and eliminates redundant tokenizers as soon 9209 // and eliminates redundant tokenizers as soon
8582 // as is possible. 9210 // as is possible.
8583 // 9211 //
8584 // The implementation tries to avoid any copying 9212 // The implementation tries to minimize temporary
8585 // of arrays or other objects. 9213 // garbage generation.
8586 // </remarks> 9214 // </remarks>
8587 9215
8588 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9216 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8589 { 9217 {
8590 int beginning = 0; 9218 return ParseString2List(src, separators, spacers, true);
8591 int srclen = src.Length; 9219 }
8592 int seplen = separators.Length;
8593 object[] separray = separators.Data;
8594 int spclen = spacers.Length;
8595 object[] spcarray = spacers.Data;
8596 int mlen = seplen+spclen;
8597
8598 int[] offset = new int[mlen+1];
8599 bool[] active = new bool[mlen];
8600
8601 int best;
8602 int j;
8603
8604 // Initial capacity reduces resize cost
8605 9220
8606 LSL_List tokens = new LSL_List(); 9221 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9222 {
9223 int srclen = src.Length;
9224 int seplen = separators.Length;
9225 object[] separray = separators.Data;
9226 int spclen = spacers.Length;
9227 object[] spcarray = spacers.Data;
9228 int dellen = 0;
9229 string[] delarray = new string[seplen+spclen];
8607 9230
8608 // All entries are initially valid 9231 int outlen = 0;
9232 string[] outarray = new string[srclen*2+1];
8609 9233
8610 for (int i = 0; i < mlen; i++) 9234 int i, j;
8611 active[i] = true; 9235 string d;
8612 9236
8613 offset[mlen] = srclen; 9237 m_host.AddScriptLPS(1);
8614 9238
8615 while (beginning < srclen) 9239 /*
9240 * Convert separator and spacer lists to C# strings.
9241 * Also filter out null strings so we don't hang.
9242 */
9243 for (i = 0; i < seplen; i ++)
8616 { 9244 {
9245 d = separray[i].ToString();
9246 if (d.Length > 0)
9247 {
9248 delarray[dellen++] = d;
9249 }
9250 }
9251 seplen = dellen;
8617 9252
8618 best = mlen; // as bad as it gets 9253 for (i = 0; i < spclen; i ++)
9254 {
9255 d = spcarray[i].ToString();
9256 if (d.Length > 0)
9257 {
9258 delarray[dellen++] = d;
9259 }
9260 }
8619 9261
8620 // Scan for separators 9262 /*
9263 * Scan through source string from beginning to end.
9264 */
9265 for (i = 0;;)
9266 {
8621 9267
8622 for (j = 0; j < seplen; j++) 9268 /*
9269 * Find earliest delimeter in src starting at i (if any).
9270 */
9271 int earliestDel = -1;
9272 int earliestSrc = srclen;
9273 string earliestStr = null;
9274 for (j = 0; j < dellen; j ++)
8623 { 9275 {
8624 if (separray[j].ToString() == String.Empty) 9276 d = delarray[j];
8625 active[j] = false; 9277 if (d != null)
8626
8627 if (active[j])
8628 { 9278 {
8629 // scan all of the markers 9279 int index = src.IndexOf(d, i);
8630 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9280 if (index < 0)
8631 { 9281 {
8632 // not present at all 9282 delarray[j] = null; // delim nowhere in src, don't check it anymore
8633 active[j] = false;
8634 } 9283 }
8635 else 9284 else if (index < earliestSrc)
8636 { 9285 {
8637 // present and correct 9286 earliestSrc = index; // where delimeter starts in source string
8638 if (offset[j] < offset[best]) 9287 earliestDel = j; // where delimeter is in delarray[]
8639 { 9288 earliestStr = d; // the delimeter string from delarray[]
8640 // closest so far 9289 if (index == i) break; // can't do any better than found at beg of string
8641 best = j;
8642 if (offset[best] == beginning)
8643 break;
8644 }
8645 } 9290 }
8646 } 9291 }
8647 } 9292 }
8648 9293
8649 // Scan for spacers 9294 /*
8650 9295 * Output source string starting at i through start of earliest delimeter.
8651 if (offset[best] != beginning) 9296 */
9297 if (keepNulls || (earliestSrc > i))
8652 { 9298 {
8653 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9299 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8654 {
8655 if (spcarray[j-seplen].ToString() == String.Empty)
8656 active[j] = false;
8657
8658 if (active[j])
8659 {
8660 // scan all of the markers
8661 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8662 {
8663 // not present at all
8664 active[j] = false;
8665 }
8666 else
8667 {
8668 // present and correct
8669 if (offset[j] < offset[best])
8670 {
8671 // closest so far
8672 best = j;
8673 }
8674 }
8675 }
8676 }
8677 } 9300 }
8678 9301
8679 // This is the normal exit from the scanning loop 9302 /*
9303 * If no delimeter found at or after i, we're done scanning.
9304 */
9305 if (earliestDel < 0) break;
8680 9306
8681 if (best == mlen) 9307 /*
9308 * If delimeter was a spacer, output the spacer.
9309 */
9310 if (earliestDel >= seplen)
8682 { 9311 {
8683 // no markers were found on this pass 9312 outarray[outlen++] = earliestStr;
8684 // so we're pretty much done
8685 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8686 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8687 break;
8688 } 9313 }
8689 9314
8690 // Otherwise we just add the newly delimited token 9315 /*
8691 // and recalculate where the search should continue. 9316 * Look at rest of src string following delimeter.
8692 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9317 */
8693 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9318 i = earliestSrc + earliestStr.Length;
8694
8695 if (best < seplen)
8696 {
8697 beginning = offset[best] + (separray[best].ToString()).Length;
8698 }
8699 else
8700 {
8701 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8702 string str = spcarray[best - seplen].ToString();
8703 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8704 tokens.Add(new LSL_String(str));
8705 }
8706 } 9319 }
8707 9320
8708 // This an awkward an not very intuitive boundary case. If the 9321 /*
8709 // last substring is a tokenizer, then there is an implied trailing 9322 * Make up an exact-sized output array suitable for an LSL_List object.
8710 // null list entry. Hopefully the single comparison will not be too 9323 */
8711 // arduous. Alternatively the 'break' could be replced with a return 9324 object[] outlist = new object[outlen];
8712 // but that's shabby programming. 9325 for (i = 0; i < outlen; i ++)
8713
8714 if ((beginning == srclen) && (keepNulls))
8715 { 9326 {
8716 if (srclen != 0) 9327 outlist[i] = new LSL_String(outarray[i]);
8717 tokens.Add(new LSL_String(""));
8718 } 9328 }
8719 9329 return new LSL_List(outlist);
8720 return tokens;
8721 }
8722
8723 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8724 {
8725 m_host.AddScriptLPS(1);
8726 return this.ParseString(src, separators, spacers, false);
8727 }
8728
8729 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8730 {
8731 m_host.AddScriptLPS(1);
8732 return this.ParseString(src, separators, spacers, true);
8733 } 9330 }
8734 9331
8735 public LSL_Integer llGetObjectPermMask(int mask) 9332 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8806,28 +9403,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8806 { 9403 {
8807 m_host.AddScriptLPS(1); 9404 m_host.AddScriptLPS(1);
8808 9405
8809 lock (m_host.TaskInventory) 9406 m_host.TaskInventory.LockItemsForRead(true);
9407 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8810 { 9408 {
8811 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9409 if (inv.Value.Name == item)
8812 { 9410 {
8813 if (inv.Value.Name == item) 9411 m_host.TaskInventory.LockItemsForRead(false);
9412 switch (mask)
8814 { 9413 {
8815 switch (mask) 9414 case 0:
8816 { 9415 return (int)inv.Value.BasePermissions;
8817 case 0: 9416 case 1:
8818 return (int)inv.Value.BasePermissions; 9417 return (int)inv.Value.CurrentPermissions;
8819 case 1: 9418 case 2:
8820 return (int)inv.Value.CurrentPermissions; 9419 return (int)inv.Value.GroupPermissions;
8821 case 2: 9420 case 3:
8822 return (int)inv.Value.GroupPermissions; 9421 return (int)inv.Value.EveryonePermissions;
8823 case 3: 9422 case 4:
8824 return (int)inv.Value.EveryonePermissions; 9423 return (int)inv.Value.NextPermissions;
8825 case 4:
8826 return (int)inv.Value.NextPermissions;
8827 }
8828 } 9424 }
8829 } 9425 }
8830 } 9426 }
9427 m_host.TaskInventory.LockItemsForRead(false);
8831 9428
8832 return -1; 9429 return -1;
8833 } 9430 }
@@ -8874,16 +9471,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8874 { 9471 {
8875 m_host.AddScriptLPS(1); 9472 m_host.AddScriptLPS(1);
8876 9473
8877 lock (m_host.TaskInventory) 9474 m_host.TaskInventory.LockItemsForRead(true);
9475 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8878 { 9476 {
8879 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9477 if (inv.Value.Name == item)
8880 { 9478 {
8881 if (inv.Value.Name == item) 9479 m_host.TaskInventory.LockItemsForRead(false);
8882 { 9480 return inv.Value.CreatorID.ToString();
8883 return inv.Value.CreatorID.ToString();
8884 }
8885 } 9481 }
8886 } 9482 }
9483 m_host.TaskInventory.LockItemsForRead(false);
8887 9484
8888 llSay(0, "No item name '" + item + "'"); 9485 llSay(0, "No item name '" + item + "'");
8889 9486
@@ -9031,7 +9628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9031 } 9628 }
9032 9629
9033 /// <summary> 9630 /// <summary>
9034 /// illListReplaceList removes the sub-list defined by the inclusive indices 9631 /// llListReplaceList removes the sub-list defined by the inclusive indices
9035 /// start and end and inserts the src list in its place. The inclusive 9632 /// start and end and inserts the src list in its place. The inclusive
9036 /// nature of the indices means that at least one element must be deleted 9633 /// nature of the indices means that at least one element must be deleted
9037 /// if the indices are within the bounds of the existing list. I.e. 2,2 9634 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9088,16 +9685,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9088 // based upon end. Note that if end exceeds the upper 9685 // based upon end. Note that if end exceeds the upper
9089 // bound in this case, the entire destination list 9686 // bound in this case, the entire destination list
9090 // is removed. 9687 // is removed.
9091 else 9688 else if (start == 0)
9092 { 9689 {
9093 if (end + 1 < dest.Length) 9690 if (end + 1 < dest.Length)
9094 {
9095 return src + dest.GetSublist(end + 1, -1); 9691 return src + dest.GetSublist(end + 1, -1);
9096 }
9097 else 9692 else
9098 {
9099 return src; 9693 return src;
9100 } 9694 }
9695 else // Start < 0
9696 {
9697 if (end + 1 < dest.Length)
9698 return dest.GetSublist(end + 1, -1);
9699 else
9700 return new LSL_List();
9101 } 9701 }
9102 } 9702 }
9103 // Finally, if start > end, we strip away a prefix and 9703 // Finally, if start > end, we strip away a prefix and
@@ -9148,17 +9748,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9148 int width = 0; 9748 int width = 0;
9149 int height = 0; 9749 int height = 0;
9150 9750
9151 ParcelMediaCommandEnum? commandToSend = null; 9751 uint commandToSend = 0;
9152 float time = 0.0f; // default is from start 9752 float time = 0.0f; // default is from start
9153 9753
9154 ScenePresence presence = null; 9754 ScenePresence presence = null;
9155 9755
9156 for (int i = 0; i < commandList.Data.Length; i++) 9756 for (int i = 0; i < commandList.Data.Length; i++)
9157 { 9757 {
9158 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9758 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9159 switch (command) 9759 switch (command)
9160 { 9760 {
9161 case ParcelMediaCommandEnum.Agent: 9761 case (uint)ParcelMediaCommandEnum.Agent:
9162 // we send only to one agent 9762 // we send only to one agent
9163 if ((i + 1) < commandList.Length) 9763 if ((i + 1) < commandList.Length)
9164 { 9764 {
@@ -9175,25 +9775,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9175 } 9775 }
9176 break; 9776 break;
9177 9777
9178 case ParcelMediaCommandEnum.Loop: 9778 case (uint)ParcelMediaCommandEnum.Loop:
9179 loop = 1; 9779 loop = 1;
9180 commandToSend = command; 9780 commandToSend = command;
9181 update = true; //need to send the media update packet to set looping 9781 update = true; //need to send the media update packet to set looping
9182 break; 9782 break;
9183 9783
9184 case ParcelMediaCommandEnum.Play: 9784 case (uint)ParcelMediaCommandEnum.Play:
9185 loop = 0; 9785 loop = 0;
9186 commandToSend = command; 9786 commandToSend = command;
9187 update = true; //need to send the media update packet to make sure it doesn't loop 9787 update = true; //need to send the media update packet to make sure it doesn't loop
9188 break; 9788 break;
9189 9789
9190 case ParcelMediaCommandEnum.Pause: 9790 case (uint)ParcelMediaCommandEnum.Pause:
9191 case ParcelMediaCommandEnum.Stop: 9791 case (uint)ParcelMediaCommandEnum.Stop:
9192 case ParcelMediaCommandEnum.Unload: 9792 case (uint)ParcelMediaCommandEnum.Unload:
9193 commandToSend = command; 9793 commandToSend = command;
9194 break; 9794 break;
9195 9795
9196 case ParcelMediaCommandEnum.Url: 9796 case (uint)ParcelMediaCommandEnum.Url:
9197 if ((i + 1) < commandList.Length) 9797 if ((i + 1) < commandList.Length)
9198 { 9798 {
9199 if (commandList.Data[i + 1] is LSL_String) 9799 if (commandList.Data[i + 1] is LSL_String)
@@ -9206,7 +9806,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9206 } 9806 }
9207 break; 9807 break;
9208 9808
9209 case ParcelMediaCommandEnum.Texture: 9809 case (uint)ParcelMediaCommandEnum.Texture:
9210 if ((i + 1) < commandList.Length) 9810 if ((i + 1) < commandList.Length)
9211 { 9811 {
9212 if (commandList.Data[i + 1] is LSL_String) 9812 if (commandList.Data[i + 1] is LSL_String)
@@ -9219,7 +9819,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9219 } 9819 }
9220 break; 9820 break;
9221 9821
9222 case ParcelMediaCommandEnum.Time: 9822 case (uint)ParcelMediaCommandEnum.Time:
9223 if ((i + 1) < commandList.Length) 9823 if ((i + 1) < commandList.Length)
9224 { 9824 {
9225 if (commandList.Data[i + 1] is LSL_Float) 9825 if (commandList.Data[i + 1] is LSL_Float)
@@ -9231,7 +9831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9231 } 9831 }
9232 break; 9832 break;
9233 9833
9234 case ParcelMediaCommandEnum.AutoAlign: 9834 case (uint)ParcelMediaCommandEnum.AutoAlign:
9235 if ((i + 1) < commandList.Length) 9835 if ((i + 1) < commandList.Length)
9236 { 9836 {
9237 if (commandList.Data[i + 1] is LSL_Integer) 9837 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9245,7 +9845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9245 } 9845 }
9246 break; 9846 break;
9247 9847
9248 case ParcelMediaCommandEnum.Type: 9848 case (uint)ParcelMediaCommandEnum.Type:
9249 if ((i + 1) < commandList.Length) 9849 if ((i + 1) < commandList.Length)
9250 { 9850 {
9251 if (commandList.Data[i + 1] is LSL_String) 9851 if (commandList.Data[i + 1] is LSL_String)
@@ -9258,7 +9858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9258 } 9858 }
9259 break; 9859 break;
9260 9860
9261 case ParcelMediaCommandEnum.Desc: 9861 case (uint)ParcelMediaCommandEnum.Desc:
9262 if ((i + 1) < commandList.Length) 9862 if ((i + 1) < commandList.Length)
9263 { 9863 {
9264 if (commandList.Data[i + 1] is LSL_String) 9864 if (commandList.Data[i + 1] is LSL_String)
@@ -9271,7 +9871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9271 } 9871 }
9272 break; 9872 break;
9273 9873
9274 case ParcelMediaCommandEnum.Size: 9874 case (uint)ParcelMediaCommandEnum.Size:
9275 if ((i + 2) < commandList.Length) 9875 if ((i + 2) < commandList.Length)
9276 { 9876 {
9277 if (commandList.Data[i + 1] is LSL_Integer) 9877 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9341,7 +9941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9341 } 9941 }
9342 } 9942 }
9343 9943
9344 if (commandToSend != null) 9944 if (commandToSend != 0)
9345 { 9945 {
9346 // the commandList contained a start/stop/... command, too 9946 // the commandList contained a start/stop/... command, too
9347 if (presence == null) 9947 if (presence == null)
@@ -9378,7 +9978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9378 9978
9379 if (aList.Data[i] != null) 9979 if (aList.Data[i] != null)
9380 { 9980 {
9381 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9981 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9382 { 9982 {
9383 case ParcelMediaCommandEnum.Url: 9983 case ParcelMediaCommandEnum.Url:
9384 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9984 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9421,16 +10021,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9421 { 10021 {
9422 m_host.AddScriptLPS(1); 10022 m_host.AddScriptLPS(1);
9423 10023
9424 lock (m_host.TaskInventory) 10024 m_host.TaskInventory.LockItemsForRead(true);
10025 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9425 { 10026 {
9426 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10027 if (inv.Value.Name == name)
9427 { 10028 {
9428 if (inv.Value.Name == name) 10029 m_host.TaskInventory.LockItemsForRead(false);
9429 { 10030 return inv.Value.Type;
9430 return inv.Value.Type;
9431 }
9432 } 10031 }
9433 } 10032 }
10033 m_host.TaskInventory.LockItemsForRead(false);
9434 10034
9435 return -1; 10035 return -1;
9436 } 10036 }
@@ -9441,15 +10041,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 10041
9442 if (quick_pay_buttons.Data.Length < 4) 10042 if (quick_pay_buttons.Data.Length < 4)
9443 { 10043 {
9444 LSLError("List must have at least 4 elements"); 10044 int x;
9445 return; 10045 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10046 {
10047 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10048 }
9446 } 10049 }
9447 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10050 int[] nPrice = new int[5];
9448 10051 nPrice[0] = price;
9449 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10052 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9450 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10053 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9451 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10054 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9452 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10055 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10056 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9453 m_host.ParentGroup.HasGroupChanged = true; 10057 m_host.ParentGroup.HasGroupChanged = true;
9454 } 10058 }
9455 10059
@@ -9461,17 +10065,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9461 if (invItemID == UUID.Zero) 10065 if (invItemID == UUID.Zero)
9462 return new LSL_Vector(); 10066 return new LSL_Vector();
9463 10067
9464 lock (m_host.TaskInventory) 10068 m_host.TaskInventory.LockItemsForRead(true);
10069 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9465 { 10070 {
9466 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10071 m_host.TaskInventory.LockItemsForRead(false);
9467 return new LSL_Vector(); 10072 return new LSL_Vector();
10073 }
9468 10074
9469 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10075 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9470 { 10076 {
9471 ShoutError("No permissions to track the camera"); 10077 ShoutError("No permissions to track the camera");
9472 return new LSL_Vector(); 10078 m_host.TaskInventory.LockItemsForRead(false);
9473 } 10079 return new LSL_Vector();
9474 } 10080 }
10081 m_host.TaskInventory.LockItemsForRead(false);
9475 10082
9476 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10083 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9477 if (presence != null) 10084 if (presence != null)
@@ -9489,17 +10096,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9489 if (invItemID == UUID.Zero) 10096 if (invItemID == UUID.Zero)
9490 return new LSL_Rotation(); 10097 return new LSL_Rotation();
9491 10098
9492 lock (m_host.TaskInventory) 10099 m_host.TaskInventory.LockItemsForRead(true);
10100 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9493 { 10101 {
9494 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10102 m_host.TaskInventory.LockItemsForRead(false);
9495 return new LSL_Rotation(); 10103 return new LSL_Rotation();
9496 10104 }
9497 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10105 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9498 { 10106 {
9499 ShoutError("No permissions to track the camera"); 10107 ShoutError("No permissions to track the camera");
9500 return new LSL_Rotation(); 10108 m_host.TaskInventory.LockItemsForRead(false);
9501 } 10109 return new LSL_Rotation();
9502 } 10110 }
10111 m_host.TaskInventory.LockItemsForRead(false);
9503 10112
9504 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10113 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9505 if (presence != null) 10114 if (presence != null)
@@ -9561,8 +10170,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9561 { 10170 {
9562 m_host.AddScriptLPS(1); 10171 m_host.AddScriptLPS(1);
9563 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10172 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9564 if (detectedParams == null) return; // only works on the first detected avatar 10173 if (detectedParams == null)
9565 10174 {
10175 if (m_host.ParentGroup.IsAttachment == true)
10176 {
10177 detectedParams = new DetectParams();
10178 detectedParams.Key = m_host.OwnerID;
10179 }
10180 else
10181 {
10182 return;
10183 }
10184 }
10185
9566 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10186 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9567 if (avatar != null) 10187 if (avatar != null)
9568 { 10188 {
@@ -9570,6 +10190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9570 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10190 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9571 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10191 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9572 } 10192 }
10193
9573 ScriptSleep(1000); 10194 ScriptSleep(1000);
9574 } 10195 }
9575 10196
@@ -9662,14 +10283,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9662 if (objectID == UUID.Zero) return; 10283 if (objectID == UUID.Zero) return;
9663 10284
9664 UUID agentID; 10285 UUID agentID;
9665 lock (m_host.TaskInventory) 10286 m_host.TaskInventory.LockItemsForRead(true);
9666 { 10287 // we need the permission first, to know which avatar we want to set the camera for
9667 // we need the permission first, to know which avatar we want to set the camera for 10288 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9668 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9669 10289
9670 if (agentID == UUID.Zero) return; 10290 if (agentID == UUID.Zero)
9671 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10291 {
10292 m_host.TaskInventory.LockItemsForRead(false);
10293 return;
9672 } 10294 }
10295 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10296 {
10297 m_host.TaskInventory.LockItemsForRead(false);
10298 return;
10299 }
10300 m_host.TaskInventory.LockItemsForRead(false);
9673 10301
9674 ScenePresence presence = World.GetScenePresence(agentID); 10302 ScenePresence presence = World.GetScenePresence(agentID);
9675 10303
@@ -9678,12 +10306,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 10306
9679 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10307 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9680 object[] data = rules.Data; 10308 object[] data = rules.Data;
9681 for (int i = 0; i < data.Length; ++i) { 10309 for (int i = 0; i < data.Length; ++i)
10310 {
9682 int type = Convert.ToInt32(data[i++].ToString()); 10311 int type = Convert.ToInt32(data[i++].ToString());
9683 if (i >= data.Length) break; // odd number of entries => ignore the last 10312 if (i >= data.Length) break; // odd number of entries => ignore the last
9684 10313
9685 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10314 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9686 switch (type) { 10315 switch (type)
10316 {
9687 case ScriptBaseClass.CAMERA_FOCUS: 10317 case ScriptBaseClass.CAMERA_FOCUS:
9688 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10318 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9689 case ScriptBaseClass.CAMERA_POSITION: 10319 case ScriptBaseClass.CAMERA_POSITION:
@@ -9719,12 +10349,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9719 10349
9720 // we need the permission first, to know which avatar we want to clear the camera for 10350 // we need the permission first, to know which avatar we want to clear the camera for
9721 UUID agentID; 10351 UUID agentID;
9722 lock (m_host.TaskInventory) 10352 m_host.TaskInventory.LockItemsForRead(true);
10353 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10354 if (agentID == UUID.Zero)
9723 { 10355 {
9724 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10356 m_host.TaskInventory.LockItemsForRead(false);
9725 if (agentID == UUID.Zero) return; 10357 return;
9726 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10358 }
10359 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10360 {
10361 m_host.TaskInventory.LockItemsForRead(false);
10362 return;
9727 } 10363 }
10364 m_host.TaskInventory.LockItemsForRead(false);
9728 10365
9729 ScenePresence presence = World.GetScenePresence(agentID); 10366 ScenePresence presence = World.GetScenePresence(agentID);
9730 10367
@@ -9791,19 +10428,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9791 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10428 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9792 { 10429 {
9793 m_host.AddScriptLPS(1); 10430 m_host.AddScriptLPS(1);
9794 string ret = String.Empty; 10431
9795 string src1 = llBase64ToString(str1); 10432 if (str1 == String.Empty)
9796 string src2 = llBase64ToString(str2); 10433 return String.Empty;
9797 int c = 0; 10434 if (str2 == String.Empty)
9798 for (int i = 0; i < src1.Length; i++) 10435 return str1;
10436
10437 int len = str2.Length;
10438 if ((len % 4) != 0) // LL is EVIL!!!!
10439 {
10440 while (str2.EndsWith("="))
10441 str2 = str2.Substring(0, str2.Length - 1);
10442
10443 len = str2.Length;
10444 int mod = len % 4;
10445
10446 if (mod == 1)
10447 str2 = str2.Substring(0, str2.Length - 1);
10448 else if (mod == 2)
10449 str2 += "==";
10450 else if (mod == 3)
10451 str2 += "=";
10452 }
10453
10454 byte[] data1;
10455 byte[] data2;
10456 try
10457 {
10458 data1 = Convert.FromBase64String(str1);
10459 data2 = Convert.FromBase64String(str2);
10460 }
10461 catch (Exception)
10462 {
10463 return new LSL_String(String.Empty);
10464 }
10465
10466 byte[] d2 = new Byte[data1.Length];
10467 int pos = 0;
10468
10469 if (data1.Length <= data2.Length)
9799 { 10470 {
9800 ret += (char) (src1[i] ^ src2[c]); 10471 Array.Copy(data2, 0, d2, 0, data1.Length);
10472 }
10473 else
10474 {
10475 while (pos < data1.Length)
10476 {
10477 len = data1.Length - pos;
10478 if (len > data2.Length)
10479 len = data2.Length;
9801 10480
9802 c++; 10481 Array.Copy(data2, 0, d2, pos, len);
9803 if (c >= src2.Length) 10482 pos += len;
9804 c = 0; 10483 }
9805 } 10484 }
9806 return llStringToBase64(ret); 10485
10486 for (pos = 0 ; pos < data1.Length ; pos++ )
10487 data1[pos] ^= d2[pos];
10488
10489 return Convert.ToBase64String(data1);
9807 } 10490 }
9808 10491
9809 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10492 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9860,12 +10543,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9860 Regex r = new Regex(authregex); 10543 Regex r = new Regex(authregex);
9861 int[] gnums = r.GetGroupNumbers(); 10544 int[] gnums = r.GetGroupNumbers();
9862 Match m = r.Match(url); 10545 Match m = r.Match(url);
9863 if (m.Success) { 10546 if (m.Success)
9864 for (int i = 1; i < gnums.Length; i++) { 10547 {
10548 for (int i = 1; i < gnums.Length; i++)
10549 {
9865 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10550 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9866 //CaptureCollection cc = g.Captures; 10551 //CaptureCollection cc = g.Captures;
9867 } 10552 }
9868 if (m.Groups.Count == 5) { 10553 if (m.Groups.Count == 5)
10554 {
9869 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10555 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9870 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10556 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9871 } 10557 }
@@ -10151,15 +10837,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10151 10837
10152 internal UUID ScriptByName(string name) 10838 internal UUID ScriptByName(string name)
10153 { 10839 {
10154 lock (m_host.TaskInventory) 10840 m_host.TaskInventory.LockItemsForRead(true);
10841
10842 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10155 { 10843 {
10156 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10844 if (item.Type == 10 && item.Name == name)
10157 { 10845 {
10158 if (item.Type == 10 && item.Name == name) 10846 m_host.TaskInventory.LockItemsForRead(false);
10159 return item.ItemID; 10847 return item.ItemID;
10160 } 10848 }
10161 } 10849 }
10162 10850
10851 m_host.TaskInventory.LockItemsForRead(false);
10852
10163 return UUID.Zero; 10853 return UUID.Zero;
10164 } 10854 }
10165 10855
@@ -10200,6 +10890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10200 { 10890 {
10201 m_host.AddScriptLPS(1); 10891 m_host.AddScriptLPS(1);
10202 10892
10893 //Clone is thread safe
10203 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10894 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10204 10895
10205 UUID assetID = UUID.Zero; 10896 UUID assetID = UUID.Zero;
@@ -10262,6 +10953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10262 { 10953 {
10263 m_host.AddScriptLPS(1); 10954 m_host.AddScriptLPS(1);
10264 10955
10956 //Clone is thread safe
10265 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10957 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10266 10958
10267 UUID assetID = UUID.Zero; 10959 UUID assetID = UUID.Zero;
@@ -10342,15 +11034,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10342 return GetLinkPrimitiveParams(obj, rules); 11034 return GetLinkPrimitiveParams(obj, rules);
10343 } 11035 }
10344 11036
10345 public void print(string str) 11037 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10346 { 11038 {
10347 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11039 List<SceneObjectPart> parts = GetLinkParts(link);
10348 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11040 if (parts.Count < 1)
10349 if (ossl != null) 11041 return 0;
10350 { 11042
10351 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11043 return GetNumberOfSides(parts[0]);
10352 m_log.Info("LSL print():" + str);
10353 }
10354 } 11044 }
10355 11045
10356 private string Name2Username(string name) 11046 private string Name2Username(string name)
@@ -10396,6 +11086,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10396 return rq.ToString(); 11086 return rq.ToString();
10397 } 11087 }
10398 11088
11089 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11090 {
11091 m_SayShoutCount = 0;
11092 }
10399 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11093 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10400 { 11094 {
10401 m_host.AddScriptLPS(1); 11095 m_host.AddScriptLPS(1);
@@ -10565,22 +11259,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10565 NotImplemented("llGetSPMaxMemory"); 11259 NotImplemented("llGetSPMaxMemory");
10566 } 11260 }
10567 11261
10568 public void llGetUsedMemory() 11262 public virtual LSL_Integer llGetUsedMemory()
10569 { 11263 {
10570 m_host.AddScriptLPS(1); 11264 m_host.AddScriptLPS(1);
10571 NotImplemented("llGetUsedMemory"); 11265 NotImplemented("llGetUsedMemory");
11266 return 0;
10572 } 11267 }
10573 11268
10574 public void llScriptProfiler(LSL_Integer flags) 11269 public void llScriptProfiler(LSL_Integer flags)
10575 { 11270 {
10576 m_host.AddScriptLPS(1); 11271 m_host.AddScriptLPS(1);
10577 NotImplemented("llScriptProfiler"); 11272 //NotImplemented("llScriptProfiler");
10578 } 11273 }
10579 11274
10580 public void llSetSoundQueueing(int queue) 11275 public void llSetSoundQueueing(int queue)
10581 { 11276 {
10582 m_host.AddScriptLPS(1); 11277 m_host.AddScriptLPS(1);
10583 NotImplemented("llSetSoundQueueing");
10584 } 11278 }
10585 11279
10586 public void llCollisionSprite(string impact_sprite) 11280 public void llCollisionSprite(string impact_sprite)
@@ -10592,7 +11286,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10592 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11286 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10593 { 11287 {
10594 m_host.AddScriptLPS(1); 11288 m_host.AddScriptLPS(1);
10595 NotImplemented("llGodLikeRezObject"); 11289
11290 if (!World.Permissions.IsGod(m_host.OwnerID))
11291 NotImplemented("llGodLikeRezObject");
11292
11293 AssetBase rezAsset = World.AssetService.Get(inventory);
11294 if (rezAsset == null)
11295 {
11296 llSay(0, "Asset not found");
11297 return;
11298 }
11299
11300 SceneObjectGroup group = null;
11301
11302 try
11303 {
11304 string xmlData = Utils.BytesToString(rezAsset.Data);
11305 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11306 }
11307 catch
11308 {
11309 llSay(0, "Asset not found");
11310 return;
11311 }
11312
11313 if (group == null)
11314 {
11315 llSay(0, "Asset not found");
11316 return;
11317 }
11318
11319 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11320 group.RootPart.AttachOffset = group.AbsolutePosition;
11321
11322 group.ResetIDs();
11323
11324 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11325 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11326 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11327 group.ScheduleGroupForFullUpdate();
11328
11329 // objects rezzed with this method are die_at_edge by default.
11330 group.RootPart.SetDieAtEdge(true);
11331
11332 group.ResumeScripts();
11333
11334 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11335 "object_rez", new Object[] {
11336 new LSL_String(
11337 group.RootPart.UUID.ToString()) },
11338 new DetectParams[0]));
10596 } 11339 }
10597 11340
10598 #endregion 11341 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 52d787d..ed2f221 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
136 internal float m_ScriptDelayFactor = 1.0f; 136 internal float m_ScriptDelayFactor = 1.0f;
137 internal float m_ScriptDistanceFactor = 1.0f; 137 internal float m_ScriptDistanceFactor = 1.0f;
138 internal bool m_debuggerSafe = false;
138 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 139 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
139 140
140 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -143,6 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 m_host = host; 144 m_host = host;
144 m_localID = localID; 145 m_localID = localID;
145 m_itemID = itemID; 146 m_itemID = itemID;
147 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 148
147 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
148 m_OSFunctionsEnabled = true; 150 m_OSFunctionsEnabled = true;
@@ -201,7 +203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 203
202 internal void OSSLError(string msg) 204 internal void OSSLError(string msg)
203 { 205 {
204 throw new Exception("OSSL Runtime Error: " + msg); 206 if (m_debuggerSafe)
207 {
208 OSSLShoutError(msg);
209 }
210 else
211 {
212 throw new Exception("OSSL Runtime Error: " + msg);
213 }
205 } 214 }
206 215
207 private void InitLSL() 216 private void InitLSL()
@@ -840,18 +849,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
840 if (target != null) 849 if (target != null)
841 { 850 {
842 UUID animID=UUID.Zero; 851 UUID animID=UUID.Zero;
843 lock (m_host.TaskInventory) 852 m_host.TaskInventory.LockItemsForRead(true);
853 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
844 { 854 {
845 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 855 if (inv.Value.Name == animation)
846 { 856 {
847 if (inv.Value.Name == animation) 857 if (inv.Value.Type == (int)AssetType.Animation)
848 { 858 animID = inv.Value.AssetID;
849 if (inv.Value.Type == (int)AssetType.Animation) 859 continue;
850 animID = inv.Value.AssetID;
851 continue;
852 }
853 } 860 }
854 } 861 }
862 m_host.TaskInventory.LockItemsForRead(false);
855 if (animID == UUID.Zero) 863 if (animID == UUID.Zero)
856 target.Animator.AddAnimation(animation, m_host.UUID); 864 target.Animator.AddAnimation(animation, m_host.UUID);
857 else 865 else
@@ -873,18 +881,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
873 if (target != null) 881 if (target != null)
874 { 882 {
875 UUID animID = UUID.Zero; 883 UUID animID = UUID.Zero;
876 lock (m_host.TaskInventory) 884 m_host.TaskInventory.LockItemsForRead(true);
885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
877 { 886 {
878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 887 if (inv.Value.Name == animation)
879 { 888 {
880 if (inv.Value.Name == animation) 889 if (inv.Value.Type == (int)AssetType.Animation)
881 { 890 animID = inv.Value.AssetID;
882 if (inv.Value.Type == (int)AssetType.Animation) 891 continue;
883 animID = inv.Value.AssetID;
884 continue;
885 }
886 } 892 }
887 } 893 }
894 m_host.TaskInventory.LockItemsForRead(false);
888 895
889 if (animID == UUID.Zero) 896 if (animID == UUID.Zero)
890 target.Animator.RemoveAnimation(animation); 897 target.Animator.RemoveAnimation(animation);
@@ -1841,6 +1848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 1848
1842 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1849 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1843 { 1850 {
1851 m_host.TaskInventory.LockItemsForRead(true);
1844 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1852 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1845 { 1853 {
1846 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1854 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1848,6 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 assetID = item.AssetID; 1856 assetID = item.AssetID;
1849 } 1857 }
1850 } 1858 }
1859 m_host.TaskInventory.LockItemsForRead(false);
1851 } 1860 }
1852 1861
1853 if (assetID == UUID.Zero) 1862 if (assetID == UUID.Zero)
@@ -2171,8 +2180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2171 UUID x = module.CreateNPC(firstname, 2180 UUID x = module.CreateNPC(firstname,
2172 lastname, 2181 lastname,
2173 new Vector3((float) position.x, (float) position.y, (float) position.z), 2182 new Vector3((float) position.x, (float) position.y, (float) position.z),
2174 World, 2183 World,appearance);
2175 appearance);
2176 2184
2177 return new LSL_Key(x.ToString()); 2185 return new LSL_Key(x.ToString());
2178 } 2186 }
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 4b008a4..3af9911 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 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 240e36f..3ebeb75 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"; }
@@ -442,47 +510,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
442 { 510 {
443 if (!m_Enabled) 511 if (!m_Enabled)
444 return; 512 return;
445 513 lockScriptsForRead(true);
446 lock (m_Scripts) 514 foreach (IScriptInstance instance in m_Scripts.Values)
447 { 515 {
448 m_log.InfoFormat( 516 // Force a final state save
449 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 517 //
450 518 if (m_Assemblies.ContainsKey(instance.AssetID))
451 foreach (IScriptInstance instance in m_Scripts.Values)
452 { 519 {
453 // Force a final state save 520 string assembly = m_Assemblies[instance.AssetID];
454 // 521 instance.SaveState(assembly);
455 if (m_Assemblies.ContainsKey(instance.AssetID)) 522 }
456 {
457 string assembly = m_Assemblies[instance.AssetID];
458 instance.SaveState(assembly);
459 }
460 523
461 // Clear the event queue and abort the instance thread 524 // Clear the event queue and abort the instance thread
462 // 525 //
463 instance.ClearQueue(); 526 instance.ClearQueue();
464 instance.Stop(0); 527 instance.Stop(0);
465 528
466 // Release events, timer, etc 529 // Release events, timer, etc
467 // 530 //
468 instance.DestroyScriptInstance(); 531 instance.DestroyScriptInstance();
469 532
470 // Unload scripts and app domains 533 // Unload scripts and app domains
471 // Must be done explicitly because they have infinite 534 // Must be done explicitly because they have infinite
472 // lifetime 535 // lifetime
473 // 536 //
474 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 537 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
475 if (m_DomainScripts[instance.AppDomain].Count == 0) 538 if (m_DomainScripts[instance.AppDomain].Count == 0)
476 { 539 {
477 m_DomainScripts.Remove(instance.AppDomain); 540 m_DomainScripts.Remove(instance.AppDomain);
478 UnloadAppDomain(instance.AppDomain); 541 UnloadAppDomain(instance.AppDomain);
479 }
480 } 542 }
481 m_Scripts.Clear();
482 m_PrimObjects.Clear();
483 m_Assemblies.Clear();
484 m_DomainScripts.Clear();
485 } 543 }
544 lockScriptsForRead(false);
545 lockScriptsForWrite(true);
546 m_Scripts.Clear();
547 lockScriptsForWrite(false);
548 m_PrimObjects.Clear();
549 m_Assemblies.Clear();
550 m_DomainScripts.Clear();
551
486 lock (m_ScriptEngines) 552 lock (m_ScriptEngines)
487 { 553 {
488 m_ScriptEngines.Remove(this); 554 m_ScriptEngines.Remove(this);
@@ -547,22 +613,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
547 613
548 List<IScriptInstance> instances = new List<IScriptInstance>(); 614 List<IScriptInstance> instances = new List<IScriptInstance>();
549 615
550 lock (m_Scripts) 616 lockScriptsForRead(true);
551 { 617 foreach (IScriptInstance instance in m_Scripts.Values)
552 foreach (IScriptInstance instance in m_Scripts.Values)
553 instances.Add(instance); 618 instances.Add(instance);
554 } 619 lockScriptsForRead(false);
555 620
556 foreach (IScriptInstance i in instances) 621 foreach (IScriptInstance i in instances)
557 { 622 {
558 string assembly = String.Empty; 623 string assembly = String.Empty;
559 624
560 lock (m_Scripts) 625
561 {
562 if (!m_Assemblies.ContainsKey(i.AssetID)) 626 if (!m_Assemblies.ContainsKey(i.AssetID))
563 continue; 627 continue;
564 assembly = m_Assemblies[i.AssetID]; 628 assembly = m_Assemblies[i.AssetID];
565 } 629
566 630
567 i.SaveState(assembly); 631 i.SaveState(assembly);
568 } 632 }
@@ -896,92 +960,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
896 } 960 }
897 961
898 ScriptInstance instance = null; 962 ScriptInstance instance = null;
899 lock (m_Scripts) 963 // Create the object record
964 lockScriptsForRead(true);
965 if ((!m_Scripts.ContainsKey(itemID)) ||
966 (m_Scripts[itemID].AssetID != assetID))
900 { 967 {
901 // Create the object record 968 lockScriptsForRead(false);
902 969
903 if ((!m_Scripts.ContainsKey(itemID)) || 970 UUID appDomain = assetID;
904 (m_Scripts[itemID].AssetID != assetID))
905 {
906 UUID appDomain = assetID;
907 971
908 if (part.ParentGroup.IsAttachment) 972 if (part.ParentGroup.IsAttachment)
909 appDomain = part.ParentGroup.RootPart.UUID; 973 appDomain = part.ParentGroup.RootPart.UUID;
910 974
911 if (!m_AppDomains.ContainsKey(appDomain)) 975 if (!m_AppDomains.ContainsKey(appDomain))
976 {
977 try
912 { 978 {
913 try 979 AppDomainSetup appSetup = new AppDomainSetup();
914 { 980 appSetup.PrivateBinPath = Path.Combine(
915 AppDomainSetup appSetup = new AppDomainSetup(); 981 m_ScriptEnginesPath,
916 appSetup.PrivateBinPath = Path.Combine( 982 m_Scene.RegionInfo.RegionID.ToString());
917 m_ScriptEnginesPath, 983
918 m_Scene.RegionInfo.RegionID.ToString()); 984 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
919 985 Evidence evidence = new Evidence(baseEvidence);
920 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 986
921 Evidence evidence = new Evidence(baseEvidence); 987 AppDomain sandbox;
922 988 if (m_AppDomainLoading)
923 AppDomain sandbox; 989 sandbox = AppDomain.CreateDomain(
924 if (m_AppDomainLoading) 990 m_Scene.RegionInfo.RegionID.ToString(),
925 sandbox = AppDomain.CreateDomain( 991 evidence, appSetup);
926 m_Scene.RegionInfo.RegionID.ToString(), 992 else
927 evidence, appSetup); 993 sandbox = AppDomain.CurrentDomain;
928 else 994
929 sandbox = AppDomain.CurrentDomain; 995 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
930 996 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
931 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 997 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
932 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 998 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
933 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 999 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
934 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 1000 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
935 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 1001 //sandbox.SetAppDomainPolicy(sandboxPolicy);
936 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 1002
937 //sandbox.SetAppDomainPolicy(sandboxPolicy); 1003 m_AppDomains[appDomain] = sandbox;
938 1004
939 m_AppDomains[appDomain] = sandbox; 1005 m_AppDomains[appDomain].AssemblyResolve +=
940 1006 new ResolveEventHandler(
941 m_AppDomains[appDomain].AssemblyResolve += 1007 AssemblyResolver.OnAssemblyResolve);
942 new ResolveEventHandler( 1008 m_DomainScripts[appDomain] = new List<UUID>();
943 AssemblyResolver.OnAssemblyResolve); 1009 }
944 m_DomainScripts[appDomain] = new List<UUID>(); 1010 catch (Exception e)
945 } 1011 {
946 catch (Exception e) 1012 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1013 m_ScriptErrorMessage += "Exception creating app domain:\n";
1014 m_ScriptFailCount++;
1015 lock (m_AddingAssemblies)
947 { 1016 {
948 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1017 m_AddingAssemblies[assembly]--;
949 m_ScriptErrorMessage += "Exception creating app domain:\n";
950 m_ScriptFailCount++;
951 lock (m_AddingAssemblies)
952 {
953 m_AddingAssemblies[assembly]--;
954 }
955 return false;
956 } 1018 }
1019 return false;
957 } 1020 }
958 m_DomainScripts[appDomain].Add(itemID); 1021 }
959 1022 m_DomainScripts[appDomain].Add(itemID);
960 instance = new ScriptInstance(this, part, 1023
961 itemID, assetID, assembly, 1024 instance = new ScriptInstance(this, part,
962 m_AppDomains[appDomain], 1025 itemID, assetID, assembly,
963 part.ParentGroup.RootPart.Name, 1026 m_AppDomains[appDomain],
964 item.Name, startParam, postOnRez, 1027 part.ParentGroup.RootPart.Name,
965 stateSource, m_MaxScriptQueue); 1028 item.Name, startParam, postOnRez,
966 1029 stateSource, m_MaxScriptQueue);
967 m_log.DebugFormat( 1030
968 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1031 m_log.DebugFormat(
969 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1032 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1033 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
970 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1034 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
971 1035
972 if (presence != null) 1036 if (presence != null)
973 { 1037 {
974 ShowScriptSaveResponse(item.OwnerID, 1038 ShowScriptSaveResponse(item.OwnerID,
975 assetID, "Compile successful", true); 1039 assetID, "Compile successful", true);
976 }
977
978 instance.AppDomain = appDomain;
979 instance.LineMap = linemap;
980
981 m_Scripts[itemID] = instance;
982 } 1040 }
983 }
984 1041
1042 instance.AppDomain = appDomain;
1043 instance.LineMap = linemap;
1044 lockScriptsForWrite(true);
1045 m_Scripts[itemID] = instance;
1046 lockScriptsForWrite(false);
1047 }
1048 else
1049 {
1050 lockScriptsForRead(false);
1051 }
985 lock (m_PrimObjects) 1052 lock (m_PrimObjects)
986 { 1053 {
987 if (!m_PrimObjects.ContainsKey(localID)) 1054 if (!m_PrimObjects.ContainsKey(localID))
@@ -1000,9 +1067,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1000 m_AddingAssemblies[assembly]--; 1067 m_AddingAssemblies[assembly]--;
1001 } 1068 }
1002 1069
1003 if (instance != null) 1070 if (instance!=null)
1004 instance.Init(); 1071 instance.Init();
1005 1072
1006 return true; 1073 return true;
1007 } 1074 }
1008 1075
@@ -1015,20 +1082,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1015 m_CompileDict.Remove(itemID); 1082 m_CompileDict.Remove(itemID);
1016 } 1083 }
1017 1084
1018 IScriptInstance instance = null; 1085 lockScriptsForRead(true);
1019 1086 // Do we even have it?
1020 lock (m_Scripts) 1087 if (!m_Scripts.ContainsKey(itemID))
1021 { 1088 {
1022 // Do we even have it? 1089 // Do we even have it?
1023 if (!m_Scripts.ContainsKey(itemID)) 1090 if (!m_Scripts.ContainsKey(itemID))
1024 return; 1091 return;
1025 1092
1026 instance = m_Scripts[itemID]; 1093 lockScriptsForRead(false);
1094 lockScriptsForWrite(true);
1027 m_Scripts.Remove(itemID); 1095 m_Scripts.Remove(itemID);
1096 lockScriptsForWrite(false);
1097
1098 return;
1028 } 1099 }
1100
1029 1101
1102 IScriptInstance instance=m_Scripts[itemID];
1103 lockScriptsForRead(false);
1104 lockScriptsForWrite(true);
1105 m_Scripts.Remove(itemID);
1106 lockScriptsForWrite(false);
1030 instance.ClearQueue(); 1107 instance.ClearQueue();
1031 instance.Stop(0); 1108 instance.Stop(0);
1109
1032// bool objectRemoved = false; 1110// bool objectRemoved = false;
1033 1111
1034 lock (m_PrimObjects) 1112 lock (m_PrimObjects)
@@ -1064,11 +1142,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1064 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1142 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1065 if (handlerObjectRemoved != null) 1143 if (handlerObjectRemoved != null)
1066 { 1144 {
1067 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1145 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1068 handlerObjectRemoved(part.UUID); 1146 handlerObjectRemoved(part.UUID);
1069 } 1147 }
1070 1148
1071 1149 CleanAssemblies();
1150
1072 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1151 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1073 if (handlerScriptRemoved != null) 1152 if (handlerScriptRemoved != null)
1074 handlerScriptRemoved(itemID); 1153 handlerScriptRemoved(itemID);
@@ -1210,7 +1289,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1210 return false; 1289 return false;
1211 1290
1212 uuids = m_PrimObjects[localID]; 1291 uuids = m_PrimObjects[localID];
1213 } 1292
1214 1293
1215 foreach (UUID itemID in uuids) 1294 foreach (UUID itemID in uuids)
1216 { 1295 {
@@ -1228,6 +1307,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1228 result = true; 1307 result = true;
1229 } 1308 }
1230 } 1309 }
1310 }
1231 1311
1232 return result; 1312 return result;
1233 } 1313 }
@@ -1327,12 +1407,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1327 private IScriptInstance GetInstance(UUID itemID) 1407 private IScriptInstance GetInstance(UUID itemID)
1328 { 1408 {
1329 IScriptInstance instance; 1409 IScriptInstance instance;
1330 lock (m_Scripts) 1410 lockScriptsForRead(true);
1411 if (!m_Scripts.ContainsKey(itemID))
1331 { 1412 {
1332 if (!m_Scripts.ContainsKey(itemID)) 1413 lockScriptsForRead(false);
1333 return null; 1414 return null;
1334 instance = m_Scripts[itemID];
1335 } 1415 }
1416 instance = m_Scripts[itemID];
1417 lockScriptsForRead(false);
1336 return instance; 1418 return instance;
1337 } 1419 }
1338 1420
@@ -1356,6 +1438,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1356 return false; 1438 return false;
1357 } 1439 }
1358 1440
1441 [DebuggerNonUserCode]
1359 public void ApiResetScript(UUID itemID) 1442 public void ApiResetScript(UUID itemID)
1360 { 1443 {
1361 IScriptInstance instance = GetInstance(itemID); 1444 IScriptInstance instance = GetInstance(itemID);
@@ -1407,6 +1490,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1407 return UUID.Zero; 1490 return UUID.Zero;
1408 } 1491 }
1409 1492
1493 [DebuggerNonUserCode]
1410 public void SetState(UUID itemID, string newState) 1494 public void SetState(UUID itemID, string newState)
1411 { 1495 {
1412 IScriptInstance instance = GetInstance(itemID); 1496 IScriptInstance instance = GetInstance(itemID);
@@ -1427,11 +1511,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1427 { 1511 {
1428 List<IScriptInstance> instances = new List<IScriptInstance>(); 1512 List<IScriptInstance> instances = new List<IScriptInstance>();
1429 1513
1430 lock (m_Scripts) 1514 lockScriptsForRead(true);
1431 { 1515 foreach (IScriptInstance instance in m_Scripts.Values)
1432 foreach (IScriptInstance instance in m_Scripts.Values)
1433 instances.Add(instance); 1516 instances.Add(instance);
1434 } 1517 lockScriptsForRead(false);
1435 1518
1436 foreach (IScriptInstance i in instances) 1519 foreach (IScriptInstance i in instances)
1437 { 1520 {
@@ -1808,5 +1891,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1808 if (instance != null) 1891 if (instance != null)
1809 instance.Resume(); 1892 instance.Resume();
1810 } 1893 }
1894
1895 public bool HasScript(UUID itemID, out bool running)
1896 {
1897 running = true;
1898
1899 IScriptInstance instance = GetInstance(itemID);
1900 if (instance == null)
1901 return false;
1902
1903 running = instance.Running;
1904 return true;
1905 }
1811 } 1906 }
1812} \ No newline at end of file 1907} \ No newline at end of file