aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2252
-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.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
19 files changed, 2112 insertions, 969 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 9a26f4b..9feed38 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 {
@@ -1943,10 +2147,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1943 return end; 2147 return end;
1944 } 2148 }
1945 2149
1946 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2150 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1947 { 2151 {
2152 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2153 return fromPos;
2154
1948 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2155 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1949 LSL_Vector currentPos = GetPartLocalPos(part); 2156
1950 2157
1951 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2158 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1952 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2159 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1955,14 +2162,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1955 { 2162 {
1956 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2163 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1957 targetPos.z = ground; 2164 targetPos.z = ground;
2165 }
2166 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2167
2168 return real_vec;
2169 }
2170
2171 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2172 {
2173 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2174 return;
2175
2176 LSL_Vector currentPos = GetPartLocalPos(part);
2177 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2178
2179 if (part.ParentGroup.RootPart == part)
2180 {
1958 SceneObjectGroup parent = part.ParentGroup; 2181 SceneObjectGroup parent = part.ParentGroup;
1959 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2182 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1960 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1961 } 2183 }
1962 else 2184 else
1963 { 2185 {
1964 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2186 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1965 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1966 SceneObjectGroup parent = part.ParentGroup; 2187 SceneObjectGroup parent = part.ParentGroup;
1967 parent.HasGroupChanged = true; 2188 parent.HasGroupChanged = true;
1968 parent.ScheduleGroupForTerseUpdate(); 2189 parent.ScheduleGroupForTerseUpdate();
@@ -2013,9 +2234,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2013 m_host.AddScriptLPS(1); 2234 m_host.AddScriptLPS(1);
2014 2235
2015 // try to let this work as in SL... 2236 // try to let this work as in SL...
2016 if (m_host.ParentID == 0) 2237 if (m_host.LinkNum < 2)
2017 { 2238 {
2018 // special case: If we are root, rotate complete SOG to new rotation 2239 // Special case: If we are root, rotate complete SOG to new
2240 // rotation.
2241 // We are root if the link number is 0 (single prim) or 1
2242 // (root prim). ParentID may be nonzero in attachments and
2243 // using it would cause attachments and HUDs to rotate
2244 // to the wrong positions.
2019 SetRot(m_host, Rot2Quaternion(rot)); 2245 SetRot(m_host, Rot2Quaternion(rot));
2020 } 2246 }
2021 else 2247 else
@@ -2040,6 +2266,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2040 2266
2041 protected void SetRot(SceneObjectPart part, Quaternion rot) 2267 protected void SetRot(SceneObjectPart part, Quaternion rot)
2042 { 2268 {
2269 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2270 return;
2271
2043 part.UpdateRotation(rot); 2272 part.UpdateRotation(rot);
2044 // Update rotation does not move the object in the physics scene if it's a linkset. 2273 // Update rotation does not move the object in the physics scene if it's a linkset.
2045 2274
@@ -2665,12 +2894,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2665 2894
2666 m_host.AddScriptLPS(1); 2895 m_host.AddScriptLPS(1);
2667 2896
2897 m_host.TaskInventory.LockItemsForRead(true);
2668 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2898 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2669 2899 m_host.TaskInventory.LockItemsForRead(false);
2670 lock (m_host.TaskInventory)
2671 {
2672 item = m_host.TaskInventory[invItemID];
2673 }
2674 2900
2675 if (item.PermsGranter == UUID.Zero) 2901 if (item.PermsGranter == UUID.Zero)
2676 return 0; 2902 return 0;
@@ -2745,6 +2971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2745 if (dist > m_ScriptDistanceFactor * 10.0f) 2971 if (dist > m_ScriptDistanceFactor * 10.0f)
2746 return; 2972 return;
2747 2973
2974 //Clone is thread-safe
2748 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2975 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2749 2976
2750 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2977 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2805,6 +3032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2805 3032
2806 public void llLookAt(LSL_Vector target, double strength, double damping) 3033 public void llLookAt(LSL_Vector target, double strength, double damping)
2807 { 3034 {
3035 /*
2808 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
2809 // Determine where we are looking from 3037 // Determine where we are looking from
2810 LSL_Vector from = llGetPos(); 3038 LSL_Vector from = llGetPos();
@@ -2824,10 +3052,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 // the angles of rotation in radians into rotation value 3052 // the angles of rotation in radians into rotation value
2825 3053
2826 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3054 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2827 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3055
2828 m_host.startLookAt(rotation, (float)damping, (float)strength); 3056 // This would only work if your physics system contains an APID controller:
3057 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3058 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3059
2829 // Orient the object to the angle calculated 3060 // Orient the object to the angle calculated
2830 //llSetRot(rot); 3061 llSetRot(rot);
3062 */
3063
3064 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3065 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3066 // http://bugs.meta7.com/view.php?id=28
3067 // - Tom
3068
3069 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3070 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3071 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3072 */
3073 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3074 {
3075 // Part is non-phys, convert this to a llSetRot()
3076 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3077 Vector3 dir = tgt - m_host.GroupPosition;
3078 dir.Normalize();
3079 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3080 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3081 float terot = (float)Math.Atan2(-dir.Z, txy);
3082 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3083 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3084 LSL_Types.Quaternion spin = llEuler2Rot(az);
3085 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3086 llSetRot(rot);
3087 }
3088 else
3089 {
3090 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3091 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3092 m_host.RotLookAt(q, (float)strength, (float)damping);
3093 }
3094
3095 }
3096
3097 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3098 {
3099 m_host.AddScriptLPS(1);
3100// NotImplemented("llRotLookAt");
3101 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3102
2831 } 3103 }
2832 3104
2833 public void llStopLookAt() 3105 public void llStopLookAt()
@@ -2876,13 +3148,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2876 { 3148 {
2877 TaskInventoryItem item; 3149 TaskInventoryItem item;
2878 3150
2879 lock (m_host.TaskInventory) 3151 m_host.TaskInventory.LockItemsForRead(true);
3152 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2880 { 3153 {
2881 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3154 m_host.TaskInventory.LockItemsForRead(false);
2882 return; 3155 return;
2883 else 3156 }
2884 item = m_host.TaskInventory[InventorySelf()]; 3157 else
3158 {
3159 item = m_host.TaskInventory[InventorySelf()];
2885 } 3160 }
3161 m_host.TaskInventory.LockItemsForRead(false);
2886 3162
2887 if (item.PermsGranter != UUID.Zero) 3163 if (item.PermsGranter != UUID.Zero)
2888 { 3164 {
@@ -2904,13 +3180,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2904 { 3180 {
2905 TaskInventoryItem item; 3181 TaskInventoryItem item;
2906 3182
3183 m_host.TaskInventory.LockItemsForRead(true);
2907 lock (m_host.TaskInventory) 3184 lock (m_host.TaskInventory)
2908 { 3185 {
3186
2909 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3187 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3188 {
3189 m_host.TaskInventory.LockItemsForRead(false);
2910 return; 3190 return;
3191 }
2911 else 3192 else
3193 {
2912 item = m_host.TaskInventory[InventorySelf()]; 3194 item = m_host.TaskInventory[InventorySelf()];
3195 }
2913 } 3196 }
3197 m_host.TaskInventory.LockItemsForRead(false);
2914 3198
2915 m_host.AddScriptLPS(1); 3199 m_host.AddScriptLPS(1);
2916 3200
@@ -2942,19 +3226,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2942 { 3226 {
2943 m_host.AddScriptLPS(1); 3227 m_host.AddScriptLPS(1);
2944 3228
2945// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2946// return;
2947
2948 TaskInventoryItem item; 3229 TaskInventoryItem item;
2949 3230
2950 lock (m_host.TaskInventory) 3231 m_host.TaskInventory.LockItemsForRead(true);
3232
3233 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2951 { 3234 {
2952 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3235 m_host.TaskInventory.LockItemsForRead(false);
2953 return; 3236 return;
2954 else 3237 }
2955 item = m_host.TaskInventory[InventorySelf()]; 3238 else
3239 {
3240 item = m_host.TaskInventory[InventorySelf()];
2956 } 3241 }
2957 3242
3243 m_host.TaskInventory.LockItemsForRead(false);
3244
2958 if (item.PermsGranter != m_host.OwnerID) 3245 if (item.PermsGranter != m_host.OwnerID)
2959 return; 3246 return;
2960 3247
@@ -2963,11 +3250,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2963 SceneObjectGroup grp = m_host.ParentGroup; 3250 SceneObjectGroup grp = m_host.ParentGroup;
2964 3251
2965 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3252 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2966 3253 if (presence.Scene.AttachmentsModule != null)
2967 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3254 {
2968 if (attachmentsModule != null) 3255 presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false);
2969 attachmentsModule.AttachObject(presence.ControllingClient, 3256 }
2970 grp, (uint)attachment, false);
2971 } 3257 }
2972 } 3258 }
2973 3259
@@ -2980,13 +3266,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 3266
2981 TaskInventoryItem item; 3267 TaskInventoryItem item;
2982 3268
2983 lock (m_host.TaskInventory) 3269 m_host.TaskInventory.LockItemsForRead(true);
3270
3271 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2984 { 3272 {
2985 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3273 m_host.TaskInventory.LockItemsForRead(false);
2986 return; 3274 return;
2987 else 3275 }
2988 item = m_host.TaskInventory[InventorySelf()]; 3276 else
3277 {
3278 item = m_host.TaskInventory[InventorySelf()];
2989 } 3279 }
3280 m_host.TaskInventory.LockItemsForRead(false);
3281
2990 3282
2991 if (item.PermsGranter != m_host.OwnerID) 3283 if (item.PermsGranter != m_host.OwnerID)
2992 return; 3284 return;
@@ -3033,6 +3325,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3033 3325
3034 public void llInstantMessage(string user, string message) 3326 public void llInstantMessage(string user, string message)
3035 { 3327 {
3328 UUID result;
3329 if (!UUID.TryParse(user, out result))
3330 {
3331 ShoutError("An invalid key was passed to llInstantMessage");
3332 ScriptSleep(2000);
3333 return;
3334 }
3335
3336
3036 m_host.AddScriptLPS(1); 3337 m_host.AddScriptLPS(1);
3037 3338
3038 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3339 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3047,14 +3348,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 UUID friendTransactionID = UUID.Random(); 3348 UUID friendTransactionID = UUID.Random();
3048 3349
3049 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3350 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3050 3351
3051 GridInstantMessage msg = new GridInstantMessage(); 3352 GridInstantMessage msg = new GridInstantMessage();
3052 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3353 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3053 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3354 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3054 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3355 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3055// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3356// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3056// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3357// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3057 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3358// DateTime dt = DateTime.UtcNow;
3359//
3360// // Ticks from UtcNow, but make it look like local. Evil, huh?
3361// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3362//
3363// try
3364// {
3365// // Convert that to the PST timezone
3366// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3367// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3368// }
3369// catch
3370// {
3371// // No logging here, as it could be VERY spammy
3372// }
3373//
3374// // And make it look local again to fool the unix time util
3375// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3376
3377 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3378
3058 //if (client != null) 3379 //if (client != null)
3059 //{ 3380 //{
3060 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3381 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3068,12 +3389,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3068 msg.message = message.Substring(0, 1024); 3389 msg.message = message.Substring(0, 1024);
3069 else 3390 else
3070 msg.message = message; 3391 msg.message = message;
3071 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3392 msg.dialog = (byte)19; // MessageFromObject
3072 msg.fromGroup = false;// fromGroup; 3393 msg.fromGroup = false;// fromGroup;
3073 msg.offline = (byte)0; //offline; 3394 msg.offline = (byte)0; //offline;
3074 msg.ParentEstateID = 0; //ParentEstateID; 3395 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3075 msg.Position = new Vector3(m_host.AbsolutePosition); 3396 msg.Position = new Vector3(m_host.AbsolutePosition);
3076 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3397 msg.RegionID = World.RegionInfo.RegionID.Guid;
3077 msg.binaryBucket 3398 msg.binaryBucket
3078 = Util.StringToBytes256( 3399 = Util.StringToBytes256(
3079 "{0}/{1}/{2}/{3}", 3400 "{0}/{1}/{2}/{3}",
@@ -3101,7 +3422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 } 3422 }
3102 3423
3103 emailModule.SendEmail(m_host.UUID, address, subject, message); 3424 emailModule.SendEmail(m_host.UUID, address, subject, message);
3104 ScriptSleep(20000); 3425 ScriptSleep(15000);
3105 } 3426 }
3106 3427
3107 public void llGetNextEmail(string address, string subject) 3428 public void llGetNextEmail(string address, string subject)
@@ -3201,13 +3522,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3201 m_host.AddScriptLPS(1); 3522 m_host.AddScriptLPS(1);
3202 } 3523 }
3203 3524
3204 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3205 {
3206 m_host.AddScriptLPS(1);
3207 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3208 m_host.RotLookAt(rot, (float)strength, (float)damping);
3209 }
3210
3211 public LSL_Integer llStringLength(string str) 3525 public LSL_Integer llStringLength(string str)
3212 { 3526 {
3213 m_host.AddScriptLPS(1); 3527 m_host.AddScriptLPS(1);
@@ -3231,14 +3545,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3231 3545
3232 TaskInventoryItem item; 3546 TaskInventoryItem item;
3233 3547
3234 lock (m_host.TaskInventory) 3548 m_host.TaskInventory.LockItemsForRead(true);
3549 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3235 { 3550 {
3236 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3551 m_host.TaskInventory.LockItemsForRead(false);
3237 return; 3552 return;
3238 else
3239 item = m_host.TaskInventory[InventorySelf()];
3240 } 3553 }
3241 3554 else
3555 {
3556 item = m_host.TaskInventory[InventorySelf()];
3557 }
3558 m_host.TaskInventory.LockItemsForRead(false);
3242 if (item.PermsGranter == UUID.Zero) 3559 if (item.PermsGranter == UUID.Zero)
3243 return; 3560 return;
3244 3561
@@ -3268,13 +3585,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 3585
3269 TaskInventoryItem item; 3586 TaskInventoryItem item;
3270 3587
3271 lock (m_host.TaskInventory) 3588 m_host.TaskInventory.LockItemsForRead(true);
3589 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3272 { 3590 {
3273 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3591 m_host.TaskInventory.LockItemsForRead(false);
3274 return; 3592 return;
3275 else 3593 }
3276 item = m_host.TaskInventory[InventorySelf()]; 3594 else
3595 {
3596 item = m_host.TaskInventory[InventorySelf()];
3277 } 3597 }
3598 m_host.TaskInventory.LockItemsForRead(false);
3599
3278 3600
3279 if (item.PermsGranter == UUID.Zero) 3601 if (item.PermsGranter == UUID.Zero)
3280 return; 3602 return;
@@ -3339,10 +3661,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3339 3661
3340 TaskInventoryItem item; 3662 TaskInventoryItem item;
3341 3663
3342 lock (m_host.TaskInventory) 3664
3665 m_host.TaskInventory.LockItemsForRead(true);
3666 if (!m_host.TaskInventory.ContainsKey(invItemID))
3667 {
3668 m_host.TaskInventory.LockItemsForRead(false);
3669 return;
3670 }
3671 else
3343 { 3672 {
3344 item = m_host.TaskInventory[invItemID]; 3673 item = m_host.TaskInventory[invItemID];
3345 } 3674 }
3675 m_host.TaskInventory.LockItemsForRead(false);
3346 3676
3347 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3677 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3348 { 3678 {
@@ -3370,15 +3700,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3370 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3700 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3371 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3701 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3372 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3702 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3703 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3373 ScriptBaseClass.PERMISSION_ATTACH; 3704 ScriptBaseClass.PERMISSION_ATTACH;
3374 3705
3375 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3706 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3376 { 3707 {
3377 lock (m_host.TaskInventory) 3708 m_host.TaskInventory.LockItemsForWrite(true);
3378 { 3709 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3379 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3710 m_host.TaskInventory[invItemID].PermsMask = perm;
3380 m_host.TaskInventory[invItemID].PermsMask = perm; 3711 m_host.TaskInventory.LockItemsForWrite(false);
3381 }
3382 3712
3383 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3713 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3384 "run_time_permissions", new Object[] { 3714 "run_time_permissions", new Object[] {
@@ -3388,28 +3718,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3388 return; 3718 return;
3389 } 3719 }
3390 } 3720 }
3391 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3721 else
3392 { 3722 {
3393 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3723 bool sitting = false;
3394 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3724 if (m_host.SitTargetAvatar == agentID)
3395 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3725 {
3396 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3726 sitting = true;
3397 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3727 }
3728 else
3729 {
3730 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3731 {
3732 if (p.SitTargetAvatar == agentID)
3733 sitting = true;
3734 }
3735 }
3398 3736
3399 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3737 if (sitting)
3400 { 3738 {
3401 lock (m_host.TaskInventory) 3739 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3740 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3741 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3742 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3743 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3744
3745 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3402 { 3746 {
3747 m_host.TaskInventory.LockItemsForWrite(true);
3403 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3748 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3404 m_host.TaskInventory[invItemID].PermsMask = perm; 3749 m_host.TaskInventory[invItemID].PermsMask = perm;
3405 } 3750 m_host.TaskInventory.LockItemsForWrite(false);
3406 3751
3407 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3752 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3408 "run_time_permissions", new Object[] { 3753 "run_time_permissions", new Object[] {
3409 new LSL_Integer(perm) }, 3754 new LSL_Integer(perm) },
3410 new DetectParams[0])); 3755 new DetectParams[0]));
3411 3756
3412 return; 3757 return;
3758 }
3413 } 3759 }
3414 } 3760 }
3415 3761
@@ -3423,11 +3769,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3423 3769
3424 if (!m_waitingForScriptAnswer) 3770 if (!m_waitingForScriptAnswer)
3425 { 3771 {
3426 lock (m_host.TaskInventory) 3772 m_host.TaskInventory.LockItemsForWrite(true);
3427 { 3773 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3428 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3774 m_host.TaskInventory[invItemID].PermsMask = 0;
3429 m_host.TaskInventory[invItemID].PermsMask = 0; 3775 m_host.TaskInventory.LockItemsForWrite(false);
3430 }
3431 3776
3432 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3777 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3433 m_waitingForScriptAnswer=true; 3778 m_waitingForScriptAnswer=true;
@@ -3462,10 +3807,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3807 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3463 llReleaseControls(); 3808 llReleaseControls();
3464 3809
3465 lock (m_host.TaskInventory) 3810
3466 { 3811 m_host.TaskInventory.LockItemsForWrite(true);
3467 m_host.TaskInventory[invItemID].PermsMask = answer; 3812 m_host.TaskInventory[invItemID].PermsMask = answer;
3468 } 3813 m_host.TaskInventory.LockItemsForWrite(false);
3814
3469 3815
3470 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3816 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3471 "run_time_permissions", new Object[] { 3817 "run_time_permissions", new Object[] {
@@ -3477,16 +3823,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3477 { 3823 {
3478 m_host.AddScriptLPS(1); 3824 m_host.AddScriptLPS(1);
3479 3825
3480 lock (m_host.TaskInventory) 3826 m_host.TaskInventory.LockItemsForRead(true);
3827
3828 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3481 { 3829 {
3482 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3830 if (item.Type == 10 && item.ItemID == m_itemID)
3483 { 3831 {
3484 if (item.Type == 10 && item.ItemID == m_itemID) 3832 m_host.TaskInventory.LockItemsForRead(false);
3485 { 3833 return item.PermsGranter.ToString();
3486 return item.PermsGranter.ToString();
3487 }
3488 } 3834 }
3489 } 3835 }
3836 m_host.TaskInventory.LockItemsForRead(false);
3490 3837
3491 return UUID.Zero.ToString(); 3838 return UUID.Zero.ToString();
3492 } 3839 }
@@ -3495,19 +3842,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3495 { 3842 {
3496 m_host.AddScriptLPS(1); 3843 m_host.AddScriptLPS(1);
3497 3844
3498 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3846
3847 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3499 { 3848 {
3500 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3849 if (item.Type == 10 && item.ItemID == m_itemID)
3501 { 3850 {
3502 if (item.Type == 10 && item.ItemID == m_itemID) 3851 int perms = item.PermsMask;
3503 { 3852 if (m_automaticLinkPermission)
3504 int perms = item.PermsMask; 3853 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3505 if (m_automaticLinkPermission) 3854 m_host.TaskInventory.LockItemsForRead(false);
3506 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3855 return perms;
3507 return perms;
3508 }
3509 } 3856 }
3510 } 3857 }
3858 m_host.TaskInventory.LockItemsForRead(false);
3511 3859
3512 return 0; 3860 return 0;
3513 } 3861 }
@@ -3529,9 +3877,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3529 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3877 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3530 { 3878 {
3531 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3879 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3532 3880 if (parts.Count > 0)
3533 foreach (SceneObjectPart part in parts) 3881 {
3534 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3882 try
3883 {
3884 parts[0].ParentGroup.areUpdatesSuspended = true;
3885 foreach (SceneObjectPart part in parts)
3886 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3887 }
3888 finally
3889 {
3890 parts[0].ParentGroup.areUpdatesSuspended = false;
3891 }
3892 }
3535 } 3893 }
3536 3894
3537 public void llCreateLink(string target, int parent) 3895 public void llCreateLink(string target, int parent)
@@ -3544,11 +3902,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3544 return; 3902 return;
3545 3903
3546 TaskInventoryItem item; 3904 TaskInventoryItem item;
3547 lock (m_host.TaskInventory) 3905 m_host.TaskInventory.LockItemsForRead(true);
3548 { 3906 item = m_host.TaskInventory[invItemID];
3549 item = m_host.TaskInventory[invItemID]; 3907 m_host.TaskInventory.LockItemsForRead(false);
3550 } 3908
3551
3552 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3909 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3553 && !m_automaticLinkPermission) 3910 && !m_automaticLinkPermission)
3554 { 3911 {
@@ -3565,11 +3922,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3565 3922
3566 if (targetPart.ParentGroup.AttachmentPoint != 0) 3923 if (targetPart.ParentGroup.AttachmentPoint != 0)
3567 return; // Fail silently if attached 3924 return; // Fail silently if attached
3925
3926 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3927 return;
3928
3568 SceneObjectGroup parentPrim = null, childPrim = null; 3929 SceneObjectGroup parentPrim = null, childPrim = null;
3569 3930
3570 if (targetPart != null) 3931 if (targetPart != null)
3571 { 3932 {
3572 if (parent != 0) { 3933 if (parent != 0)
3934 {
3573 parentPrim = m_host.ParentGroup; 3935 parentPrim = m_host.ParentGroup;
3574 childPrim = targetPart.ParentGroup; 3936 childPrim = targetPart.ParentGroup;
3575 } 3937 }
@@ -3601,16 +3963,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3601 m_host.AddScriptLPS(1); 3963 m_host.AddScriptLPS(1);
3602 UUID invItemID = InventorySelf(); 3964 UUID invItemID = InventorySelf();
3603 3965
3604 lock (m_host.TaskInventory) 3966 m_host.TaskInventory.LockItemsForRead(true);
3605 {
3606 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3967 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3607 && !m_automaticLinkPermission) 3968 && !m_automaticLinkPermission)
3608 { 3969 {
3609 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3970 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3971 m_host.TaskInventory.LockItemsForRead(false);
3610 return; 3972 return;
3611 } 3973 }
3612 } 3974 m_host.TaskInventory.LockItemsForRead(false);
3613 3975
3614 if (linknum < ScriptBaseClass.LINK_THIS) 3976 if (linknum < ScriptBaseClass.LINK_THIS)
3615 return; 3977 return;
3616 3978
@@ -3649,10 +4011,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3649 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3650 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3651 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3652 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3653 { 4015 {
3654 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 parts[0].ParentGroup.areUpdatesSuspended = true;
4019 foreach (SceneObjectPart part in parts)
4020 {
4021 parentPrim.DelinkFromGroup(part.LocalId, true);
4022 }
4023 }
4024 finally
4025 {
4026 parts[0].ParentGroup.areUpdatesSuspended = false;
4027 }
3655 } 4028 }
4029
3656 parentPrim.HasGroupChanged = true; 4030 parentPrim.HasGroupChanged = true;
3657 parentPrim.ScheduleGroupForFullUpdate(); 4031 parentPrim.ScheduleGroupForFullUpdate();
3658 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4032 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3661,11 +4035,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 { 4035 {
3662 SceneObjectPart newRoot = parts[0]; 4036 SceneObjectPart newRoot = parts[0];
3663 parts.Remove(newRoot); 4037 parts.Remove(newRoot);
3664 foreach (SceneObjectPart part in parts) 4038
4039 try
3665 { 4040 {
3666 part.UpdateFlag = 0; 4041 parts[0].ParentGroup.areUpdatesSuspended = true;
3667 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4042 foreach (SceneObjectPart part in parts)
4043 {
4044 part.UpdateFlag = 0;
4045 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4046 }
3668 } 4047 }
4048 finally
4049 {
4050 parts[0].ParentGroup.areUpdatesSuspended = false;
4051 }
4052
4053
3669 newRoot.ParentGroup.HasGroupChanged = true; 4054 newRoot.ParentGroup.HasGroupChanged = true;
3670 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4055 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3671 } 4056 }
@@ -3685,6 +4070,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 public void llBreakAllLinks() 4070 public void llBreakAllLinks()
3686 { 4071 {
3687 m_host.AddScriptLPS(1); 4072 m_host.AddScriptLPS(1);
4073
4074 UUID invItemID = InventorySelf();
4075
4076 TaskInventoryItem item;
4077 m_host.TaskInventory.LockItemsForRead(true);
4078 item = m_host.TaskInventory[invItemID];
4079 m_host.TaskInventory.LockItemsForRead(false);
4080
4081 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4082 && !m_automaticLinkPermission)
4083 {
4084 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4085 return;
4086 }
4087
3688 SceneObjectGroup parentPrim = m_host.ParentGroup; 4088 SceneObjectGroup parentPrim = m_host.ParentGroup;
3689 if (parentPrim.AttachmentPoint != 0) 4089 if (parentPrim.AttachmentPoint != 0)
3690 return; // Fail silently if attached 4090 return; // Fail silently if attached
@@ -3730,6 +4130,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3730 } 4130 }
3731 else 4131 else
3732 { 4132 {
4133 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4134 {
4135 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4136
4137 if (linknum < 0)
4138 return UUID.Zero.ToString();
4139
4140 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4141 if (avatars.Count > linknum)
4142 {
4143 return avatars[linknum].UUID.ToString();
4144 }
4145 }
3733 return UUID.Zero.ToString(); 4146 return UUID.Zero.ToString();
3734 } 4147 }
3735 } 4148 }
@@ -3828,17 +4241,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3828 m_host.AddScriptLPS(1); 4241 m_host.AddScriptLPS(1);
3829 int count = 0; 4242 int count = 0;
3830 4243
3831 lock (m_host.TaskInventory) 4244 m_host.TaskInventory.LockItemsForRead(true);
4245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3832 { 4246 {
3833 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4247 if (inv.Value.Type == type || type == -1)
3834 { 4248 {
3835 if (inv.Value.Type == type || type == -1) 4249 count = count + 1;
3836 {
3837 count = count + 1;
3838 }
3839 } 4250 }
3840 } 4251 }
3841 4252
4253 m_host.TaskInventory.LockItemsForRead(false);
3842 return count; 4254 return count;
3843 } 4255 }
3844 4256
@@ -3847,16 +4259,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3847 m_host.AddScriptLPS(1); 4259 m_host.AddScriptLPS(1);
3848 ArrayList keys = new ArrayList(); 4260 ArrayList keys = new ArrayList();
3849 4261
3850 lock (m_host.TaskInventory) 4262 m_host.TaskInventory.LockItemsForRead(true);
4263 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3851 { 4264 {
3852 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4265 if (inv.Value.Type == type || type == -1)
3853 { 4266 {
3854 if (inv.Value.Type == type || type == -1) 4267 keys.Add(inv.Value.Name);
3855 {
3856 keys.Add(inv.Value.Name);
3857 }
3858 } 4268 }
3859 } 4269 }
4270 m_host.TaskInventory.LockItemsForRead(false);
3860 4271
3861 if (keys.Count == 0) 4272 if (keys.Count == 0)
3862 { 4273 {
@@ -3893,25 +4304,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3893 } 4304 }
3894 4305
3895 // move the first object found with this inventory name 4306 // move the first object found with this inventory name
3896 lock (m_host.TaskInventory) 4307 m_host.TaskInventory.LockItemsForRead(true);
4308 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3897 { 4309 {
3898 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4310 if (inv.Value.Name == inventory)
3899 { 4311 {
3900 if (inv.Value.Name == inventory) 4312 found = true;
3901 { 4313 objId = inv.Key;
3902 found = true; 4314 assetType = inv.Value.Type;
3903 objId = inv.Key; 4315 objName = inv.Value.Name;
3904 assetType = inv.Value.Type; 4316 break;
3905 objName = inv.Value.Name;
3906 break;
3907 }
3908 } 4317 }
3909 } 4318 }
4319 m_host.TaskInventory.LockItemsForRead(false);
3910 4320
3911 if (!found) 4321 if (!found)
3912 { 4322 {
3913 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4323 llSay(0, String.Format("Could not find object '{0}'", inventory));
3914 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4324 return;
4325// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3915 } 4326 }
3916 4327
3917 // check if destination is an object 4328 // check if destination is an object
@@ -3937,6 +4348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3937 return; 4348 return;
3938 } 4349 }
3939 } 4350 }
4351
3940 // destination is an avatar 4352 // destination is an avatar
3941 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4353 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3942 4354
@@ -3959,26 +4371,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3959 bucket); 4371 bucket);
3960 if (m_TransferModule != null) 4372 if (m_TransferModule != null)
3961 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4373 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4374
4375 //This delay should only occur when giving inventory to avatars.
3962 ScriptSleep(3000); 4376 ScriptSleep(3000);
3963 } 4377 }
3964 } 4378 }
3965 4379
4380 [DebuggerNonUserCode]
3966 public void llRemoveInventory(string name) 4381 public void llRemoveInventory(string name)
3967 { 4382 {
3968 m_host.AddScriptLPS(1); 4383 m_host.AddScriptLPS(1);
3969 4384
3970 lock (m_host.TaskInventory) 4385 List<TaskInventoryItem> inv;
4386 try
3971 { 4387 {
3972 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4388 m_host.TaskInventory.LockItemsForRead(true);
4389 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4390 }
4391 finally
4392 {
4393 m_host.TaskInventory.LockItemsForRead(false);
4394 }
4395 foreach (TaskInventoryItem item in inv)
4396 {
4397 if (item.Name == name)
3973 { 4398 {
3974 if (item.Name == name) 4399 if (item.ItemID == m_itemID)
3975 { 4400 throw new ScriptDeleteException();
3976 if (item.ItemID == m_itemID) 4401 else
3977 throw new ScriptDeleteException(); 4402 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3978 else 4403 return;
3979 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3980 return;
3981 }
3982 } 4404 }
3983 } 4405 }
3984 } 4406 }
@@ -4013,112 +4435,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4013 { 4435 {
4014 m_host.AddScriptLPS(1); 4436 m_host.AddScriptLPS(1);
4015 4437
4016 UUID uuid = (UUID)id; 4438 UUID uuid;
4017 PresenceInfo pinfo = null; 4439 if (UUID.TryParse(id, out uuid))
4018 UserAccount account;
4019
4020 UserInfoCacheEntry ce;
4021 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4022 { 4440 {
4023 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4441 PresenceInfo pinfo = null;
4024 if (account == null) 4442 UserAccount account;
4443
4444 UserInfoCacheEntry ce;
4445 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4025 { 4446 {
4026 m_userInfoCache[uuid] = null; // Cache negative 4447 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4027 return UUID.Zero.ToString(); 4448 if (account == null)
4028 } 4449 {
4450 m_userInfoCache[uuid] = null; // Cache negative
4451 return UUID.Zero.ToString();
4452 }
4029 4453
4030 4454
4031 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4455 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4032 if (pinfos != null && pinfos.Length > 0) 4456 if (pinfos != null && pinfos.Length > 0)
4033 {
4034 foreach (PresenceInfo p in pinfos)
4035 { 4457 {
4036 if (p.RegionID != UUID.Zero) 4458 foreach (PresenceInfo p in pinfos)
4037 { 4459 {
4038 pinfo = p; 4460 if (p.RegionID != UUID.Zero)
4461 {
4462 pinfo = p;
4463 }
4039 } 4464 }
4040 } 4465 }
4041 }
4042 4466
4043 ce = new UserInfoCacheEntry(); 4467 ce = new UserInfoCacheEntry();
4044 ce.time = Util.EnvironmentTickCount(); 4468 ce.time = Util.EnvironmentTickCount();
4045 ce.account = account; 4469 ce.account = account;
4046 ce.pinfo = pinfo; 4470 ce.pinfo = pinfo;
4047 } 4471 m_userInfoCache[uuid] = ce;
4048 else 4472 }
4049 { 4473 else
4050 if (ce == null) 4474 {
4051 return UUID.Zero.ToString(); 4475 if (ce == null)
4476 return UUID.Zero.ToString();
4052 4477
4053 account = ce.account; 4478 account = ce.account;
4054 pinfo = ce.pinfo; 4479 pinfo = ce.pinfo;
4055 } 4480 }
4056 4481
4057 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4482 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4058 {
4059 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4060 if (pinfos != null && pinfos.Length > 0)
4061 { 4483 {
4062 foreach (PresenceInfo p in pinfos) 4484 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4485 if (pinfos != null && pinfos.Length > 0)
4063 { 4486 {
4064 if (p.RegionID != UUID.Zero) 4487 foreach (PresenceInfo p in pinfos)
4065 { 4488 {
4066 pinfo = p; 4489 if (p.RegionID != UUID.Zero)
4490 {
4491 pinfo = p;
4492 }
4067 } 4493 }
4068 } 4494 }
4069 } 4495 else
4070 else 4496 pinfo = null;
4071 pinfo = null;
4072 4497
4073 ce.time = Util.EnvironmentTickCount(); 4498 ce.time = Util.EnvironmentTickCount();
4074 ce.pinfo = pinfo; 4499 ce.pinfo = pinfo;
4075 } 4500 }
4076 4501
4077 string reply = String.Empty; 4502 string reply = String.Empty;
4078 4503
4079 switch (data) 4504 switch (data)
4080 { 4505 {
4081 case 1: // DATA_ONLINE (0|1) 4506 case 1: // DATA_ONLINE (0|1)
4082 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4507 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4083 reply = "1"; 4508 reply = "1";
4084 else 4509 else
4085 reply = "0"; 4510 reply = "0";
4086 break; 4511 break;
4087 case 2: // DATA_NAME (First Last) 4512 case 2: // DATA_NAME (First Last)
4088 reply = account.FirstName + " " + account.LastName; 4513 reply = account.FirstName + " " + account.LastName;
4089 break; 4514 break;
4090 case 3: // DATA_BORN (YYYY-MM-DD) 4515 case 3: // DATA_BORN (YYYY-MM-DD)
4091 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4516 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4092 born = born.AddSeconds(account.Created); 4517 born = born.AddSeconds(account.Created);
4093 reply = born.ToString("yyyy-MM-dd"); 4518 reply = born.ToString("yyyy-MM-dd");
4094 break; 4519 break;
4095 case 4: // DATA_RATING (0,0,0,0,0,0) 4520 case 4: // DATA_RATING (0,0,0,0,0,0)
4096 reply = "0,0,0,0,0,0"; 4521 reply = "0,0,0,0,0,0";
4097 break; 4522 break;
4098 case 8: // DATA_PAYINFO (0|1|2|3) 4523 case 8: // DATA_PAYINFO (0|1|2|3)
4099 reply = "0"; 4524 reply = "0";
4100 break; 4525 break;
4101 default: 4526 default:
4102 return UUID.Zero.ToString(); // Raise no event 4527 return UUID.Zero.ToString(); // Raise no event
4103 } 4528 }
4104 4529
4105 UUID rq = UUID.Random(); 4530 UUID rq = UUID.Random();
4106 4531
4107 UUID tid = AsyncCommands. 4532 UUID tid = AsyncCommands.
4108 DataserverPlugin.RegisterRequest(m_localID, 4533 DataserverPlugin.RegisterRequest(m_localID,
4109 m_itemID, rq.ToString()); 4534 m_itemID, rq.ToString());
4110 4535
4111 AsyncCommands. 4536 AsyncCommands.
4112 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4537 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4113 4538
4114 ScriptSleep(100); 4539 ScriptSleep(100);
4115 return tid.ToString(); 4540 return tid.ToString();
4541 }
4542 else
4543 {
4544 ShoutError("Invalid UUID passed to llRequestAgentData.");
4545 }
4546 return "";
4116 } 4547 }
4117 4548
4118 public LSL_String llRequestInventoryData(string name) 4549 public LSL_String llRequestInventoryData(string name)
4119 { 4550 {
4120 m_host.AddScriptLPS(1); 4551 m_host.AddScriptLPS(1);
4121 4552
4553 //Clone is thread safe
4122 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4554 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4123 4555
4124 foreach (TaskInventoryItem item in itemDictionary.Values) 4556 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4172,6 +4604,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4172 ScenePresence presence = World.GetScenePresence(agentId); 4604 ScenePresence presence = World.GetScenePresence(agentId);
4173 if (presence != null) 4605 if (presence != null)
4174 { 4606 {
4607 // agent must not be a god
4608 if (presence.UserLevel >= 200) return;
4609
4175 // agent must be over the owners land 4610 // agent must be over the owners land
4176 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4611 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4177 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4612 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4194,7 +4629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4194 UUID av = new UUID(); 4629 UUID av = new UUID();
4195 if (!UUID.TryParse(agent,out av)) 4630 if (!UUID.TryParse(agent,out av))
4196 { 4631 {
4197 LSLError("First parameter to llDialog needs to be a key"); 4632 //LSLError("First parameter to llDialog needs to be a key");
4198 return; 4633 return;
4199 } 4634 }
4200 4635
@@ -4231,17 +4666,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4231 UUID soundId = UUID.Zero; 4666 UUID soundId = UUID.Zero;
4232 if (!UUID.TryParse(impact_sound, out soundId)) 4667 if (!UUID.TryParse(impact_sound, out soundId))
4233 { 4668 {
4234 lock (m_host.TaskInventory) 4669 m_host.TaskInventory.LockItemsForRead(true);
4670 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4235 { 4671 {
4236 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4672 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4237 { 4673 {
4238 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4674 soundId = item.AssetID;
4239 { 4675 break;
4240 soundId = item.AssetID;
4241 break;
4242 }
4243 } 4676 }
4244 } 4677 }
4678 m_host.TaskInventory.LockItemsForRead(false);
4245 } 4679 }
4246 m_host.CollisionSound = soundId; 4680 m_host.CollisionSound = soundId;
4247 m_host.CollisionSoundVolume = (float)impact_volume; 4681 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4281,6 +4715,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID partItemID; 4715 UUID partItemID;
4282 foreach (SceneObjectPart part in parts) 4716 foreach (SceneObjectPart part in parts)
4283 { 4717 {
4718 //Clone is thread safe
4284 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4719 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4285 4720
4286 foreach (TaskInventoryItem item in itemsDictionary.Values) 4721 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4495,17 +4930,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4495 4930
4496 m_host.AddScriptLPS(1); 4931 m_host.AddScriptLPS(1);
4497 4932
4498 lock (m_host.TaskInventory) 4933 m_host.TaskInventory.LockItemsForRead(true);
4934 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4499 { 4935 {
4500 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4936 if (item.Type == 10 && item.ItemID == m_itemID)
4501 { 4937 {
4502 if (item.Type == 10 && item.ItemID == m_itemID) 4938 result = item.Name!=null?item.Name:String.Empty;
4503 { 4939 break;
4504 result = item.Name != null ? item.Name : String.Empty;
4505 break;
4506 }
4507 } 4940 }
4508 } 4941 }
4942 m_host.TaskInventory.LockItemsForRead(false);
4509 4943
4510 return result; 4944 return result;
4511 } 4945 }
@@ -4674,23 +5108,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4674 { 5108 {
4675 m_host.AddScriptLPS(1); 5109 m_host.AddScriptLPS(1);
4676 5110
4677 lock (m_host.TaskInventory) 5111 m_host.TaskInventory.LockItemsForRead(true);
5112 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4678 { 5113 {
4679 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5114 if (inv.Value.Name == name)
4680 { 5115 {
4681 if (inv.Value.Name == name) 5116 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4682 { 5117 {
4683 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5118 m_host.TaskInventory.LockItemsForRead(false);
4684 { 5119 return inv.Value.AssetID.ToString();
4685 return inv.Value.AssetID.ToString(); 5120 }
4686 } 5121 else
4687 else 5122 {
4688 { 5123 m_host.TaskInventory.LockItemsForRead(false);
4689 return UUID.Zero.ToString(); 5124 return UUID.Zero.ToString();
4690 }
4691 } 5125 }
4692 } 5126 }
4693 } 5127 }
5128 m_host.TaskInventory.LockItemsForRead(false);
4694 5129
4695 return UUID.Zero.ToString(); 5130 return UUID.Zero.ToString();
4696 } 5131 }
@@ -4843,14 +5278,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4843 { 5278 {
4844 m_host.AddScriptLPS(1); 5279 m_host.AddScriptLPS(1);
4845 5280
4846 if (src == null) 5281 return src.Length;
4847 {
4848 return 0;
4849 }
4850 else
4851 {
4852 return src.Length;
4853 }
4854 } 5282 }
4855 5283
4856 public LSL_Integer llList2Integer(LSL_List src, int index) 5284 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4896,7 +5324,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4896 else if (src.Data[index] is LSL_Float) 5324 else if (src.Data[index] is LSL_Float)
4897 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5325 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4898 else if (src.Data[index] is LSL_String) 5326 else if (src.Data[index] is LSL_String)
4899 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5327 {
5328 string str = ((LSL_String) src.Data[index]).m_string;
5329 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5330 if (m != Match.Empty)
5331 {
5332 str = m.Value;
5333 double d = 0.0;
5334 if (!Double.TryParse(str, out d))
5335 return 0.0;
5336
5337 return d;
5338 }
5339 return 0.0;
5340 }
4900 return Convert.ToDouble(src.Data[index]); 5341 return Convert.ToDouble(src.Data[index]);
4901 } 5342 }
4902 catch (FormatException) 5343 catch (FormatException)
@@ -5169,7 +5610,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5169 } 5610 }
5170 } 5611 }
5171 } 5612 }
5172 else { 5613 else
5614 {
5173 object[] array = new object[src.Length]; 5615 object[] array = new object[src.Length];
5174 Array.Copy(src.Data, 0, array, 0, src.Length); 5616 Array.Copy(src.Data, 0, array, 0, src.Length);
5175 result = new LSL_List(array); 5617 result = new LSL_List(array);
@@ -5620,10 +6062,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5620 m_host.AddScriptLPS(1); 6062 m_host.AddScriptLPS(1);
5621 6063
5622 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6064 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5623 6065 if (parts.Count > 0)
5624 foreach (var part in parts)
5625 { 6066 {
5626 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6067 try
6068 {
6069 parts[0].ParentGroup.areUpdatesSuspended = true;
6070 foreach (var part in parts)
6071 {
6072 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6073 }
6074 }
6075 finally
6076 {
6077 parts[0].ParentGroup.areUpdatesSuspended = false;
6078 }
5627 } 6079 }
5628 } 6080 }
5629 6081
@@ -5677,6 +6129,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5677 ScriptSleep(5000); 6129 ScriptSleep(5000);
5678 } 6130 }
5679 6131
6132 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6133 {
6134 return ParseString2List(str, separators, in_spacers, false);
6135 }
6136
5680 public LSL_Integer llOverMyLand(string id) 6137 public LSL_Integer llOverMyLand(string id)
5681 { 6138 {
5682 m_host.AddScriptLPS(1); 6139 m_host.AddScriptLPS(1);
@@ -5877,7 +6334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5877 return m_host.ParentGroup.AttachmentPoint; 6334 return m_host.ParentGroup.AttachmentPoint;
5878 } 6335 }
5879 6336
5880 public LSL_Integer llGetFreeMemory() 6337 public virtual LSL_Integer llGetFreeMemory()
5881 { 6338 {
5882 m_host.AddScriptLPS(1); 6339 m_host.AddScriptLPS(1);
5883 // Make scripts designed for LSO happy 6340 // Make scripts designed for LSO happy
@@ -5994,7 +6451,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5994 SetParticleSystem(m_host, rules); 6451 SetParticleSystem(m_host, rules);
5995 } 6452 }
5996 6453
5997 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6454 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6455 {
5998 6456
5999 6457
6000 if (rules.Length == 0) 6458 if (rules.Length == 0)
@@ -6188,14 +6646,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6188 6646
6189 protected UUID GetTaskInventoryItem(string name) 6647 protected UUID GetTaskInventoryItem(string name)
6190 { 6648 {
6191 lock (m_host.TaskInventory) 6649 m_host.TaskInventory.LockItemsForRead(true);
6650 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6192 { 6651 {
6193 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6652 if (inv.Value.Name == name)
6194 { 6653 {
6195 if (inv.Value.Name == name) 6654 m_host.TaskInventory.LockItemsForRead(false);
6196 return inv.Key; 6655 return inv.Key;
6197 } 6656 }
6198 } 6657 }
6658 m_host.TaskInventory.LockItemsForRead(false);
6199 6659
6200 return UUID.Zero; 6660 return UUID.Zero;
6201 } 6661 }
@@ -6445,13 +6905,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6445 UUID av = new UUID(); 6905 UUID av = new UUID();
6446 if (!UUID.TryParse(avatar,out av)) 6906 if (!UUID.TryParse(avatar,out av))
6447 { 6907 {
6448 LSLError("First parameter to llDialog needs to be a key"); 6908 //LSLError("First parameter to llDialog needs to be a key");
6449 return; 6909 return;
6450 } 6910 }
6451 if (buttons.Length < 1) 6911 if (buttons.Length < 1)
6452 { 6912 {
6453 LSLError("No less than 1 button can be shown"); 6913 buttons.Add("OK");
6454 return;
6455 } 6914 }
6456 if (buttons.Length > 12) 6915 if (buttons.Length > 12)
6457 { 6916 {
@@ -6468,7 +6927,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6468 } 6927 }
6469 if (buttons.Data[i].ToString().Length > 24) 6928 if (buttons.Data[i].ToString().Length > 24)
6470 { 6929 {
6471 LSLError("button label cannot be longer than 24 characters"); 6930 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6472 return; 6931 return;
6473 } 6932 }
6474 buts[i] = buttons.Data[i].ToString(); 6933 buts[i] = buttons.Data[i].ToString();
@@ -6527,22 +6986,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6527 } 6986 }
6528 6987
6529 // copy the first script found with this inventory name 6988 // copy the first script found with this inventory name
6530 lock (m_host.TaskInventory) 6989 TaskInventoryItem scriptItem = null;
6990 m_host.TaskInventory.LockItemsForRead(true);
6991 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6531 { 6992 {
6532 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6993 if (inv.Value.Name == name)
6533 { 6994 {
6534 if (inv.Value.Name == name) 6995 // make sure the object is a script
6996 if (10 == inv.Value.Type)
6535 { 6997 {
6536 // make sure the object is a script 6998 found = true;
6537 if (10 == inv.Value.Type) 6999 srcId = inv.Key;
6538 { 7000 scriptItem = inv.Value;
6539 found = true; 7001 break;
6540 srcId = inv.Key;
6541 break;
6542 }
6543 } 7002 }
6544 } 7003 }
6545 } 7004 }
7005 m_host.TaskInventory.LockItemsForRead(false);
6546 7006
6547 if (!found) 7007 if (!found)
6548 { 7008 {
@@ -6550,8 +7010,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6550 return; 7010 return;
6551 } 7011 }
6552 7012
6553 // the rest of the permission checks are done in RezScript, so check the pin there as well 7013 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6554 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7014 if (dest != null)
7015 {
7016 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7017 {
7018 // the rest of the permission checks are done in RezScript, so check the pin there as well
7019 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7020
7021 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7022 m_host.Inventory.RemoveInventoryItem(srcId);
7023 }
7024 }
6555 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7025 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6556 ScriptSleep(3000); 7026 ScriptSleep(3000);
6557 } 7027 }
@@ -6614,19 +7084,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6614 public LSL_String llMD5String(string src, int nonce) 7084 public LSL_String llMD5String(string src, int nonce)
6615 { 7085 {
6616 m_host.AddScriptLPS(1); 7086 m_host.AddScriptLPS(1);
6617 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7087 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6618 } 7088 }
6619 7089
6620 public LSL_String llSHA1String(string src) 7090 public LSL_String llSHA1String(string src)
6621 { 7091 {
6622 m_host.AddScriptLPS(1); 7092 m_host.AddScriptLPS(1);
6623 return Util.SHA1Hash(src).ToLower(); 7093 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6624 } 7094 }
6625 7095
6626 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7096 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6627 { 7097 {
6628 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7098 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6629 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7099 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7101 return shapeBlock;
6630 7102
6631 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7103 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6632 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7104 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6731,6 +7203,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6731 // Prim type box, cylinder and prism. 7203 // Prim type box, cylinder and prism.
6732 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) 7204 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)
6733 { 7205 {
7206 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7207 return;
7208
6734 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7209 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6735 ObjectShapePacket.ObjectDataBlock shapeBlock; 7210 ObjectShapePacket.ObjectDataBlock shapeBlock;
6736 7211
@@ -6784,6 +7259,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6784 // Prim type sphere. 7259 // Prim type sphere.
6785 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7260 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6786 { 7261 {
7262 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7263 return;
7264
6787 ObjectShapePacket.ObjectDataBlock shapeBlock; 7265 ObjectShapePacket.ObjectDataBlock shapeBlock;
6788 7266
6789 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7267 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6825,6 +7303,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6825 // Prim type torus, tube and ring. 7303 // Prim type torus, tube and ring.
6826 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) 7304 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)
6827 { 7305 {
7306 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7307 return;
7308
6828 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7309 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6829 ObjectShapePacket.ObjectDataBlock shapeBlock; 7310 ObjectShapePacket.ObjectDataBlock shapeBlock;
6830 7311
@@ -6960,6 +7441,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6960 // Prim type sculpt. 7441 // Prim type sculpt.
6961 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7442 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6962 { 7443 {
7444 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7445 return;
7446
6963 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7447 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6964 UUID sculptId; 7448 UUID sculptId;
6965 7449
@@ -6976,13 +7460,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6976 shapeBlock.PathScaleX = 100; 7460 shapeBlock.PathScaleX = 100;
6977 shapeBlock.PathScaleY = 150; 7461 shapeBlock.PathScaleY = 150;
6978 7462
6979 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7463 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6980 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7464 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6981 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7465 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6982 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7466 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6983 { 7467 {
6984 // default 7468 // default
6985 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7469 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6986 } 7470 }
6987 7471
6988 part.Shape.SetSculptProperties((byte)type, sculptId); 7472 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -6998,32 +7482,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6998 ScriptSleep(200); 7482 ScriptSleep(200);
6999 } 7483 }
7000 7484
7001 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7485 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7002 { 7486 {
7003 m_host.AddScriptLPS(1); 7487 m_host.AddScriptLPS(1);
7004 7488
7005 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7489 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7490 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7491 if (parts.Count>0)
7492 {
7493 try
7494 {
7495 parts[0].ParentGroup.areUpdatesSuspended = true;
7496 foreach (SceneObjectPart part in parts)
7497 SetPrimParams(part, rules);
7498 }
7499 finally
7500 {
7501 parts[0].ParentGroup.areUpdatesSuspended = false;
7502 }
7503 }
7504 if (avatars.Count > 0)
7505 {
7506 foreach (ScenePresence avatar in avatars)
7507 SetPrimParams(avatar, rules);
7508 }
7509 }
7006 7510
7007 foreach (SceneObjectPart part in parts) 7511 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7008 SetPrimParams(part, rules); 7512 {
7009 7513 llSetLinkPrimitiveParamsFast(linknumber, rules);
7010 ScriptSleep(200); 7514 ScriptSleep(200);
7011 } 7515 }
7012 7516
7013 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7517 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7014 { 7518 {
7015 m_host.AddScriptLPS(1); 7519 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7520 //We only support PRIM_POSITION and PRIM_ROTATION
7016 7521
7017 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7522 int idx = 0;
7018 7523
7019 foreach (SceneObjectPart part in parts) 7524 while (idx < rules.Length)
7020 SetPrimParams(part, rules); 7525 {
7526 int code = rules.GetLSLIntegerItem(idx++);
7527
7528 int remain = rules.Length - idx;
7529
7530
7531
7532 switch (code)
7533 {
7534 case (int)ScriptBaseClass.PRIM_POSITION:
7535 if (remain < 1)
7536 return;
7537 LSL_Vector v;
7538 v = rules.GetVector3Item(idx++);
7539 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7540 av.SendAvatarDataToAllAgents();
7541
7542 break;
7543
7544 case (int)ScriptBaseClass.PRIM_ROTATION:
7545 if (remain < 1)
7546 return;
7547 LSL_Rotation r;
7548 r = rules.GetQuaternionItem(idx++);
7549 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7550 av.SendAvatarDataToAllAgents();
7551 break;
7552 }
7553 }
7021 } 7554 }
7022 7555
7023 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7556 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7024 { 7557 {
7558 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7559 return;
7560
7025 int idx = 0; 7561 int idx = 0;
7026 7562
7563 bool positionChanged = false;
7564 LSL_Vector currentPosition = GetPartLocalPos(part);
7565
7027 while (idx < rules.Length) 7566 while (idx < rules.Length)
7028 { 7567 {
7029 int code = rules.GetLSLIntegerItem(idx++); 7568 int code = rules.GetLSLIntegerItem(idx++);
@@ -7032,7 +7571,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7032 7571
7033 int face; 7572 int face;
7034 LSL_Vector v; 7573 LSL_Vector v;
7035 7574
7036 switch (code) 7575 switch (code)
7037 { 7576 {
7038 case (int)ScriptBaseClass.PRIM_POSITION: 7577 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -7040,7 +7579,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7040 return; 7579 return;
7041 7580
7042 v=rules.GetVector3Item(idx++); 7581 v=rules.GetVector3Item(idx++);
7043 SetPos(part, v); 7582 positionChanged = true;
7583 currentPosition = GetSetPosTarget(part, v, currentPosition);
7044 7584
7045 break; 7585 break;
7046 case (int)ScriptBaseClass.PRIM_SIZE: 7586 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7385,6 +7925,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7385 break; 7925 break;
7386 } 7926 }
7387 } 7927 }
7928
7929 if (positionChanged)
7930 {
7931 if (part.ParentGroup.RootPart == part)
7932 {
7933 SceneObjectGroup parent = part.ParentGroup;
7934 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7935 }
7936 else
7937 {
7938 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7939 SceneObjectGroup parent = part.ParentGroup;
7940 parent.HasGroupChanged = true;
7941 parent.ScheduleGroupForTerseUpdate();
7942 }
7943 }
7388 } 7944 }
7389 7945
7390 public LSL_String llStringToBase64(string str) 7946 public LSL_String llStringToBase64(string str)
@@ -7533,13 +8089,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7533 public LSL_Integer llGetNumberOfPrims() 8089 public LSL_Integer llGetNumberOfPrims()
7534 { 8090 {
7535 m_host.AddScriptLPS(1); 8091 m_host.AddScriptLPS(1);
7536 int avatarCount = 0; 8092 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7537 World.ForEachScenePresence(delegate(ScenePresence presence) 8093
7538 {
7539 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7540 avatarCount++;
7541 });
7542
7543 return m_host.ParentGroup.PrimCount + avatarCount; 8094 return m_host.ParentGroup.PrimCount + avatarCount;
7544 } 8095 }
7545 8096
@@ -7555,55 +8106,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7555 m_host.AddScriptLPS(1); 8106 m_host.AddScriptLPS(1);
7556 UUID objID = UUID.Zero; 8107 UUID objID = UUID.Zero;
7557 LSL_List result = new LSL_List(); 8108 LSL_List result = new LSL_List();
8109
8110 // If the ID is not valid, return null result
7558 if (!UUID.TryParse(obj, out objID)) 8111 if (!UUID.TryParse(obj, out objID))
7559 { 8112 {
7560 result.Add(new LSL_Vector()); 8113 result.Add(new LSL_Vector());
7561 result.Add(new LSL_Vector()); 8114 result.Add(new LSL_Vector());
7562 return result; 8115 return result;
7563 } 8116 }
8117
8118 // Check if this is an attached prim. If so, replace
8119 // the UUID with the avatar UUID and report it's bounding box
8120 SceneObjectPart part = World.GetSceneObjectPart(objID);
8121 if (part != null && part.ParentGroup.IsAttachment)
8122 objID = part.ParentGroup.AttachedAvatar;
8123
8124 // Find out if this is an avatar ID. If so, return it's box
7564 ScenePresence presence = World.GetScenePresence(objID); 8125 ScenePresence presence = World.GetScenePresence(objID);
7565 if (presence != null) 8126 if (presence != null)
7566 { 8127 {
7567 if (presence.ParentID == 0) // not sat on an object 8128 // As per LSL Wiki, there is no difference between sitting
8129 // and standing avatar since server 1.36
8130 LSL_Vector lower;
8131 LSL_Vector upper;
8132 if (presence.Animator.Animations.DefaultAnimation.AnimID
8133 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7568 { 8134 {
7569 LSL_Vector lower; 8135 // This is for ground sitting avatars
7570 LSL_Vector upper; 8136 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7571 if (presence.Animator.Animations.DefaultAnimation.AnimID 8137 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7572 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8138 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7573 {
7574 // This is for ground sitting avatars
7575 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7576 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7577 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7578 }
7579 else
7580 {
7581 // This is for standing/flying avatars
7582 float height = presence.Appearance.AvatarHeight / 2.0f;
7583 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7584 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7585 }
7586 result.Add(lower);
7587 result.Add(upper);
7588 return result;
7589 } 8139 }
7590 else 8140 else
7591 { 8141 {
7592 // sitting on an object so we need the bounding box of that 8142 // This is for standing/flying avatars
7593 // which should include the avatar so set the UUID to the 8143 float height = presence.Appearance.AvatarHeight / 2.0f;
7594 // UUID of the object the avatar is sat on and allow it to fall through 8144 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7595 // to processing an object 8145 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7596 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7597 objID = p.UUID;
7598 } 8146 }
8147
8148 // Adjust to the documented error offsets (see LSL Wiki)
8149 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8150 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8151
8152 if (lower.x > upper.x)
8153 lower.x = upper.x;
8154 if (lower.y > upper.y)
8155 lower.y = upper.y;
8156 if (lower.z > upper.z)
8157 lower.z = upper.z;
8158
8159 result.Add(lower);
8160 result.Add(upper);
8161 return result;
7599 } 8162 }
7600 SceneObjectPart part = World.GetSceneObjectPart(objID); 8163
8164 part = World.GetSceneObjectPart(objID);
7601 // Currently only works for single prims without a sitting avatar 8165 // Currently only works for single prims without a sitting avatar
7602 if (part != null) 8166 if (part != null)
7603 { 8167 {
7604 Vector3 halfSize = part.Scale / 2.0f; 8168 float minX;
7605 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8169 float maxX;
7606 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8170 float minY;
8171 float maxY;
8172 float minZ;
8173 float maxZ;
8174
8175 // This BBox is in sim coordinates, with the offset being
8176 // a contained point.
8177 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8178 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8179
8180 minX -= offsets[0].X;
8181 maxX -= offsets[0].X;
8182 minY -= offsets[0].Y;
8183 maxY -= offsets[0].Y;
8184 minZ -= offsets[0].Z;
8185 maxZ -= offsets[0].Z;
8186
8187 LSL_Vector lower;
8188 LSL_Vector upper;
8189
8190 // Adjust to the documented error offsets (see LSL Wiki)
8191 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8192 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8193
8194 if (lower.x > upper.x)
8195 lower.x = upper.x;
8196 if (lower.y > upper.y)
8197 lower.y = upper.y;
8198 if (lower.z > upper.z)
8199 lower.z = upper.z;
8200
7607 result.Add(lower); 8201 result.Add(lower);
7608 result.Add(upper); 8202 result.Add(upper);
7609 return result; 8203 return result;
@@ -7683,13 +8277,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7683 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8277 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7684 part.AbsolutePosition.Y, 8278 part.AbsolutePosition.Y,
7685 part.AbsolutePosition.Z); 8279 part.AbsolutePosition.Z);
7686 // For some reason, the part.AbsolutePosition.* values do not change if the
7687 // linkset is rotated; they always reflect the child prim's world position
7688 // as though the linkset is unrotated. This is incompatible behavior with SL's
7689 // implementation, so will break scripts imported from there (not to mention it
7690 // makes it more difficult to determine a child prim's actual inworld position).
7691 if (part.ParentID != 0)
7692 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7693 res.Add(v); 8280 res.Add(v);
7694 break; 8281 break;
7695 8282
@@ -7860,56 +8447,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7860 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8447 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7861 if (remain < 1) 8448 if (remain < 1)
7862 return res; 8449 return res;
7863 8450 face = (int)rules.GetLSLIntegerItem(idx++);
7864 face=(int)rules.GetLSLIntegerItem(idx++);
7865 8451
7866 tex = part.Shape.Textures; 8452 tex = part.Shape.Textures;
8453 int shiny;
7867 if (face == ScriptBaseClass.ALL_SIDES) 8454 if (face == ScriptBaseClass.ALL_SIDES)
7868 { 8455 {
7869 for (face = 0; face < GetNumberOfSides(part); face++) 8456 for (face = 0; face < GetNumberOfSides(part); face++)
7870 { 8457 {
7871 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8458 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7872 // Convert Shininess to PRIM_SHINY_* 8459 if (shinyness == Shininess.High)
7873 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8460 {
7874 // PRIM_BUMP_* 8461 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7875 res.Add(new LSL_Integer((int)texface.Bump)); 8462 }
8463 else if (shinyness == Shininess.Medium)
8464 {
8465 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8466 }
8467 else if (shinyness == Shininess.Low)
8468 {
8469 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8470 }
8471 else
8472 {
8473 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8474 }
8475 res.Add(new LSL_Integer(shiny));
8476 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7876 } 8477 }
7877 } 8478 }
7878 else 8479 else
7879 { 8480 {
7880 if (face >= 0 && face < GetNumberOfSides(part)) 8481 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8482 if (shinyness == Shininess.High)
7881 { 8483 {
7882 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8484 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7883 // Convert Shininess to PRIM_SHINY_*
7884 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7885 // PRIM_BUMP_*
7886 res.Add(new LSL_Integer((int)texface.Bump));
7887 } 8485 }
8486 else if (shinyness == Shininess.Medium)
8487 {
8488 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8489 }
8490 else if (shinyness == Shininess.Low)
8491 {
8492 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8493 }
8494 else
8495 {
8496 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8497 }
8498 res.Add(new LSL_Integer(shiny));
8499 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7888 } 8500 }
7889 break; 8501 break;
7890 8502
7891 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8503 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7892 if (remain < 1) 8504 if (remain < 1)
7893 return res; 8505 return res;
7894 8506 face = (int)rules.GetLSLIntegerItem(idx++);
7895 face=(int)rules.GetLSLIntegerItem(idx++);
7896 8507
7897 tex = part.Shape.Textures; 8508 tex = part.Shape.Textures;
8509 int fullbright;
7898 if (face == ScriptBaseClass.ALL_SIDES) 8510 if (face == ScriptBaseClass.ALL_SIDES)
7899 { 8511 {
7900 for (face = 0; face < GetNumberOfSides(part); face++) 8512 for (face = 0; face < GetNumberOfSides(part); face++)
7901 { 8513 {
7902 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8514 if (tex.GetFace((uint)face).Fullbright == true)
7903 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8515 {
8516 fullbright = ScriptBaseClass.TRUE;
8517 }
8518 else
8519 {
8520 fullbright = ScriptBaseClass.FALSE;
8521 }
8522 res.Add(new LSL_Integer(fullbright));
7904 } 8523 }
7905 } 8524 }
7906 else 8525 else
7907 { 8526 {
7908 if (face >= 0 && face < GetNumberOfSides(part)) 8527 if (tex.GetFace((uint)face).Fullbright == true)
7909 { 8528 {
7910 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8529 fullbright = ScriptBaseClass.TRUE;
7911 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7912 } 8530 }
8531 else
8532 {
8533 fullbright = ScriptBaseClass.FALSE;
8534 }
8535 res.Add(new LSL_Integer(fullbright));
7913 } 8536 }
7914 break; 8537 break;
7915 8538
@@ -7931,27 +8554,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7931 break; 8554 break;
7932 8555
7933 case (int)ScriptBaseClass.PRIM_TEXGEN: 8556 case (int)ScriptBaseClass.PRIM_TEXGEN:
8557 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7934 if (remain < 1) 8558 if (remain < 1)
7935 return res; 8559 return res;
7936 8560 face = (int)rules.GetLSLIntegerItem(idx++);
7937 face=(int)rules.GetLSLIntegerItem(idx++);
7938 8561
7939 tex = part.Shape.Textures; 8562 tex = part.Shape.Textures;
7940 if (face == ScriptBaseClass.ALL_SIDES) 8563 if (face == ScriptBaseClass.ALL_SIDES)
7941 { 8564 {
7942 for (face = 0; face < GetNumberOfSides(part); face++) 8565 for (face = 0; face < GetNumberOfSides(part); face++)
7943 { 8566 {
7944 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8567 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7945 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8568 {
7946 res.Add(new LSL_Integer((uint)texgen >> 1)); 8569 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8570 }
8571 else
8572 {
8573 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8574 }
7947 } 8575 }
7948 } 8576 }
7949 else 8577 else
7950 { 8578 {
7951 if (face >= 0 && face < GetNumberOfSides(part)) 8579 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8580 {
8581 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8582 }
8583 else
7952 { 8584 {
7953 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8585 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7954 res.Add(new LSL_Integer((uint)texgen >> 1));
7955 } 8586 }
7956 } 8587 }
7957 break; 8588 break;
@@ -7974,28 +8605,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7974 case (int)ScriptBaseClass.PRIM_GLOW: 8605 case (int)ScriptBaseClass.PRIM_GLOW:
7975 if (remain < 1) 8606 if (remain < 1)
7976 return res; 8607 return res;
7977 8608 face = (int)rules.GetLSLIntegerItem(idx++);
7978 face=(int)rules.GetLSLIntegerItem(idx++);
7979 8609
7980 tex = part.Shape.Textures; 8610 tex = part.Shape.Textures;
8611 float primglow;
7981 if (face == ScriptBaseClass.ALL_SIDES) 8612 if (face == ScriptBaseClass.ALL_SIDES)
7982 { 8613 {
7983 for (face = 0; face < GetNumberOfSides(part); face++) 8614 for (face = 0; face < GetNumberOfSides(part); face++)
7984 { 8615 {
7985 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8616 primglow = tex.GetFace((uint)face).Glow;
7986 res.Add(new LSL_Float(texface.Glow)); 8617 res.Add(new LSL_Float(primglow));
7987 } 8618 }
7988 } 8619 }
7989 else 8620 else
7990 { 8621 {
7991 if (face >= 0 && face < GetNumberOfSides(part)) 8622 primglow = tex.GetFace((uint)face).Glow;
7992 { 8623 res.Add(new LSL_Float(primglow));
7993 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7994 res.Add(new LSL_Float(texface.Glow));
7995 }
7996 } 8624 }
7997 break; 8625 break;
7998
7999 case (int)ScriptBaseClass.PRIM_TEXT: 8626 case (int)ScriptBaseClass.PRIM_TEXT:
8000 Color4 textColor = part.GetTextColor(); 8627 Color4 textColor = part.GetTextColor();
8001 res.Add(new LSL_String(part.Text)); 8628 res.Add(new LSL_String(part.Text));
@@ -8544,8 +9171,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8544 // The function returns an ordered list 9171 // The function returns an ordered list
8545 // representing the tokens found in the supplied 9172 // representing the tokens found in the supplied
8546 // sources string. If two successive tokenizers 9173 // sources string. If two successive tokenizers
8547 // are encountered, then a NULL entry is added 9174 // are encountered, then a null-string entry is
8548 // to the list. 9175 // added to the list.
8549 // 9176 //
8550 // It is a precondition that the source and 9177 // It is a precondition that the source and
8551 // toekizer lisst are non-null. If they are null, 9178 // toekizer lisst are non-null. If they are null,
@@ -8553,7 +9180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8553 // while their lengths are being determined. 9180 // while their lengths are being determined.
8554 // 9181 //
8555 // A small amount of working memoryis required 9182 // A small amount of working memoryis required
8556 // of approximately 8*#tokenizers. 9183 // of approximately 8*#tokenizers + 8*srcstrlen.
8557 // 9184 //
8558 // There are many ways in which this function 9185 // There are many ways in which this function
8559 // can be implemented, this implementation is 9186 // can be implemented, this implementation is
@@ -8569,155 +9196,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8569 // and eliminates redundant tokenizers as soon 9196 // and eliminates redundant tokenizers as soon
8570 // as is possible. 9197 // as is possible.
8571 // 9198 //
8572 // The implementation tries to avoid any copying 9199 // The implementation tries to minimize temporary
8573 // of arrays or other objects. 9200 // garbage generation.
8574 // </remarks> 9201 // </remarks>
8575 9202
8576 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9203 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8577 { 9204 {
8578 int beginning = 0; 9205 return ParseString2List(src, separators, spacers, true);
8579 int srclen = src.Length; 9206 }
8580 int seplen = separators.Length;
8581 object[] separray = separators.Data;
8582 int spclen = spacers.Length;
8583 object[] spcarray = spacers.Data;
8584 int mlen = seplen+spclen;
8585
8586 int[] offset = new int[mlen+1];
8587 bool[] active = new bool[mlen];
8588
8589 int best;
8590 int j;
8591
8592 // Initial capacity reduces resize cost
8593 9207
8594 LSL_List tokens = new LSL_List(); 9208 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9209 {
9210 int srclen = src.Length;
9211 int seplen = separators.Length;
9212 object[] separray = separators.Data;
9213 int spclen = spacers.Length;
9214 object[] spcarray = spacers.Data;
9215 int dellen = 0;
9216 string[] delarray = new string[seplen+spclen];
8595 9217
8596 // All entries are initially valid 9218 int outlen = 0;
9219 string[] outarray = new string[srclen*2+1];
8597 9220
8598 for (int i = 0; i < mlen; i++) 9221 int i, j;
8599 active[i] = true; 9222 string d;
8600 9223
8601 offset[mlen] = srclen; 9224 m_host.AddScriptLPS(1);
8602 9225
8603 while (beginning < srclen) 9226 /*
9227 * Convert separator and spacer lists to C# strings.
9228 * Also filter out null strings so we don't hang.
9229 */
9230 for (i = 0; i < seplen; i ++)
8604 { 9231 {
9232 d = separray[i].ToString();
9233 if (d.Length > 0)
9234 {
9235 delarray[dellen++] = d;
9236 }
9237 }
9238 seplen = dellen;
8605 9239
8606 best = mlen; // as bad as it gets 9240 for (i = 0; i < spclen; i ++)
9241 {
9242 d = spcarray[i].ToString();
9243 if (d.Length > 0)
9244 {
9245 delarray[dellen++] = d;
9246 }
9247 }
8607 9248
8608 // Scan for separators 9249 /*
9250 * Scan through source string from beginning to end.
9251 */
9252 for (i = 0;;)
9253 {
8609 9254
8610 for (j = 0; j < seplen; j++) 9255 /*
9256 * Find earliest delimeter in src starting at i (if any).
9257 */
9258 int earliestDel = -1;
9259 int earliestSrc = srclen;
9260 string earliestStr = null;
9261 for (j = 0; j < dellen; j ++)
8611 { 9262 {
8612 if (separray[j].ToString() == String.Empty) 9263 d = delarray[j];
8613 active[j] = false; 9264 if (d != null)
8614
8615 if (active[j])
8616 { 9265 {
8617 // scan all of the markers 9266 int index = src.IndexOf(d, i);
8618 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9267 if (index < 0)
8619 { 9268 {
8620 // not present at all 9269 delarray[j] = null; // delim nowhere in src, don't check it anymore
8621 active[j] = false;
8622 } 9270 }
8623 else 9271 else if (index < earliestSrc)
8624 { 9272 {
8625 // present and correct 9273 earliestSrc = index; // where delimeter starts in source string
8626 if (offset[j] < offset[best]) 9274 earliestDel = j; // where delimeter is in delarray[]
8627 { 9275 earliestStr = d; // the delimeter string from delarray[]
8628 // closest so far 9276 if (index == i) break; // can't do any better than found at beg of string
8629 best = j;
8630 if (offset[best] == beginning)
8631 break;
8632 }
8633 } 9277 }
8634 } 9278 }
8635 } 9279 }
8636 9280
8637 // Scan for spacers 9281 /*
8638 9282 * Output source string starting at i through start of earliest delimeter.
8639 if (offset[best] != beginning) 9283 */
9284 if (keepNulls || (earliestSrc > i))
8640 { 9285 {
8641 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9286 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8642 {
8643 if (spcarray[j-seplen].ToString() == String.Empty)
8644 active[j] = false;
8645
8646 if (active[j])
8647 {
8648 // scan all of the markers
8649 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8650 {
8651 // not present at all
8652 active[j] = false;
8653 }
8654 else
8655 {
8656 // present and correct
8657 if (offset[j] < offset[best])
8658 {
8659 // closest so far
8660 best = j;
8661 }
8662 }
8663 }
8664 }
8665 } 9287 }
8666 9288
8667 // This is the normal exit from the scanning loop 9289 /*
9290 * If no delimeter found at or after i, we're done scanning.
9291 */
9292 if (earliestDel < 0) break;
8668 9293
8669 if (best == mlen) 9294 /*
9295 * If delimeter was a spacer, output the spacer.
9296 */
9297 if (earliestDel >= seplen)
8670 { 9298 {
8671 // no markers were found on this pass 9299 outarray[outlen++] = earliestStr;
8672 // so we're pretty much done
8673 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8674 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8675 break;
8676 } 9300 }
8677 9301
8678 // Otherwise we just add the newly delimited token 9302 /*
8679 // and recalculate where the search should continue. 9303 * Look at rest of src string following delimeter.
8680 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9304 */
8681 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9305 i = earliestSrc + earliestStr.Length;
8682
8683 if (best < seplen)
8684 {
8685 beginning = offset[best] + (separray[best].ToString()).Length;
8686 }
8687 else
8688 {
8689 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8690 string str = spcarray[best - seplen].ToString();
8691 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8692 tokens.Add(new LSL_String(str));
8693 }
8694 } 9306 }
8695 9307
8696 // This an awkward an not very intuitive boundary case. If the 9308 /*
8697 // last substring is a tokenizer, then there is an implied trailing 9309 * Make up an exact-sized output array suitable for an LSL_List object.
8698 // null list entry. Hopefully the single comparison will not be too 9310 */
8699 // arduous. Alternatively the 'break' could be replced with a return 9311 object[] outlist = new object[outlen];
8700 // but that's shabby programming. 9312 for (i = 0; i < outlen; i ++)
8701
8702 if ((beginning == srclen) && (keepNulls))
8703 { 9313 {
8704 if (srclen != 0) 9314 outlist[i] = new LSL_String(outarray[i]);
8705 tokens.Add(new LSL_String(""));
8706 } 9315 }
8707 9316 return new LSL_List(outlist);
8708 return tokens;
8709 }
8710
8711 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8712 {
8713 m_host.AddScriptLPS(1);
8714 return this.ParseString(src, separators, spacers, false);
8715 }
8716
8717 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8718 {
8719 m_host.AddScriptLPS(1);
8720 return this.ParseString(src, separators, spacers, true);
8721 } 9317 }
8722 9318
8723 public LSL_Integer llGetObjectPermMask(int mask) 9319 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8794,28 +9390,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8794 { 9390 {
8795 m_host.AddScriptLPS(1); 9391 m_host.AddScriptLPS(1);
8796 9392
8797 lock (m_host.TaskInventory) 9393 m_host.TaskInventory.LockItemsForRead(true);
9394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8798 { 9395 {
8799 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9396 if (inv.Value.Name == item)
8800 { 9397 {
8801 if (inv.Value.Name == item) 9398 m_host.TaskInventory.LockItemsForRead(false);
9399 switch (mask)
8802 { 9400 {
8803 switch (mask) 9401 case 0:
8804 { 9402 return (int)inv.Value.BasePermissions;
8805 case 0: 9403 case 1:
8806 return (int)inv.Value.BasePermissions; 9404 return (int)inv.Value.CurrentPermissions;
8807 case 1: 9405 case 2:
8808 return (int)inv.Value.CurrentPermissions; 9406 return (int)inv.Value.GroupPermissions;
8809 case 2: 9407 case 3:
8810 return (int)inv.Value.GroupPermissions; 9408 return (int)inv.Value.EveryonePermissions;
8811 case 3: 9409 case 4:
8812 return (int)inv.Value.EveryonePermissions; 9410 return (int)inv.Value.NextPermissions;
8813 case 4:
8814 return (int)inv.Value.NextPermissions;
8815 }
8816 } 9411 }
8817 } 9412 }
8818 } 9413 }
9414 m_host.TaskInventory.LockItemsForRead(false);
8819 9415
8820 return -1; 9416 return -1;
8821 } 9417 }
@@ -8862,16 +9458,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8862 { 9458 {
8863 m_host.AddScriptLPS(1); 9459 m_host.AddScriptLPS(1);
8864 9460
8865 lock (m_host.TaskInventory) 9461 m_host.TaskInventory.LockItemsForRead(true);
9462 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8866 { 9463 {
8867 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9464 if (inv.Value.Name == item)
8868 { 9465 {
8869 if (inv.Value.Name == item) 9466 m_host.TaskInventory.LockItemsForRead(false);
8870 { 9467 return inv.Value.CreatorID.ToString();
8871 return inv.Value.CreatorID.ToString();
8872 }
8873 } 9468 }
8874 } 9469 }
9470 m_host.TaskInventory.LockItemsForRead(false);
8875 9471
8876 llSay(0, "No item name '" + item + "'"); 9472 llSay(0, "No item name '" + item + "'");
8877 9473
@@ -9019,7 +9615,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9019 } 9615 }
9020 9616
9021 /// <summary> 9617 /// <summary>
9022 /// illListReplaceList removes the sub-list defined by the inclusive indices 9618 /// llListReplaceList removes the sub-list defined by the inclusive indices
9023 /// start and end and inserts the src list in its place. The inclusive 9619 /// start and end and inserts the src list in its place. The inclusive
9024 /// nature of the indices means that at least one element must be deleted 9620 /// nature of the indices means that at least one element must be deleted
9025 /// if the indices are within the bounds of the existing list. I.e. 2,2 9621 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9076,16 +9672,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9076 // based upon end. Note that if end exceeds the upper 9672 // based upon end. Note that if end exceeds the upper
9077 // bound in this case, the entire destination list 9673 // bound in this case, the entire destination list
9078 // is removed. 9674 // is removed.
9079 else 9675 else if (start == 0)
9080 { 9676 {
9081 if (end + 1 < dest.Length) 9677 if (end + 1 < dest.Length)
9082 {
9083 return src + dest.GetSublist(end + 1, -1); 9678 return src + dest.GetSublist(end + 1, -1);
9084 }
9085 else 9679 else
9086 {
9087 return src; 9680 return src;
9088 } 9681 }
9682 else // Start < 0
9683 {
9684 if (end + 1 < dest.Length)
9685 return dest.GetSublist(end + 1, -1);
9686 else
9687 return new LSL_List();
9089 } 9688 }
9090 } 9689 }
9091 // Finally, if start > end, we strip away a prefix and 9690 // Finally, if start > end, we strip away a prefix and
@@ -9136,17 +9735,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9136 int width = 0; 9735 int width = 0;
9137 int height = 0; 9736 int height = 0;
9138 9737
9139 ParcelMediaCommandEnum? commandToSend = null; 9738 uint commandToSend = 0;
9140 float time = 0.0f; // default is from start 9739 float time = 0.0f; // default is from start
9141 9740
9142 ScenePresence presence = null; 9741 ScenePresence presence = null;
9143 9742
9144 for (int i = 0; i < commandList.Data.Length; i++) 9743 for (int i = 0; i < commandList.Data.Length; i++)
9145 { 9744 {
9146 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9745 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9147 switch (command) 9746 switch (command)
9148 { 9747 {
9149 case ParcelMediaCommandEnum.Agent: 9748 case (uint)ParcelMediaCommandEnum.Agent:
9150 // we send only to one agent 9749 // we send only to one agent
9151 if ((i + 1) < commandList.Length) 9750 if ((i + 1) < commandList.Length)
9152 { 9751 {
@@ -9163,25 +9762,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9163 } 9762 }
9164 break; 9763 break;
9165 9764
9166 case ParcelMediaCommandEnum.Loop: 9765 case (uint)ParcelMediaCommandEnum.Loop:
9167 loop = 1; 9766 loop = 1;
9168 commandToSend = command; 9767 commandToSend = command;
9169 update = true; //need to send the media update packet to set looping 9768 update = true; //need to send the media update packet to set looping
9170 break; 9769 break;
9171 9770
9172 case ParcelMediaCommandEnum.Play: 9771 case (uint)ParcelMediaCommandEnum.Play:
9173 loop = 0; 9772 loop = 0;
9174 commandToSend = command; 9773 commandToSend = command;
9175 update = true; //need to send the media update packet to make sure it doesn't loop 9774 update = true; //need to send the media update packet to make sure it doesn't loop
9176 break; 9775 break;
9177 9776
9178 case ParcelMediaCommandEnum.Pause: 9777 case (uint)ParcelMediaCommandEnum.Pause:
9179 case ParcelMediaCommandEnum.Stop: 9778 case (uint)ParcelMediaCommandEnum.Stop:
9180 case ParcelMediaCommandEnum.Unload: 9779 case (uint)ParcelMediaCommandEnum.Unload:
9181 commandToSend = command; 9780 commandToSend = command;
9182 break; 9781 break;
9183 9782
9184 case ParcelMediaCommandEnum.Url: 9783 case (uint)ParcelMediaCommandEnum.Url:
9185 if ((i + 1) < commandList.Length) 9784 if ((i + 1) < commandList.Length)
9186 { 9785 {
9187 if (commandList.Data[i + 1] is LSL_String) 9786 if (commandList.Data[i + 1] is LSL_String)
@@ -9194,7 +9793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9194 } 9793 }
9195 break; 9794 break;
9196 9795
9197 case ParcelMediaCommandEnum.Texture: 9796 case (uint)ParcelMediaCommandEnum.Texture:
9198 if ((i + 1) < commandList.Length) 9797 if ((i + 1) < commandList.Length)
9199 { 9798 {
9200 if (commandList.Data[i + 1] is LSL_String) 9799 if (commandList.Data[i + 1] is LSL_String)
@@ -9207,7 +9806,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9207 } 9806 }
9208 break; 9807 break;
9209 9808
9210 case ParcelMediaCommandEnum.Time: 9809 case (uint)ParcelMediaCommandEnum.Time:
9211 if ((i + 1) < commandList.Length) 9810 if ((i + 1) < commandList.Length)
9212 { 9811 {
9213 if (commandList.Data[i + 1] is LSL_Float) 9812 if (commandList.Data[i + 1] is LSL_Float)
@@ -9219,7 +9818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9219 } 9818 }
9220 break; 9819 break;
9221 9820
9222 case ParcelMediaCommandEnum.AutoAlign: 9821 case (uint)ParcelMediaCommandEnum.AutoAlign:
9223 if ((i + 1) < commandList.Length) 9822 if ((i + 1) < commandList.Length)
9224 { 9823 {
9225 if (commandList.Data[i + 1] is LSL_Integer) 9824 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9233,7 +9832,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9233 } 9832 }
9234 break; 9833 break;
9235 9834
9236 case ParcelMediaCommandEnum.Type: 9835 case (uint)ParcelMediaCommandEnum.Type:
9237 if ((i + 1) < commandList.Length) 9836 if ((i + 1) < commandList.Length)
9238 { 9837 {
9239 if (commandList.Data[i + 1] is LSL_String) 9838 if (commandList.Data[i + 1] is LSL_String)
@@ -9246,7 +9845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 } 9845 }
9247 break; 9846 break;
9248 9847
9249 case ParcelMediaCommandEnum.Desc: 9848 case (uint)ParcelMediaCommandEnum.Desc:
9250 if ((i + 1) < commandList.Length) 9849 if ((i + 1) < commandList.Length)
9251 { 9850 {
9252 if (commandList.Data[i + 1] is LSL_String) 9851 if (commandList.Data[i + 1] is LSL_String)
@@ -9259,7 +9858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9259 } 9858 }
9260 break; 9859 break;
9261 9860
9262 case ParcelMediaCommandEnum.Size: 9861 case (uint)ParcelMediaCommandEnum.Size:
9263 if ((i + 2) < commandList.Length) 9862 if ((i + 2) < commandList.Length)
9264 { 9863 {
9265 if (commandList.Data[i + 1] is LSL_Integer) 9864 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9329,7 +9928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9329 } 9928 }
9330 } 9929 }
9331 9930
9332 if (commandToSend != null) 9931 if (commandToSend != 0)
9333 { 9932 {
9334 // the commandList contained a start/stop/... command, too 9933 // the commandList contained a start/stop/... command, too
9335 if (presence == null) 9934 if (presence == null)
@@ -9366,7 +9965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9366 9965
9367 if (aList.Data[i] != null) 9966 if (aList.Data[i] != null)
9368 { 9967 {
9369 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9968 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9370 { 9969 {
9371 case ParcelMediaCommandEnum.Url: 9970 case ParcelMediaCommandEnum.Url:
9372 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9971 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9409,16 +10008,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9409 { 10008 {
9410 m_host.AddScriptLPS(1); 10009 m_host.AddScriptLPS(1);
9411 10010
9412 lock (m_host.TaskInventory) 10011 m_host.TaskInventory.LockItemsForRead(true);
10012 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9413 { 10013 {
9414 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10014 if (inv.Value.Name == name)
9415 { 10015 {
9416 if (inv.Value.Name == name) 10016 m_host.TaskInventory.LockItemsForRead(false);
9417 { 10017 return inv.Value.Type;
9418 return inv.Value.Type;
9419 }
9420 } 10018 }
9421 } 10019 }
10020 m_host.TaskInventory.LockItemsForRead(false);
9422 10021
9423 return -1; 10022 return -1;
9424 } 10023 }
@@ -9429,15 +10028,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9429 10028
9430 if (quick_pay_buttons.Data.Length < 4) 10029 if (quick_pay_buttons.Data.Length < 4)
9431 { 10030 {
9432 LSLError("List must have at least 4 elements"); 10031 int x;
9433 return; 10032 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10033 {
10034 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10035 }
9434 } 10036 }
9435 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10037 int[] nPrice = new int[5];
9436 10038 nPrice[0] = price;
9437 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10039 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9438 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10040 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9439 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10041 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9440 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10042 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10043 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9441 m_host.ParentGroup.HasGroupChanged = true; 10044 m_host.ParentGroup.HasGroupChanged = true;
9442 } 10045 }
9443 10046
@@ -9449,17 +10052,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9449 if (invItemID == UUID.Zero) 10052 if (invItemID == UUID.Zero)
9450 return new LSL_Vector(); 10053 return new LSL_Vector();
9451 10054
9452 lock (m_host.TaskInventory) 10055 m_host.TaskInventory.LockItemsForRead(true);
10056 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9453 { 10057 {
9454 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10058 m_host.TaskInventory.LockItemsForRead(false);
9455 return new LSL_Vector(); 10059 return new LSL_Vector();
10060 }
9456 10061
9457 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10062 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9458 { 10063 {
9459 ShoutError("No permissions to track the camera"); 10064 ShoutError("No permissions to track the camera");
9460 return new LSL_Vector(); 10065 m_host.TaskInventory.LockItemsForRead(false);
9461 } 10066 return new LSL_Vector();
9462 } 10067 }
10068 m_host.TaskInventory.LockItemsForRead(false);
9463 10069
9464 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10070 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9465 if (presence != null) 10071 if (presence != null)
@@ -9477,17 +10083,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 if (invItemID == UUID.Zero) 10083 if (invItemID == UUID.Zero)
9478 return new LSL_Rotation(); 10084 return new LSL_Rotation();
9479 10085
9480 lock (m_host.TaskInventory) 10086 m_host.TaskInventory.LockItemsForRead(true);
10087 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9481 { 10088 {
9482 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10089 m_host.TaskInventory.LockItemsForRead(false);
9483 return new LSL_Rotation(); 10090 return new LSL_Rotation();
9484
9485 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9486 {
9487 ShoutError("No permissions to track the camera");
9488 return new LSL_Rotation();
9489 }
9490 } 10091 }
10092 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10093 {
10094 ShoutError("No permissions to track the camera");
10095 m_host.TaskInventory.LockItemsForRead(false);
10096 return new LSL_Rotation();
10097 }
10098 m_host.TaskInventory.LockItemsForRead(false);
9491 10099
9492 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10100 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9493 if (presence != null) 10101 if (presence != null)
@@ -9549,8 +10157,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9549 { 10157 {
9550 m_host.AddScriptLPS(1); 10158 m_host.AddScriptLPS(1);
9551 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10159 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9552 if (detectedParams == null) return; // only works on the first detected avatar 10160 if (detectedParams == null)
9553 10161 {
10162 if (m_host.ParentGroup.IsAttachment == true)
10163 {
10164 detectedParams = new DetectParams();
10165 detectedParams.Key = m_host.OwnerID;
10166 }
10167 else
10168 {
10169 return;
10170 }
10171 }
10172
9554 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10173 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9555 if (avatar != null) 10174 if (avatar != null)
9556 { 10175 {
@@ -9558,6 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10177 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9559 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10178 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9560 } 10179 }
10180
9561 ScriptSleep(1000); 10181 ScriptSleep(1000);
9562 } 10182 }
9563 10183
@@ -9650,14 +10270,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9650 if (objectID == UUID.Zero) return; 10270 if (objectID == UUID.Zero) return;
9651 10271
9652 UUID agentID; 10272 UUID agentID;
9653 lock (m_host.TaskInventory) 10273 m_host.TaskInventory.LockItemsForRead(true);
9654 { 10274 // we need the permission first, to know which avatar we want to set the camera for
9655 // we need the permission first, to know which avatar we want to set the camera for 10275 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9656 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9657 10276
9658 if (agentID == UUID.Zero) return; 10277 if (agentID == UUID.Zero)
9659 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10278 {
10279 m_host.TaskInventory.LockItemsForRead(false);
10280 return;
10281 }
10282 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10283 {
10284 m_host.TaskInventory.LockItemsForRead(false);
10285 return;
9660 } 10286 }
10287 m_host.TaskInventory.LockItemsForRead(false);
9661 10288
9662 ScenePresence presence = World.GetScenePresence(agentID); 10289 ScenePresence presence = World.GetScenePresence(agentID);
9663 10290
@@ -9666,12 +10293,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9666 10293
9667 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10294 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9668 object[] data = rules.Data; 10295 object[] data = rules.Data;
9669 for (int i = 0; i < data.Length; ++i) { 10296 for (int i = 0; i < data.Length; ++i)
10297 {
9670 int type = Convert.ToInt32(data[i++].ToString()); 10298 int type = Convert.ToInt32(data[i++].ToString());
9671 if (i >= data.Length) break; // odd number of entries => ignore the last 10299 if (i >= data.Length) break; // odd number of entries => ignore the last
9672 10300
9673 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10301 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9674 switch (type) { 10302 switch (type)
10303 {
9675 case ScriptBaseClass.CAMERA_FOCUS: 10304 case ScriptBaseClass.CAMERA_FOCUS:
9676 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10305 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9677 case ScriptBaseClass.CAMERA_POSITION: 10306 case ScriptBaseClass.CAMERA_POSITION:
@@ -9707,12 +10336,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9707 10336
9708 // we need the permission first, to know which avatar we want to clear the camera for 10337 // we need the permission first, to know which avatar we want to clear the camera for
9709 UUID agentID; 10338 UUID agentID;
9710 lock (m_host.TaskInventory) 10339 m_host.TaskInventory.LockItemsForRead(true);
10340 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10341 if (agentID == UUID.Zero)
9711 { 10342 {
9712 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10343 m_host.TaskInventory.LockItemsForRead(false);
9713 if (agentID == UUID.Zero) return; 10344 return;
9714 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10345 }
10346 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10347 {
10348 m_host.TaskInventory.LockItemsForRead(false);
10349 return;
9715 } 10350 }
10351 m_host.TaskInventory.LockItemsForRead(false);
9716 10352
9717 ScenePresence presence = World.GetScenePresence(agentID); 10353 ScenePresence presence = World.GetScenePresence(agentID);
9718 10354
@@ -9779,19 +10415,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9779 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10415 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9780 { 10416 {
9781 m_host.AddScriptLPS(1); 10417 m_host.AddScriptLPS(1);
9782 string ret = String.Empty; 10418
9783 string src1 = llBase64ToString(str1); 10419 if (str1 == String.Empty)
9784 string src2 = llBase64ToString(str2); 10420 return String.Empty;
9785 int c = 0; 10421 if (str2 == String.Empty)
9786 for (int i = 0; i < src1.Length; i++) 10422 return str1;
10423
10424 int len = str2.Length;
10425 if ((len % 4) != 0) // LL is EVIL!!!!
9787 { 10426 {
9788 ret += (char) (src1[i] ^ src2[c]); 10427 while (str2.EndsWith("="))
10428 str2 = str2.Substring(0, str2.Length - 1);
10429
10430 len = str2.Length;
10431 int mod = len % 4;
10432
10433 if (mod == 1)
10434 str2 = str2.Substring(0, str2.Length - 1);
10435 else if (mod == 2)
10436 str2 += "==";
10437 else if (mod == 3)
10438 str2 += "=";
10439 }
9789 10440
9790 c++; 10441 byte[] data1;
9791 if (c >= src2.Length) 10442 byte[] data2;
9792 c = 0; 10443 try
10444 {
10445 data1 = Convert.FromBase64String(str1);
10446 data2 = Convert.FromBase64String(str2);
9793 } 10447 }
9794 return llStringToBase64(ret); 10448 catch (Exception)
10449 {
10450 return new LSL_String(String.Empty);
10451 }
10452
10453 byte[] d2 = new Byte[data1.Length];
10454 int pos = 0;
10455
10456 if (data1.Length <= data2.Length)
10457 {
10458 Array.Copy(data2, 0, d2, 0, data1.Length);
10459 }
10460 else
10461 {
10462 while (pos < data1.Length)
10463 {
10464 len = data1.Length - pos;
10465 if (len > data2.Length)
10466 len = data2.Length;
10467
10468 Array.Copy(data2, 0, d2, pos, len);
10469 pos += len;
10470 }
10471 }
10472
10473 for (pos = 0 ; pos < data1.Length ; pos++ )
10474 data1[pos] ^= d2[pos];
10475
10476 return Convert.ToBase64String(data1);
9795 } 10477 }
9796 10478
9797 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10479 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9850,12 +10532,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9850 Regex r = new Regex(authregex); 10532 Regex r = new Regex(authregex);
9851 int[] gnums = r.GetGroupNumbers(); 10533 int[] gnums = r.GetGroupNumbers();
9852 Match m = r.Match(url); 10534 Match m = r.Match(url);
9853 if (m.Success) { 10535 if (m.Success)
9854 for (int i = 1; i < gnums.Length; i++) { 10536 {
10537 for (int i = 1; i < gnums.Length; i++)
10538 {
9855 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10539 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9856 //CaptureCollection cc = g.Captures; 10540 //CaptureCollection cc = g.Captures;
9857 } 10541 }
9858 if (m.Groups.Count == 5) { 10542 if (m.Groups.Count == 5)
10543 {
9859 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10544 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9860 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10545 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9861 } 10546 }
@@ -10141,15 +10826,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10141 10826
10142 internal UUID ScriptByName(string name) 10827 internal UUID ScriptByName(string name)
10143 { 10828 {
10144 lock (m_host.TaskInventory) 10829 m_host.TaskInventory.LockItemsForRead(true);
10830
10831 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10145 { 10832 {
10146 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10833 if (item.Type == 10 && item.Name == name)
10147 { 10834 {
10148 if (item.Type == 10 && item.Name == name) 10835 m_host.TaskInventory.LockItemsForRead(false);
10149 return item.ItemID; 10836 return item.ItemID;
10150 } 10837 }
10151 } 10838 }
10152 10839
10840 m_host.TaskInventory.LockItemsForRead(false);
10841
10153 return UUID.Zero; 10842 return UUID.Zero;
10154 } 10843 }
10155 10844
@@ -10190,6 +10879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10190 { 10879 {
10191 m_host.AddScriptLPS(1); 10880 m_host.AddScriptLPS(1);
10192 10881
10882 //Clone is thread safe
10193 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10883 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10194 10884
10195 UUID assetID = UUID.Zero; 10885 UUID assetID = UUID.Zero;
@@ -10252,6 +10942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10252 { 10942 {
10253 m_host.AddScriptLPS(1); 10943 m_host.AddScriptLPS(1);
10254 10944
10945 //Clone is thread safe
10255 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10946 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10256 10947
10257 UUID assetID = UUID.Zero; 10948 UUID assetID = UUID.Zero;
@@ -10332,15 +11023,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10332 return GetLinkPrimitiveParams(obj, rules); 11023 return GetLinkPrimitiveParams(obj, rules);
10333 } 11024 }
10334 11025
10335 public void print(string str) 11026 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10336 { 11027 {
10337 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11028 List<SceneObjectPart> parts = GetLinkParts(link);
10338 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11029 if (parts.Count < 1)
10339 if (ossl != null) 11030 return 0;
10340 { 11031
10341 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11032 return GetNumberOfSides(parts[0]);
10342 m_log.Info("LSL print():" + str);
10343 }
10344 } 11033 }
10345 11034
10346 private string Name2Username(string name) 11035 private string Name2Username(string name)
@@ -10386,6 +11075,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10386 return rq.ToString(); 11075 return rq.ToString();
10387 } 11076 }
10388 11077
11078 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11079 {
11080 m_SayShoutCount = 0;
11081 }
10389 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11082 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10390 { 11083 {
10391 m_host.AddScriptLPS(1); 11084 m_host.AddScriptLPS(1);
@@ -10555,22 +11248,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10555 NotImplemented("llGetSPMaxMemory"); 11248 NotImplemented("llGetSPMaxMemory");
10556 } 11249 }
10557 11250
10558 public void llGetUsedMemory() 11251 public virtual LSL_Integer llGetUsedMemory()
10559 { 11252 {
10560 m_host.AddScriptLPS(1); 11253 m_host.AddScriptLPS(1);
10561 NotImplemented("llGetUsedMemory"); 11254 NotImplemented("llGetUsedMemory");
11255 return 0;
10562 } 11256 }
10563 11257
10564 public void llScriptProfiler(LSL_Integer flags) 11258 public void llScriptProfiler(LSL_Integer flags)
10565 { 11259 {
10566 m_host.AddScriptLPS(1); 11260 m_host.AddScriptLPS(1);
10567 NotImplemented("llScriptProfiler"); 11261 //NotImplemented("llScriptProfiler");
10568 } 11262 }
10569 11263
10570 public void llSetSoundQueueing(int queue) 11264 public void llSetSoundQueueing(int queue)
10571 { 11265 {
10572 m_host.AddScriptLPS(1); 11266 m_host.AddScriptLPS(1);
10573 NotImplemented("llSetSoundQueueing");
10574 } 11267 }
10575 11268
10576 public void llCollisionSprite(string impact_sprite) 11269 public void llCollisionSprite(string impact_sprite)
@@ -10582,7 +11275,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10582 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11275 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10583 { 11276 {
10584 m_host.AddScriptLPS(1); 11277 m_host.AddScriptLPS(1);
10585 NotImplemented("llGodLikeRezObject"); 11278
11279 if (!World.Permissions.IsGod(m_host.OwnerID))
11280 NotImplemented("llGodLikeRezObject");
11281
11282 AssetBase rezAsset = World.AssetService.Get(inventory);
11283 if (rezAsset == null)
11284 {
11285 llSay(0, "Asset not found");
11286 return;
11287 }
11288
11289 SceneObjectGroup group = null;
11290
11291 try
11292 {
11293 string xmlData = Utils.BytesToString(rezAsset.Data);
11294 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11295 }
11296 catch
11297 {
11298 llSay(0, "Asset not found");
11299 return;
11300 }
11301
11302 if (group == null)
11303 {
11304 llSay(0, "Asset not found");
11305 return;
11306 }
11307
11308 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11309 group.RootPart.AttachOffset = group.AbsolutePosition;
11310
11311 group.ResetIDs();
11312
11313 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11314 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11315 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11316 group.ScheduleGroupForFullUpdate();
11317
11318 // objects rezzed with this method are die_at_edge by default.
11319 group.RootPart.SetDieAtEdge(true);
11320
11321 group.ResumeScripts();
11322
11323 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11324 "object_rez", new Object[] {
11325 new LSL_String(
11326 group.RootPart.UUID.ToString()) },
11327 new DetectParams[0]));
10586 } 11328 }
10587 11329
10588 #endregion 11330 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index e1c837e..8f450f8 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);
@@ -1834,6 +1841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1834 1841
1835 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1842 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1836 { 1843 {
1844 m_host.TaskInventory.LockItemsForRead(true);
1837 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1838 { 1846 {
1839 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1847 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1841,6 +1849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 assetID = item.AssetID; 1849 assetID = item.AssetID;
1842 } 1850 }
1843 } 1851 }
1852 m_host.TaskInventory.LockItemsForRead(false);
1844 } 1853 }
1845 1854
1846 if (assetID == UUID.Zero) 1855 if (assetID == UUID.Zero)
@@ -2164,8 +2173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2164 UUID x = module.CreateNPC(firstname, 2173 UUID x = module.CreateNPC(firstname,
2165 lastname, 2174 lastname,
2166 new Vector3((float) position.x, (float) position.y, (float) position.z), 2175 new Vector3((float) position.x, (float) position.y, (float) position.z),
2167 World, 2176 World,appearance);
2168 appearance);
2169 2177
2170 return new LSL_Key(x.ToString()); 2178 return new LSL_Key(x.ToString());
2171 } 2179 }
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 87cfe1a..5ddba60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index e82c281..59eaccb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 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 6e9f3ec..cf25189 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 156fd57..975e9cc 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -269,43 +337,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
269 337
270 public void RemoveRegion(Scene scene) 338 public void RemoveRegion(Scene scene)
271 { 339 {
272 lock (m_Scripts) 340 lockScriptsForRead(true);
341 foreach (IScriptInstance instance in m_Scripts.Values)
273 { 342 {
274 foreach (IScriptInstance instance in m_Scripts.Values) 343 // Force a final state save
344 //
345 if (m_Assemblies.ContainsKey(instance.AssetID))
275 { 346 {
276 // Force a final state save 347 string assembly = m_Assemblies[instance.AssetID];
277 // 348 instance.SaveState(assembly);
278 if (m_Assemblies.ContainsKey(instance.AssetID)) 349 }
279 {
280 string assembly = m_Assemblies[instance.AssetID];
281 instance.SaveState(assembly);
282 }
283 350
284 // Clear the event queue and abort the instance thread 351 // Clear the event queue and abort the instance thread
285 // 352 //
286 instance.ClearQueue(); 353 instance.ClearQueue();
287 instance.Stop(0); 354 instance.Stop(0);
288 355
289 // Release events, timer, etc 356 // Release events, timer, etc
290 // 357 //
291 instance.DestroyScriptInstance(); 358 instance.DestroyScriptInstance();
292 359
293 // Unload scripts and app domains 360 // Unload scripts and app domains
294 // Must be done explicitly because they have infinite 361 // Must be done explicitly because they have infinite
295 // lifetime 362 // lifetime
296 // 363 //
297 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 364 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
298 if (m_DomainScripts[instance.AppDomain].Count == 0) 365 if (m_DomainScripts[instance.AppDomain].Count == 0)
299 { 366 {
300 m_DomainScripts.Remove(instance.AppDomain); 367 m_DomainScripts.Remove(instance.AppDomain);
301 UnloadAppDomain(instance.AppDomain); 368 UnloadAppDomain(instance.AppDomain);
302 }
303 } 369 }
304 m_Scripts.Clear();
305 m_PrimObjects.Clear();
306 m_Assemblies.Clear();
307 m_DomainScripts.Clear();
308 } 370 }
371 lockScriptsForRead(false);
372 lockScriptsForWrite(true);
373 m_Scripts.Clear();
374 lockScriptsForWrite(false);
375 m_PrimObjects.Clear();
376 m_Assemblies.Clear();
377 m_DomainScripts.Clear();
378
309 lock (m_ScriptEngines) 379 lock (m_ScriptEngines)
310 { 380 {
311 m_ScriptEngines.Remove(this); 381 m_ScriptEngines.Remove(this);
@@ -367,22 +437,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
367 437
368 List<IScriptInstance> instances = new List<IScriptInstance>(); 438 List<IScriptInstance> instances = new List<IScriptInstance>();
369 439
370 lock (m_Scripts) 440 lockScriptsForRead(true);
371 { 441 foreach (IScriptInstance instance in m_Scripts.Values)
372 foreach (IScriptInstance instance in m_Scripts.Values)
373 instances.Add(instance); 442 instances.Add(instance);
374 } 443 lockScriptsForRead(false);
375 444
376 foreach (IScriptInstance i in instances) 445 foreach (IScriptInstance i in instances)
377 { 446 {
378 string assembly = String.Empty; 447 string assembly = String.Empty;
379 448
380 lock (m_Scripts) 449
381 {
382 if (!m_Assemblies.ContainsKey(i.AssetID)) 450 if (!m_Assemblies.ContainsKey(i.AssetID))
383 continue; 451 continue;
384 assembly = m_Assemblies[i.AssetID]; 452 assembly = m_Assemblies[i.AssetID];
385 } 453
386 454
387 i.SaveState(assembly); 455 i.SaveState(assembly);
388 } 456 }
@@ -716,92 +784,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
716 } 784 }
717 785
718 ScriptInstance instance = null; 786 ScriptInstance instance = null;
719 lock (m_Scripts) 787 // Create the object record
788 lockScriptsForRead(true);
789 if ((!m_Scripts.ContainsKey(itemID)) ||
790 (m_Scripts[itemID].AssetID != assetID))
720 { 791 {
721 // Create the object record 792 lockScriptsForRead(false);
722 793
723 if ((!m_Scripts.ContainsKey(itemID)) || 794 UUID appDomain = assetID;
724 (m_Scripts[itemID].AssetID != assetID))
725 {
726 UUID appDomain = assetID;
727 795
728 if (part.ParentGroup.IsAttachment) 796 if (part.ParentGroup.IsAttachment)
729 appDomain = part.ParentGroup.RootPart.UUID; 797 appDomain = part.ParentGroup.RootPart.UUID;
730 798
731 if (!m_AppDomains.ContainsKey(appDomain)) 799 if (!m_AppDomains.ContainsKey(appDomain))
800 {
801 try
732 { 802 {
733 try 803 AppDomainSetup appSetup = new AppDomainSetup();
734 { 804 appSetup.PrivateBinPath = Path.Combine(
735 AppDomainSetup appSetup = new AppDomainSetup(); 805 m_ScriptEnginesPath,
736 appSetup.PrivateBinPath = Path.Combine( 806 m_Scene.RegionInfo.RegionID.ToString());
737 m_ScriptEnginesPath, 807
738 m_Scene.RegionInfo.RegionID.ToString()); 808 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
739 809 Evidence evidence = new Evidence(baseEvidence);
740 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 810
741 Evidence evidence = new Evidence(baseEvidence); 811 AppDomain sandbox;
742 812 if (m_AppDomainLoading)
743 AppDomain sandbox; 813 sandbox = AppDomain.CreateDomain(
744 if (m_AppDomainLoading) 814 m_Scene.RegionInfo.RegionID.ToString(),
745 sandbox = AppDomain.CreateDomain( 815 evidence, appSetup);
746 m_Scene.RegionInfo.RegionID.ToString(), 816 else
747 evidence, appSetup); 817 sandbox = AppDomain.CurrentDomain;
748 else 818
749 sandbox = AppDomain.CurrentDomain; 819 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
750 820 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
751 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 821 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
752 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 822 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
753 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 823 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
754 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 824 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
755 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 825 //sandbox.SetAppDomainPolicy(sandboxPolicy);
756 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 826
757 //sandbox.SetAppDomainPolicy(sandboxPolicy); 827 m_AppDomains[appDomain] = sandbox;
758 828
759 m_AppDomains[appDomain] = sandbox; 829 m_AppDomains[appDomain].AssemblyResolve +=
760 830 new ResolveEventHandler(
761 m_AppDomains[appDomain].AssemblyResolve += 831 AssemblyResolver.OnAssemblyResolve);
762 new ResolveEventHandler( 832 m_DomainScripts[appDomain] = new List<UUID>();
763 AssemblyResolver.OnAssemblyResolve); 833 }
764 m_DomainScripts[appDomain] = new List<UUID>(); 834 catch (Exception e)
765 } 835 {
766 catch (Exception e) 836 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
837 m_ScriptErrorMessage += "Exception creating app domain:\n";
838 m_ScriptFailCount++;
839 lock (m_AddingAssemblies)
767 { 840 {
768 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 841 m_AddingAssemblies[assembly]--;
769 m_ScriptErrorMessage += "Exception creating app domain:\n";
770 m_ScriptFailCount++;
771 lock (m_AddingAssemblies)
772 {
773 m_AddingAssemblies[assembly]--;
774 }
775 return false;
776 } 842 }
843 return false;
777 } 844 }
778 m_DomainScripts[appDomain].Add(itemID); 845 }
779 846 m_DomainScripts[appDomain].Add(itemID);
780 instance = new ScriptInstance(this, part, 847
781 itemID, assetID, assembly, 848 instance = new ScriptInstance(this, part,
782 m_AppDomains[appDomain], 849 itemID, assetID, assembly,
783 part.ParentGroup.RootPart.Name, 850 m_AppDomains[appDomain],
784 item.Name, startParam, postOnRez, 851 part.ParentGroup.RootPart.Name,
785 stateSource, m_MaxScriptQueue); 852 item.Name, startParam, postOnRez,
786 853 stateSource, m_MaxScriptQueue);
787 m_log.DebugFormat( 854
855 m_log.DebugFormat(
788 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 856 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
789 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 857 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
790 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 858 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
791 859
792 if (presence != null) 860 if (presence != null)
793 { 861 {
794 ShowScriptSaveResponse(item.OwnerID, 862 ShowScriptSaveResponse(item.OwnerID,
795 assetID, "Compile successful", true); 863 assetID, "Compile successful", true);
796 }
797
798 instance.AppDomain = appDomain;
799 instance.LineMap = linemap;
800
801 m_Scripts[itemID] = instance;
802 } 864 }
803 }
804 865
866 instance.AppDomain = appDomain;
867 instance.LineMap = linemap;
868 lockScriptsForWrite(true);
869 m_Scripts[itemID] = instance;
870 lockScriptsForWrite(false);
871 }
872 else
873 {
874 lockScriptsForRead(false);
875 }
805 lock (m_PrimObjects) 876 lock (m_PrimObjects)
806 { 877 {
807 if (!m_PrimObjects.ContainsKey(localID)) 878 if (!m_PrimObjects.ContainsKey(localID))
@@ -820,9 +891,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
820 m_AddingAssemblies[assembly]--; 891 m_AddingAssemblies[assembly]--;
821 } 892 }
822 893
823 if (instance != null) 894 if (instance!=null)
824 instance.Init(); 895 instance.Init();
825 896
826 return true; 897 return true;
827 } 898 }
828 899
@@ -835,20 +906,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
835 m_CompileDict.Remove(itemID); 906 m_CompileDict.Remove(itemID);
836 } 907 }
837 908
838 IScriptInstance instance = null; 909 lockScriptsForRead(true);
839 910 // Do we even have it?
840 lock (m_Scripts) 911 if (!m_Scripts.ContainsKey(itemID))
841 { 912 {
842 // Do we even have it? 913 lockScriptsForRead(false);
843 if (!m_Scripts.ContainsKey(itemID)) 914 return;
844 return;
845
846 instance=m_Scripts[itemID];
847 m_Scripts.Remove(itemID);
848 } 915 }
916
849 917
918 IScriptInstance instance=m_Scripts[itemID];
919 lockScriptsForRead(false);
920 lockScriptsForWrite(true);
921 m_Scripts.Remove(itemID);
922 lockScriptsForWrite(false);
850 instance.ClearQueue(); 923 instance.ClearQueue();
851 instance.Stop(0); 924 instance.Stop(0);
925
852// bool objectRemoved = false; 926// bool objectRemoved = false;
853 927
854 lock (m_PrimObjects) 928 lock (m_PrimObjects)
@@ -884,11 +958,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
884 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 958 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
885 if (handlerObjectRemoved != null) 959 if (handlerObjectRemoved != null)
886 { 960 {
887 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 961 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
888 handlerObjectRemoved(part.UUID); 962 handlerObjectRemoved(part.UUID);
889 } 963 }
890 964
891 965 CleanAssemblies();
966
892 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 967 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
893 if (handlerScriptRemoved != null) 968 if (handlerScriptRemoved != null)
894 handlerScriptRemoved(itemID); 969 handlerScriptRemoved(itemID);
@@ -1030,7 +1105,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1030 return false; 1105 return false;
1031 1106
1032 uuids = m_PrimObjects[localID]; 1107 uuids = m_PrimObjects[localID];
1033 } 1108
1034 1109
1035 foreach (UUID itemID in uuids) 1110 foreach (UUID itemID in uuids)
1036 { 1111 {
@@ -1048,6 +1123,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1048 result = true; 1123 result = true;
1049 } 1124 }
1050 } 1125 }
1126 }
1051 1127
1052 return result; 1128 return result;
1053 } 1129 }
@@ -1147,12 +1223,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1147 private IScriptInstance GetInstance(UUID itemID) 1223 private IScriptInstance GetInstance(UUID itemID)
1148 { 1224 {
1149 IScriptInstance instance; 1225 IScriptInstance instance;
1150 lock (m_Scripts) 1226 lockScriptsForRead(true);
1227 if (!m_Scripts.ContainsKey(itemID))
1151 { 1228 {
1152 if (!m_Scripts.ContainsKey(itemID)) 1229 lockScriptsForRead(false);
1153 return null; 1230 return null;
1154 instance = m_Scripts[itemID];
1155 } 1231 }
1232 instance = m_Scripts[itemID];
1233 lockScriptsForRead(false);
1156 return instance; 1234 return instance;
1157 } 1235 }
1158 1236
@@ -1176,6 +1254,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1176 return false; 1254 return false;
1177 } 1255 }
1178 1256
1257 [DebuggerNonUserCode]
1179 public void ApiResetScript(UUID itemID) 1258 public void ApiResetScript(UUID itemID)
1180 { 1259 {
1181 IScriptInstance instance = GetInstance(itemID); 1260 IScriptInstance instance = GetInstance(itemID);
@@ -1227,6 +1306,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1227 return UUID.Zero; 1306 return UUID.Zero;
1228 } 1307 }
1229 1308
1309 [DebuggerNonUserCode]
1230 public void SetState(UUID itemID, string newState) 1310 public void SetState(UUID itemID, string newState)
1231 { 1311 {
1232 IScriptInstance instance = GetInstance(itemID); 1312 IScriptInstance instance = GetInstance(itemID);
@@ -1247,11 +1327,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1247 { 1327 {
1248 List<IScriptInstance> instances = new List<IScriptInstance>(); 1328 List<IScriptInstance> instances = new List<IScriptInstance>();
1249 1329
1250 lock (m_Scripts) 1330 lockScriptsForRead(true);
1251 { 1331 foreach (IScriptInstance instance in m_Scripts.Values)
1252 foreach (IScriptInstance instance in m_Scripts.Values)
1253 instances.Add(instance); 1332 instances.Add(instance);
1254 } 1333 lockScriptsForRead(false);
1255 1334
1256 foreach (IScriptInstance i in instances) 1335 foreach (IScriptInstance i in instances)
1257 { 1336 {
@@ -1632,5 +1711,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1632 1711
1633 instance.Resume(); 1712 instance.Resume();
1634 } 1713 }
1714
1715 public bool HasScript(UUID itemID, out bool running)
1716 {
1717 running = true;
1718
1719 IScriptInstance instance = GetInstance(itemID);
1720 if (instance == null)
1721 return false;
1722
1723 running = instance.Running;
1724 return true;
1725 }
1635 } 1726 }
1636} 1727}