aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-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.cs2227
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs90
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
18 files changed, 1885 insertions, 856 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 a51a88b..652fa7e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -275,40 +344,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
275 protected UUID InventorySelf() 344 protected UUID InventorySelf()
276 { 345 {
277 UUID invItemID = new UUID(); 346 UUID invItemID = new UUID();
278 347 bool unlock = false;
279 lock (m_host.TaskInventory) 348 if (!m_host.TaskInventory.IsReadLockedByMe())
349 {
350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
280 { 354 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
282 { 356 {
283 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 357 invItemID = inv.Key;
284 { 358 break;
285 invItemID = inv.Key;
286 break;
287 }
288 } 359 }
289 } 360 }
290 361 if (unlock)
362 {
363 m_host.TaskInventory.LockItemsForRead(false);
364 }
291 return invItemID; 365 return invItemID;
292 } 366 }
293 367
294 protected UUID InventoryKey(string name, int type) 368 protected UUID InventoryKey(string name, int type)
295 { 369 {
296 m_host.AddScriptLPS(1); 370 m_host.AddScriptLPS(1);
297 371 m_host.TaskInventory.LockItemsForRead(true);
298 lock (m_host.TaskInventory) 372
373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
299 { 374 {
300 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 375 if (inv.Value.Name == name)
301 { 376 {
302 if (inv.Value.Name == name) 377 m_host.TaskInventory.LockItemsForRead(false);
378
379 if (inv.Value.Type != type)
303 { 380 {
304 if (inv.Value.Type != type) 381 return UUID.Zero;
305 return UUID.Zero;
306
307 return inv.Value.AssetID;
308 } 382 }
383
384 return inv.Value.AssetID;
309 } 385 }
310 } 386 }
311 387
388 m_host.TaskInventory.LockItemsForRead(false);
312 return UUID.Zero; 389 return UUID.Zero;
313 } 390 }
314 391
@@ -316,17 +393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 { 393 {
317 m_host.AddScriptLPS(1); 394 m_host.AddScriptLPS(1);
318 395
319 lock (m_host.TaskInventory) 396
397 m_host.TaskInventory.LockItemsForRead(true);
398
399 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
320 { 400 {
321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 401 if (inv.Value.Name == name)
322 { 402 {
323 if (inv.Value.Name == name) 403 m_host.TaskInventory.LockItemsForRead(false);
324 { 404 return inv.Value.AssetID;
325 return inv.Value.AssetID;
326 }
327 } 405 }
328 } 406 }
329 407
408 m_host.TaskInventory.LockItemsForRead(false);
409
410
330 return UUID.Zero; 411 return UUID.Zero;
331 } 412 }
332 413
@@ -468,26 +549,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 549
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 550 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 551
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 552 // Utility function for llRot2Euler
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 553
554 // normalize an angle between -PI and PI (-180 to +180 degrees)
555 protected double NormalizeAngle(double angle)
556 {
557 if (angle > -Math.PI && angle < Math.PI)
558 return angle;
559
560 int numPis = (int)(Math.PI / angle);
561 double remainder = angle - Math.PI * numPis;
562 if (numPis % 2 == 1)
563 return Math.PI - angle;
564 return remainder;
565 }
473 566
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
475 { 568 {
476 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
479 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
480 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
481 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
482 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
483 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 577 double test = q1.x*q1.z + q1.y*q1.s;
485 Math.Atan2(n, Math.Sqrt(p)), 578 if (test > 0.4999*unit) { // singularity at north pole
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
487 else if (n > 0) 580 eul.y = Math.PI/2;
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 581 eul.x = 0;
489 else 582 return eul;
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
491 } 594 }
492 595
493 /* From wiki: 596 /* From wiki:
@@ -689,77 +792,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 792 {
690 //A and B should both be normalized 793 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 794 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 795 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 796 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 797
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 798 double dotProduct = LSL_Vector.Dot(a, b);
799 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
800 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
801 double angle = Math.Acos(dotProduct / magProduct);
802 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
803 double s = Math.Sin(angle / 2);
804
805 double x = axis.x * s;
806 double y = axis.y * s;
807 double z = axis.z * s;
808 double w = Math.Cos(angle / 2);
809
810 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812
813 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
814 */
815
816 // This method mimics the 180 errors found in SL
817 // See www.euclideanspace.com... angleBetween
818 LSL_Vector vec_a = a;
819 LSL_Vector vec_b = b;
820
821 // Eliminate zero length
822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
824 if (vec_a_mag < 0.00001 ||
825 vec_b_mag < 0.00001)
696 { 826 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 828 }
699 else 829
830 // Normalize
831 vec_a = llVecNorm(vec_a);
832 vec_b = llVecNorm(vec_b);
833
834 // Calculate axis and rotation angle
835 LSL_Vector axis = vec_a % vec_b;
836 LSL_Float cos_theta = vec_a * vec_b;
837
838 // Check if parallel
839 if (cos_theta > 0.99999)
700 { 840 {
701 a = LSL_Vector.Norm(a); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 842 }
703 double dotProduct = LSL_Vector.Dot(a, b); 843
704 // There are two degenerate cases possible. These are for vectors 180 or 844 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 845 else if (cos_theta < -0.99999)
706 // 846 {
707 // Check for vectors 180 degrees apart. 847 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 850 }
711 // First assume X axis is orthogonal to the vectors. 851 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 852 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 853 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 854 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 855 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 856 s = Math.Cos(theta);
717 { 857 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 858 x = axis.x * t;
719 } 859 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 860 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 861 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 862 }
760 return rotBetween;
761 } 863 }
762 864
763 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
764 { 866 {
765 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -779,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 881 {
780 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
781 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 891 {
784 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -801,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 909 {
802 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
803 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
804 if (text.Length > 1023) 918 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
806 920
@@ -1101,10 +1215,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1215 return detectedParams.TouchUV;
1102 } 1216 }
1103 1217
1218 [DebuggerNonUserCode]
1104 public virtual void llDie() 1219 public virtual void llDie()
1105 { 1220 {
1106 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1223 }
1109 1224
1110 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1292
1178 public void llSetStatus(int status, int value) 1293 public void llSetStatus(int status, int value)
1179 { 1294 {
1295 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1296 return;
1180 m_host.AddScriptLPS(1); 1297 m_host.AddScriptLPS(1);
1181 1298
1182 int statusrotationaxis = 0; 1299 int statusrotationaxis = 0;
@@ -1406,6 +1523,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1523 {
1407 m_host.AddScriptLPS(1); 1524 m_host.AddScriptLPS(1);
1408 1525
1526 SetColor(m_host, color, face);
1527 }
1528
1529 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1530 {
1531 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1532 return;
1533
1534 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part))
1537 {
1538 texcolor = tex.CreateFace((uint)face).RGBA;
1539 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1542 tex.FaceTextures[face].RGBA = texcolor;
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546 else if (face == ScriptBaseClass.ALL_SIDES)
1547 {
1548 for (uint i = 0; i < GetNumberOfSides(part); i++)
1549 {
1550 if (tex.FaceTextures[i] != null)
1551 {
1552 texcolor = tex.FaceTextures[i].RGBA;
1553 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1554 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1555 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1556 tex.FaceTextures[i].RGBA = texcolor;
1557 }
1558 texcolor = tex.DefaultTexture.RGBA;
1559 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1560 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1562 tex.DefaultTexture.RGBA = texcolor;
1563 }
1564 part.UpdateTexture(tex);
1565 return;
1566 }
1567
1409 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1411 1570
@@ -1414,6 +1573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1573
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1574 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1575 {
1576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1577 return;
1578
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1579 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1580 MappingType textype;
1419 textype = MappingType.Default; 1581 textype = MappingType.Default;
@@ -1444,6 +1606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1606
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1607 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1608 {
1609 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1610 return;
1611
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1612 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1613 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1614 {
@@ -1469,6 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1634
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1635 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1636 {
1637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1638 return;
1472 1639
1473 Shininess sval = new Shininess(); 1640 Shininess sval = new Shininess();
1474 1641
@@ -1519,6 +1686,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1686
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1687 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1688 {
1689 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1690 return;
1691
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1692 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1693 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1694 {
@@ -1579,13 +1749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1580 1750
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1752 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1753 {
1584 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1585 } 1765 }
1586 1766
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1773 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1640 { 1823 {
1641 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1825 return;
1643 1826
1644 if (flexi) 1827 if (flexi)
@@ -1673,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1673 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1674 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1675 { 1858 {
1676 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return; 1860 return;
1678 1861
1679 if (light) 1862 if (light)
@@ -1750,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1751 1934
1752 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1753 1936 if (parts.Count > 0)
1754 foreach (SceneObjectPart part in parts) 1937 {
1755 SetTexture(part, texture, face); 1938 try
1756 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1757 ScriptSleep(200); 1949 ScriptSleep(200);
1758 } 1950 }
1759 1951
1760 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1761 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1762 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1763 1958
1764 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1803,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1998
1804 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1805 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1806 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1807 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1808 { 2006 {
@@ -1839,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1839 2037
1840 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1841 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1842 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1843 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1844 { 2045 {
@@ -1875,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 2076
1876 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1877 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1878 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1879 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1880 { 2084 {
@@ -1981,24 +2185,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1981 2185
1982 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2186 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1983 { 2187 {
1984 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2188 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1985 LSL_Vector currentPos = GetPartLocalPos(part); 2189 return;
1986 2190
1987 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2191 LSL_Vector currentPos = GetPartLocalPos(part);
1988 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2192 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1989 2193
1990 if (part.ParentGroup.RootPart == part) 2194 if (part.ParentGroup.RootPart == part)
1991 { 2195 {
1992 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1993 targetPos.z = ground;
1994 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
1995 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2197 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1996 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1997 } 2198 }
1998 else 2199 else
1999 { 2200 {
2000 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2201 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2001 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2002 SceneObjectGroup parent = part.ParentGroup; 2202 SceneObjectGroup parent = part.ParentGroup;
2003 parent.HasGroupChanged = true; 2203 parent.HasGroupChanged = true;
2004 parent.ScheduleGroupForTerseUpdate(); 2204 parent.ScheduleGroupForTerseUpdate();
@@ -2049,9 +2249,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2049 m_host.AddScriptLPS(1); 2249 m_host.AddScriptLPS(1);
2050 2250
2051 // try to let this work as in SL... 2251 // try to let this work as in SL...
2052 if (m_host.ParentID == 0) 2252 if (m_host.LinkNum < 2)
2053 { 2253 {
2054 // special case: If we are root, rotate complete SOG to new rotation 2254 // Special case: If we are root, rotate complete SOG to new
2255 // rotation.
2256 // We are root if the link number is 0 (single prim) or 1
2257 // (root prim). ParentID may be nonzero in attachments and
2258 // using it would cause attachments and HUDs to rotate
2259 // to the wrong positions.
2055 SetRot(m_host, Rot2Quaternion(rot)); 2260 SetRot(m_host, Rot2Quaternion(rot));
2056 } 2261 }
2057 else 2262 else
@@ -2076,6 +2281,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2076 2281
2077 protected void SetRot(SceneObjectPart part, Quaternion rot) 2282 protected void SetRot(SceneObjectPart part, Quaternion rot)
2078 { 2283 {
2284 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2285 return;
2286
2079 part.UpdateRotation(rot); 2287 part.UpdateRotation(rot);
2080 // Update rotation does not move the object in the physics scene if it's a linkset. 2288 // Update rotation does not move the object in the physics scene if it's a linkset.
2081 2289
@@ -2699,12 +2907,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2699 2907
2700 m_host.AddScriptLPS(1); 2908 m_host.AddScriptLPS(1);
2701 2909
2910 m_host.TaskInventory.LockItemsForRead(true);
2702 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2911 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2703 2912 m_host.TaskInventory.LockItemsForRead(false);
2704 lock (m_host.TaskInventory)
2705 {
2706 item = m_host.TaskInventory[invItemID];
2707 }
2708 2913
2709 if (item.PermsGranter == UUID.Zero) 2914 if (item.PermsGranter == UUID.Zero)
2710 return 0; 2915 return 0;
@@ -2779,6 +2984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2779 if (dist > m_ScriptDistanceFactor * 10.0f) 2984 if (dist > m_ScriptDistanceFactor * 10.0f)
2780 return; 2985 return;
2781 2986
2987 //Clone is thread-safe
2782 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2988 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2783 2989
2784 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2990 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2839,6 +3045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 3045
2840 public void llLookAt(LSL_Vector target, double strength, double damping) 3046 public void llLookAt(LSL_Vector target, double strength, double damping)
2841 { 3047 {
3048 /*
2842 m_host.AddScriptLPS(1); 3049 m_host.AddScriptLPS(1);
2843 // Determine where we are looking from 3050 // Determine where we are looking from
2844 LSL_Vector from = llGetPos(); 3051 LSL_Vector from = llGetPos();
@@ -2858,10 +3065,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 // the angles of rotation in radians into rotation value 3065 // the angles of rotation in radians into rotation value
2859 3066
2860 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3067 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2861 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3068
2862 m_host.startLookAt(rotation, (float)damping, (float)strength); 3069 // This would only work if your physics system contains an APID controller:
3070 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3071 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3072
2863 // Orient the object to the angle calculated 3073 // Orient the object to the angle calculated
2864 //llSetRot(rot); 3074 llSetRot(rot);
3075 */
3076
3077 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3078 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3079 // http://bugs.meta7.com/view.php?id=28
3080 // - Tom
3081
3082 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3083 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3084 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3085 */
3086 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3087 {
3088 // Part is non-phys, convert this to a llSetRot()
3089 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3090 Vector3 dir = tgt - m_host.GroupPosition;
3091 dir.Normalize();
3092 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3093 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3094 float terot = (float)Math.Atan2(-dir.Z, txy);
3095 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3096 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3097 LSL_Types.Quaternion spin = llEuler2Rot(az);
3098 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3099 llSetRot(rot);
3100 }
3101 else
3102 {
3103 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3104 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3105 m_host.RotLookAt(q, (float)strength, (float)damping);
3106 }
3107
3108 }
3109
3110 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3111 {
3112 m_host.AddScriptLPS(1);
3113// NotImplemented("llRotLookAt");
3114 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3115
2865 } 3116 }
2866 3117
2867 public void llStopLookAt() 3118 public void llStopLookAt()
@@ -2910,13 +3161,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2910 { 3161 {
2911 TaskInventoryItem item; 3162 TaskInventoryItem item;
2912 3163
2913 lock (m_host.TaskInventory) 3164 m_host.TaskInventory.LockItemsForRead(true);
3165 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2914 { 3166 {
2915 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3167 m_host.TaskInventory.LockItemsForRead(false);
2916 return; 3168 return;
2917 else
2918 item = m_host.TaskInventory[InventorySelf()];
2919 } 3169 }
3170 else
3171 {
3172 item = m_host.TaskInventory[InventorySelf()];
3173 }
3174 m_host.TaskInventory.LockItemsForRead(false);
2920 3175
2921 if (item.PermsGranter != UUID.Zero) 3176 if (item.PermsGranter != UUID.Zero)
2922 { 3177 {
@@ -2938,13 +3193,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 { 3193 {
2939 TaskInventoryItem item; 3194 TaskInventoryItem item;
2940 3195
3196 m_host.TaskInventory.LockItemsForRead(true);
2941 lock (m_host.TaskInventory) 3197 lock (m_host.TaskInventory)
2942 { 3198 {
3199
2943 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3200 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3201 {
3202 m_host.TaskInventory.LockItemsForRead(false);
2944 return; 3203 return;
3204 }
2945 else 3205 else
3206 {
2946 item = m_host.TaskInventory[InventorySelf()]; 3207 item = m_host.TaskInventory[InventorySelf()];
3208 }
2947 } 3209 }
3210 m_host.TaskInventory.LockItemsForRead(false);
2948 3211
2949 m_host.AddScriptLPS(1); 3212 m_host.AddScriptLPS(1);
2950 3213
@@ -2976,18 +3239,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 { 3239 {
2977 m_host.AddScriptLPS(1); 3240 m_host.AddScriptLPS(1);
2978 3241
2979// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2980// return;
2981
2982 TaskInventoryItem item; 3242 TaskInventoryItem item;
2983 3243
2984 lock (m_host.TaskInventory) 3244 m_host.TaskInventory.LockItemsForRead(true);
3245
3246 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2985 { 3247 {
2986 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3248 m_host.TaskInventory.LockItemsForRead(false);
2987 return; 3249 return;
2988 else
2989 item = m_host.TaskInventory[InventorySelf()];
2990 } 3250 }
3251 else
3252 {
3253 item = m_host.TaskInventory[InventorySelf()];
3254 }
3255
3256 m_host.TaskInventory.LockItemsForRead(false);
2991 3257
2992 if (item.PermsGranter != m_host.OwnerID) 3258 if (item.PermsGranter != m_host.OwnerID)
2993 return; 3259 return;
@@ -3013,13 +3279,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 3279
3014 TaskInventoryItem item; 3280 TaskInventoryItem item;
3015 3281
3016 lock (m_host.TaskInventory) 3282 m_host.TaskInventory.LockItemsForRead(true);
3283
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3017 { 3285 {
3018 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3286 m_host.TaskInventory.LockItemsForRead(false);
3019 return; 3287 return;
3020 else
3021 item = m_host.TaskInventory[InventorySelf()];
3022 } 3288 }
3289 else
3290 {
3291 item = m_host.TaskInventory[InventorySelf()];
3292 }
3293 m_host.TaskInventory.LockItemsForRead(false);
3294
3023 3295
3024 if (item.PermsGranter != m_host.OwnerID) 3296 if (item.PermsGranter != m_host.OwnerID)
3025 return; 3297 return;
@@ -3066,6 +3338,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3066 3338
3067 public void llInstantMessage(string user, string message) 3339 public void llInstantMessage(string user, string message)
3068 { 3340 {
3341 UUID result;
3342 if (!UUID.TryParse(user, out result))
3343 {
3344 ShoutError("An invalid key was passed to llInstantMessage");
3345 ScriptSleep(2000);
3346 return;
3347 }
3348
3349
3069 m_host.AddScriptLPS(1); 3350 m_host.AddScriptLPS(1);
3070 3351
3071 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3352 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3080,14 +3361,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3080 UUID friendTransactionID = UUID.Random(); 3361 UUID friendTransactionID = UUID.Random();
3081 3362
3082 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3363 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3083 3364
3084 GridInstantMessage msg = new GridInstantMessage(); 3365 GridInstantMessage msg = new GridInstantMessage();
3085 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3366 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3086 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3367 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3087 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3368 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3088// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3369// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3089// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3370// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3090 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3371// DateTime dt = DateTime.UtcNow;
3372//
3373// // Ticks from UtcNow, but make it look like local. Evil, huh?
3374// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3375//
3376// try
3377// {
3378// // Convert that to the PST timezone
3379// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3380// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3381// }
3382// catch
3383// {
3384// // No logging here, as it could be VERY spammy
3385// }
3386//
3387// // And make it look local again to fool the unix time util
3388// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3389
3390 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3391
3091 //if (client != null) 3392 //if (client != null)
3092 //{ 3393 //{
3093 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3394 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3101,12 +3402,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 msg.message = message.Substring(0, 1024); 3402 msg.message = message.Substring(0, 1024);
3102 else 3403 else
3103 msg.message = message; 3404 msg.message = message;
3104 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3405 msg.dialog = (byte)19; // MessageFromObject
3105 msg.fromGroup = false;// fromGroup; 3406 msg.fromGroup = false;// fromGroup;
3106 msg.offline = (byte)0; //offline; 3407 msg.offline = (byte)0; //offline;
3107 msg.ParentEstateID = 0; //ParentEstateID; 3408 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3108 msg.Position = new Vector3(m_host.AbsolutePosition); 3409 msg.Position = new Vector3(m_host.AbsolutePosition);
3109 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3410 msg.RegionID = World.RegionInfo.RegionID.Guid;
3110 msg.binaryBucket 3411 msg.binaryBucket
3111 = Util.StringToBytes256( 3412 = Util.StringToBytes256(
3112 "{0}/{1}/{2}/{3}", 3413 "{0}/{1}/{2}/{3}",
@@ -3134,7 +3435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 } 3435 }
3135 3436
3136 emailModule.SendEmail(m_host.UUID, address, subject, message); 3437 emailModule.SendEmail(m_host.UUID, address, subject, message);
3137 ScriptSleep(20000); 3438 ScriptSleep(15000);
3138 } 3439 }
3139 3440
3140 public void llGetNextEmail(string address, string subject) 3441 public void llGetNextEmail(string address, string subject)
@@ -3234,13 +3535,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3234 m_host.AddScriptLPS(1); 3535 m_host.AddScriptLPS(1);
3235 } 3536 }
3236 3537
3237 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3238 {
3239 m_host.AddScriptLPS(1);
3240 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3241 m_host.RotLookAt(rot, (float)strength, (float)damping);
3242 }
3243
3244 public LSL_Integer llStringLength(string str) 3538 public LSL_Integer llStringLength(string str)
3245 { 3539 {
3246 m_host.AddScriptLPS(1); 3540 m_host.AddScriptLPS(1);
@@ -3264,14 +3558,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3264 3558
3265 TaskInventoryItem item; 3559 TaskInventoryItem item;
3266 3560
3267 lock (m_host.TaskInventory) 3561 m_host.TaskInventory.LockItemsForRead(true);
3562 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3268 { 3563 {
3269 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3564 m_host.TaskInventory.LockItemsForRead(false);
3270 return; 3565 return;
3271 else
3272 item = m_host.TaskInventory[InventorySelf()];
3273 } 3566 }
3274 3567 else
3568 {
3569 item = m_host.TaskInventory[InventorySelf()];
3570 }
3571 m_host.TaskInventory.LockItemsForRead(false);
3275 if (item.PermsGranter == UUID.Zero) 3572 if (item.PermsGranter == UUID.Zero)
3276 return; 3573 return;
3277 3574
@@ -3301,13 +3598,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3301 3598
3302 TaskInventoryItem item; 3599 TaskInventoryItem item;
3303 3600
3304 lock (m_host.TaskInventory) 3601 m_host.TaskInventory.LockItemsForRead(true);
3602 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3305 { 3603 {
3306 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3604 m_host.TaskInventory.LockItemsForRead(false);
3307 return; 3605 return;
3308 else
3309 item = m_host.TaskInventory[InventorySelf()];
3310 } 3606 }
3607 else
3608 {
3609 item = m_host.TaskInventory[InventorySelf()];
3610 }
3611 m_host.TaskInventory.LockItemsForRead(false);
3612
3311 3613
3312 if (item.PermsGranter == UUID.Zero) 3614 if (item.PermsGranter == UUID.Zero)
3313 return; 3615 return;
@@ -3377,10 +3679,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3377 3679
3378 TaskInventoryItem item; 3680 TaskInventoryItem item;
3379 3681
3380 lock (m_host.TaskInventory) 3682
3683 m_host.TaskInventory.LockItemsForRead(true);
3684 if (!m_host.TaskInventory.ContainsKey(invItemID))
3685 {
3686 m_host.TaskInventory.LockItemsForRead(false);
3687 return;
3688 }
3689 else
3381 { 3690 {
3382 item = m_host.TaskInventory[invItemID]; 3691 item = m_host.TaskInventory[invItemID];
3383 } 3692 }
3693 m_host.TaskInventory.LockItemsForRead(false);
3384 3694
3385 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3695 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3386 { 3696 {
@@ -3408,15 +3718,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3408 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3718 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3409 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3719 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3410 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3720 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3721 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3411 ScriptBaseClass.PERMISSION_ATTACH; 3722 ScriptBaseClass.PERMISSION_ATTACH;
3412 3723
3413 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3724 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3414 { 3725 {
3415 lock (m_host.TaskInventory) 3726 m_host.TaskInventory.LockItemsForWrite(true);
3416 { 3727 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3417 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3728 m_host.TaskInventory[invItemID].PermsMask = perm;
3418 m_host.TaskInventory[invItemID].PermsMask = perm; 3729 m_host.TaskInventory.LockItemsForWrite(false);
3419 }
3420 3730
3421 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3731 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3422 "run_time_permissions", new Object[] { 3732 "run_time_permissions", new Object[] {
@@ -3426,28 +3736,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3426 return; 3736 return;
3427 } 3737 }
3428 } 3738 }
3429 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3739 else
3430 { 3740 {
3431 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3741 bool sitting = false;
3432 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3742 if (m_host.SitTargetAvatar == agentID)
3433 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3743 {
3434 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3744 sitting = true;
3435 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3745 }
3746 else
3747 {
3748 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3749 {
3750 if (p.SitTargetAvatar == agentID)
3751 sitting = true;
3752 }
3753 }
3436 3754
3437 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3755 if (sitting)
3438 { 3756 {
3439 lock (m_host.TaskInventory) 3757 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3758 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3759 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3760 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3761 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3762
3763 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3440 { 3764 {
3765 m_host.TaskInventory.LockItemsForWrite(true);
3441 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3766 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3442 m_host.TaskInventory[invItemID].PermsMask = perm; 3767 m_host.TaskInventory[invItemID].PermsMask = perm;
3443 } 3768 m_host.TaskInventory.LockItemsForWrite(false);
3444 3769
3445 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3770 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3446 "run_time_permissions", new Object[] { 3771 "run_time_permissions", new Object[] {
3447 new LSL_Integer(perm) }, 3772 new LSL_Integer(perm) },
3448 new DetectParams[0])); 3773 new DetectParams[0]));
3449 3774
3450 return; 3775 return;
3776 }
3451 } 3777 }
3452 } 3778 }
3453 3779
@@ -3461,11 +3787,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3461 3787
3462 if (!m_waitingForScriptAnswer) 3788 if (!m_waitingForScriptAnswer)
3463 { 3789 {
3464 lock (m_host.TaskInventory) 3790 m_host.TaskInventory.LockItemsForWrite(true);
3465 { 3791 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3466 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3792 m_host.TaskInventory[invItemID].PermsMask = 0;
3467 m_host.TaskInventory[invItemID].PermsMask = 0; 3793 m_host.TaskInventory.LockItemsForWrite(false);
3468 }
3469 3794
3470 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3795 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3471 m_waitingForScriptAnswer=true; 3796 m_waitingForScriptAnswer=true;
@@ -3500,10 +3825,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3500 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3825 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3501 llReleaseControls(); 3826 llReleaseControls();
3502 3827
3503 lock (m_host.TaskInventory) 3828
3504 { 3829 m_host.TaskInventory.LockItemsForWrite(true);
3505 m_host.TaskInventory[invItemID].PermsMask = answer; 3830 m_host.TaskInventory[invItemID].PermsMask = answer;
3506 } 3831 m_host.TaskInventory.LockItemsForWrite(false);
3832
3507 3833
3508 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3834 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3509 "run_time_permissions", new Object[] { 3835 "run_time_permissions", new Object[] {
@@ -3515,16 +3841,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3515 { 3841 {
3516 m_host.AddScriptLPS(1); 3842 m_host.AddScriptLPS(1);
3517 3843
3518 lock (m_host.TaskInventory) 3844 m_host.TaskInventory.LockItemsForRead(true);
3845
3846 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3519 { 3847 {
3520 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3848 if (item.Type == 10 && item.ItemID == m_itemID)
3521 { 3849 {
3522 if (item.Type == 10 && item.ItemID == m_itemID) 3850 m_host.TaskInventory.LockItemsForRead(false);
3523 { 3851 return item.PermsGranter.ToString();
3524 return item.PermsGranter.ToString();
3525 }
3526 } 3852 }
3527 } 3853 }
3854 m_host.TaskInventory.LockItemsForRead(false);
3528 3855
3529 return UUID.Zero.ToString(); 3856 return UUID.Zero.ToString();
3530 } 3857 }
@@ -3533,19 +3860,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 { 3860 {
3534 m_host.AddScriptLPS(1); 3861 m_host.AddScriptLPS(1);
3535 3862
3536 lock (m_host.TaskInventory) 3863 m_host.TaskInventory.LockItemsForRead(true);
3864
3865 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3537 { 3866 {
3538 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3867 if (item.Type == 10 && item.ItemID == m_itemID)
3539 { 3868 {
3540 if (item.Type == 10 && item.ItemID == m_itemID) 3869 int perms = item.PermsMask;
3541 { 3870 if (m_automaticLinkPermission)
3542 int perms = item.PermsMask; 3871 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3543 if (m_automaticLinkPermission) 3872 m_host.TaskInventory.LockItemsForRead(false);
3544 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3873 return perms;
3545 return perms;
3546 }
3547 } 3874 }
3548 } 3875 }
3876 m_host.TaskInventory.LockItemsForRead(false);
3549 3877
3550 return 0; 3878 return 0;
3551 } 3879 }
@@ -3567,9 +3895,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3895 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3568 { 3896 {
3569 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3897 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3570 3898 if (parts.Count > 0)
3571 foreach (SceneObjectPart part in parts) 3899 {
3572 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3900 try
3901 {
3902 parts[0].ParentGroup.areUpdatesSuspended = true;
3903 foreach (SceneObjectPart part in parts)
3904 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3905 }
3906 finally
3907 {
3908 parts[0].ParentGroup.areUpdatesSuspended = false;
3909 }
3910 }
3573 } 3911 }
3574 3912
3575 public void llCreateLink(string target, int parent) 3913 public void llCreateLink(string target, int parent)
@@ -3582,11 +3920,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3582 return; 3920 return;
3583 3921
3584 TaskInventoryItem item; 3922 TaskInventoryItem item;
3585 lock (m_host.TaskInventory) 3923 m_host.TaskInventory.LockItemsForRead(true);
3586 { 3924 item = m_host.TaskInventory[invItemID];
3587 item = m_host.TaskInventory[invItemID]; 3925 m_host.TaskInventory.LockItemsForRead(false);
3588 } 3926
3589
3590 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3927 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3591 && !m_automaticLinkPermission) 3928 && !m_automaticLinkPermission)
3592 { 3929 {
@@ -3603,11 +3940,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3603 3940
3604 if (targetPart.ParentGroup.AttachmentPoint != 0) 3941 if (targetPart.ParentGroup.AttachmentPoint != 0)
3605 return; // Fail silently if attached 3942 return; // Fail silently if attached
3943
3944 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3945 return;
3946
3606 SceneObjectGroup parentPrim = null, childPrim = null; 3947 SceneObjectGroup parentPrim = null, childPrim = null;
3607 3948
3608 if (targetPart != null) 3949 if (targetPart != null)
3609 { 3950 {
3610 if (parent != 0) { 3951 if (parent != 0)
3952 {
3611 parentPrim = m_host.ParentGroup; 3953 parentPrim = m_host.ParentGroup;
3612 childPrim = targetPart.ParentGroup; 3954 childPrim = targetPart.ParentGroup;
3613 } 3955 }
@@ -3639,16 +3981,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 m_host.AddScriptLPS(1); 3981 m_host.AddScriptLPS(1);
3640 UUID invItemID = InventorySelf(); 3982 UUID invItemID = InventorySelf();
3641 3983
3642 lock (m_host.TaskInventory) 3984 m_host.TaskInventory.LockItemsForRead(true);
3643 {
3644 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3985 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3645 && !m_automaticLinkPermission) 3986 && !m_automaticLinkPermission)
3646 { 3987 {
3647 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3988 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3989 m_host.TaskInventory.LockItemsForRead(false);
3648 return; 3990 return;
3649 } 3991 }
3650 } 3992 m_host.TaskInventory.LockItemsForRead(false);
3651 3993
3652 if (linknum < ScriptBaseClass.LINK_THIS) 3994 if (linknum < ScriptBaseClass.LINK_THIS)
3653 return; 3995 return;
3654 3996
@@ -3687,10 +4029,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3687 // Restructuring Multiple Prims. 4029 // Restructuring Multiple Prims.
3688 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4030 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3689 parts.Remove(parentPrim.RootPart); 4031 parts.Remove(parentPrim.RootPart);
3690 foreach (SceneObjectPart part in parts) 4032 if (parts.Count > 0)
3691 { 4033 {
3692 parentPrim.DelinkFromGroup(part.LocalId, true); 4034 try
4035 {
4036 parts[0].ParentGroup.areUpdatesSuspended = true;
4037 foreach (SceneObjectPart part in parts)
4038 {
4039 parentPrim.DelinkFromGroup(part.LocalId, true);
4040 }
4041 }
4042 finally
4043 {
4044 parts[0].ParentGroup.areUpdatesSuspended = false;
4045 }
3693 } 4046 }
4047
3694 parentPrim.HasGroupChanged = true; 4048 parentPrim.HasGroupChanged = true;
3695 parentPrim.ScheduleGroupForFullUpdate(); 4049 parentPrim.ScheduleGroupForFullUpdate();
3696 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4050 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3699,11 +4053,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3699 { 4053 {
3700 SceneObjectPart newRoot = parts[0]; 4054 SceneObjectPart newRoot = parts[0];
3701 parts.Remove(newRoot); 4055 parts.Remove(newRoot);
3702 foreach (SceneObjectPart part in parts) 4056
4057 try
3703 { 4058 {
3704 part.UpdateFlag = 0; 4059 parts[0].ParentGroup.areUpdatesSuspended = true;
3705 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4060 foreach (SceneObjectPart part in parts)
4061 {
4062 part.UpdateFlag = 0;
4063 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4064 }
3706 } 4065 }
4066 finally
4067 {
4068 parts[0].ParentGroup.areUpdatesSuspended = false;
4069 }
4070
4071
3707 newRoot.ParentGroup.HasGroupChanged = true; 4072 newRoot.ParentGroup.HasGroupChanged = true;
3708 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4073 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3709 } 4074 }
@@ -3723,6 +4088,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3723 public void llBreakAllLinks() 4088 public void llBreakAllLinks()
3724 { 4089 {
3725 m_host.AddScriptLPS(1); 4090 m_host.AddScriptLPS(1);
4091
4092 UUID invItemID = InventorySelf();
4093
4094 TaskInventoryItem item;
4095 m_host.TaskInventory.LockItemsForRead(true);
4096 item = m_host.TaskInventory[invItemID];
4097 m_host.TaskInventory.LockItemsForRead(false);
4098
4099 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4100 && !m_automaticLinkPermission)
4101 {
4102 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4103 return;
4104 }
4105
3726 SceneObjectGroup parentPrim = m_host.ParentGroup; 4106 SceneObjectGroup parentPrim = m_host.ParentGroup;
3727 if (parentPrim.AttachmentPoint != 0) 4107 if (parentPrim.AttachmentPoint != 0)
3728 return; // Fail silently if attached 4108 return; // Fail silently if attached
@@ -3768,6 +4148,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3768 } 4148 }
3769 else 4149 else
3770 { 4150 {
4151 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4152 {
4153 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4154
4155 if (linknum < 0)
4156 return UUID.Zero.ToString();
4157
4158 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4159 if (avatars.Count > linknum)
4160 {
4161 return avatars[linknum].UUID.ToString();
4162 }
4163 }
3771 return UUID.Zero.ToString(); 4164 return UUID.Zero.ToString();
3772 } 4165 }
3773 } 4166 }
@@ -3866,17 +4259,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4259 m_host.AddScriptLPS(1);
3867 int count = 0; 4260 int count = 0;
3868 4261
3869 lock (m_host.TaskInventory) 4262 m_host.TaskInventory.LockItemsForRead(true);
4263 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4264 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4265 if (inv.Value.Type == type || type == -1)
3872 { 4266 {
3873 if (inv.Value.Type == type || type == -1) 4267 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4268 }
3878 } 4269 }
3879 4270
4271 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4272 return count;
3881 } 4273 }
3882 4274
@@ -3885,16 +4277,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4277 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4278 ArrayList keys = new ArrayList();
3887 4279
3888 lock (m_host.TaskInventory) 4280 m_host.TaskInventory.LockItemsForRead(true);
4281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4282 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4283 if (inv.Value.Type == type || type == -1)
3891 { 4284 {
3892 if (inv.Value.Type == type || type == -1) 4285 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4286 }
3897 } 4287 }
4288 m_host.TaskInventory.LockItemsForRead(false);
3898 4289
3899 if (keys.Count == 0) 4290 if (keys.Count == 0)
3900 { 4291 {
@@ -3931,25 +4322,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3931 } 4322 }
3932 4323
3933 // move the first object found with this inventory name 4324 // move the first object found with this inventory name
3934 lock (m_host.TaskInventory) 4325 m_host.TaskInventory.LockItemsForRead(true);
4326 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3935 { 4327 {
3936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4328 if (inv.Value.Name == inventory)
3937 { 4329 {
3938 if (inv.Value.Name == inventory) 4330 found = true;
3939 { 4331 objId = inv.Key;
3940 found = true; 4332 assetType = inv.Value.Type;
3941 objId = inv.Key; 4333 objName = inv.Value.Name;
3942 assetType = inv.Value.Type; 4334 break;
3943 objName = inv.Value.Name;
3944 break;
3945 }
3946 } 4335 }
3947 } 4336 }
4337 m_host.TaskInventory.LockItemsForRead(false);
3948 4338
3949 if (!found) 4339 if (!found)
3950 { 4340 {
3951 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4341 llSay(0, String.Format("Could not find object '{0}'", inventory));
3952 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4342 return;
4343// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3953 } 4344 }
3954 4345
3955 // check if destination is an object 4346 // check if destination is an object
@@ -3975,6 +4366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3975 return; 4366 return;
3976 } 4367 }
3977 } 4368 }
4369
3978 // destination is an avatar 4370 // destination is an avatar
3979 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4371 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3980 4372
@@ -3997,26 +4389,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3997 bucket); 4389 bucket);
3998 if (m_TransferModule != null) 4390 if (m_TransferModule != null)
3999 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4391 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4392
4393 //This delay should only occur when giving inventory to avatars.
4000 ScriptSleep(3000); 4394 ScriptSleep(3000);
4001 } 4395 }
4002 } 4396 }
4003 4397
4398 [DebuggerNonUserCode]
4004 public void llRemoveInventory(string name) 4399 public void llRemoveInventory(string name)
4005 { 4400 {
4006 m_host.AddScriptLPS(1); 4401 m_host.AddScriptLPS(1);
4007 4402
4008 lock (m_host.TaskInventory) 4403 List<TaskInventoryItem> inv;
4404 try
4009 { 4405 {
4010 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4406 m_host.TaskInventory.LockItemsForRead(true);
4407 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4408 }
4409 finally
4410 {
4411 m_host.TaskInventory.LockItemsForRead(false);
4412 }
4413 foreach (TaskInventoryItem item in inv)
4414 {
4415 if (item.Name == name)
4011 { 4416 {
4012 if (item.Name == name) 4417 if (item.ItemID == m_itemID)
4013 { 4418 throw new ScriptDeleteException();
4014 if (item.ItemID == m_itemID) 4419 else
4015 throw new ScriptDeleteException(); 4420 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4016 else 4421 return;
4017 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4018 return;
4019 }
4020 } 4422 }
4021 } 4423 }
4022 } 4424 }
@@ -4051,112 +4453,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4051 { 4453 {
4052 m_host.AddScriptLPS(1); 4454 m_host.AddScriptLPS(1);
4053 4455
4054 UUID uuid = (UUID)id; 4456 UUID uuid;
4055 PresenceInfo pinfo = null; 4457 if (UUID.TryParse(id, out uuid))
4056 UserAccount account;
4057
4058 UserInfoCacheEntry ce;
4059 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4060 { 4458 {
4061 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4459 PresenceInfo pinfo = null;
4062 if (account == null) 4460 UserAccount account;
4461
4462 UserInfoCacheEntry ce;
4463 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4063 { 4464 {
4064 m_userInfoCache[uuid] = null; // Cache negative 4465 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4065 return UUID.Zero.ToString(); 4466 if (account == null)
4066 } 4467 {
4468 m_userInfoCache[uuid] = null; // Cache negative
4469 return UUID.Zero.ToString();
4470 }
4067 4471
4068 4472
4069 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4473 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4070 if (pinfos != null && pinfos.Length > 0) 4474 if (pinfos != null && pinfos.Length > 0)
4071 {
4072 foreach (PresenceInfo p in pinfos)
4073 { 4475 {
4074 if (p.RegionID != UUID.Zero) 4476 foreach (PresenceInfo p in pinfos)
4075 { 4477 {
4076 pinfo = p; 4478 if (p.RegionID != UUID.Zero)
4479 {
4480 pinfo = p;
4481 }
4077 } 4482 }
4078 } 4483 }
4079 }
4080 4484
4081 ce = new UserInfoCacheEntry(); 4485 ce = new UserInfoCacheEntry();
4082 ce.time = Util.EnvironmentTickCount(); 4486 ce.time = Util.EnvironmentTickCount();
4083 ce.account = account; 4487 ce.account = account;
4084 ce.pinfo = pinfo; 4488 ce.pinfo = pinfo;
4085 } 4489 m_userInfoCache[uuid] = ce;
4086 else 4490 }
4087 { 4491 else
4088 if (ce == null) 4492 {
4089 return UUID.Zero.ToString(); 4493 if (ce == null)
4494 return UUID.Zero.ToString();
4090 4495
4091 account = ce.account; 4496 account = ce.account;
4092 pinfo = ce.pinfo; 4497 pinfo = ce.pinfo;
4093 } 4498 }
4094 4499
4095 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4500 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4096 {
4097 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4098 if (pinfos != null && pinfos.Length > 0)
4099 { 4501 {
4100 foreach (PresenceInfo p in pinfos) 4502 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4503 if (pinfos != null && pinfos.Length > 0)
4101 { 4504 {
4102 if (p.RegionID != UUID.Zero) 4505 foreach (PresenceInfo p in pinfos)
4103 { 4506 {
4104 pinfo = p; 4507 if (p.RegionID != UUID.Zero)
4508 {
4509 pinfo = p;
4510 }
4105 } 4511 }
4106 } 4512 }
4107 } 4513 else
4108 else 4514 pinfo = null;
4109 pinfo = null;
4110 4515
4111 ce.time = Util.EnvironmentTickCount(); 4516 ce.time = Util.EnvironmentTickCount();
4112 ce.pinfo = pinfo; 4517 ce.pinfo = pinfo;
4113 } 4518 }
4114 4519
4115 string reply = String.Empty; 4520 string reply = String.Empty;
4116 4521
4117 switch (data) 4522 switch (data)
4118 { 4523 {
4119 case 1: // DATA_ONLINE (0|1) 4524 case 1: // DATA_ONLINE (0|1)
4120 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4525 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4121 reply = "1"; 4526 reply = "1";
4122 else 4527 else
4123 reply = "0"; 4528 reply = "0";
4124 break; 4529 break;
4125 case 2: // DATA_NAME (First Last) 4530 case 2: // DATA_NAME (First Last)
4126 reply = account.FirstName + " " + account.LastName; 4531 reply = account.FirstName + " " + account.LastName;
4127 break; 4532 break;
4128 case 3: // DATA_BORN (YYYY-MM-DD) 4533 case 3: // DATA_BORN (YYYY-MM-DD)
4129 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4534 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4130 born = born.AddSeconds(account.Created); 4535 born = born.AddSeconds(account.Created);
4131 reply = born.ToString("yyyy-MM-dd"); 4536 reply = born.ToString("yyyy-MM-dd");
4132 break; 4537 break;
4133 case 4: // DATA_RATING (0,0,0,0,0,0) 4538 case 4: // DATA_RATING (0,0,0,0,0,0)
4134 reply = "0,0,0,0,0,0"; 4539 reply = "0,0,0,0,0,0";
4135 break; 4540 break;
4136 case 8: // DATA_PAYINFO (0|1|2|3) 4541 case 8: // DATA_PAYINFO (0|1|2|3)
4137 reply = "0"; 4542 reply = "0";
4138 break; 4543 break;
4139 default: 4544 default:
4140 return UUID.Zero.ToString(); // Raise no event 4545 return UUID.Zero.ToString(); // Raise no event
4141 } 4546 }
4142 4547
4143 UUID rq = UUID.Random(); 4548 UUID rq = UUID.Random();
4144 4549
4145 UUID tid = AsyncCommands. 4550 UUID tid = AsyncCommands.
4146 DataserverPlugin.RegisterRequest(m_localID, 4551 DataserverPlugin.RegisterRequest(m_localID,
4147 m_itemID, rq.ToString()); 4552 m_itemID, rq.ToString());
4148 4553
4149 AsyncCommands. 4554 AsyncCommands.
4150 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4555 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4151 4556
4152 ScriptSleep(100); 4557 ScriptSleep(100);
4153 return tid.ToString(); 4558 return tid.ToString();
4559 }
4560 else
4561 {
4562 ShoutError("Invalid UUID passed to llRequestAgentData.");
4563 }
4564 return "";
4154 } 4565 }
4155 4566
4156 public LSL_String llRequestInventoryData(string name) 4567 public LSL_String llRequestInventoryData(string name)
4157 { 4568 {
4158 m_host.AddScriptLPS(1); 4569 m_host.AddScriptLPS(1);
4159 4570
4571 //Clone is thread safe
4160 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4572 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4161 4573
4162 foreach (TaskInventoryItem item in itemDictionary.Values) 4574 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4210,6 +4622,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4210 ScenePresence presence = World.GetScenePresence(agentId); 4622 ScenePresence presence = World.GetScenePresence(agentId);
4211 if (presence != null) 4623 if (presence != null)
4212 { 4624 {
4625 // agent must not be a god
4626 if (presence.UserLevel >= 200) return;
4627
4213 // agent must be over the owners land 4628 // agent must be over the owners land
4214 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4629 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4215 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4630 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4232,7 +4647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4232 UUID av = new UUID(); 4647 UUID av = new UUID();
4233 if (!UUID.TryParse(agent,out av)) 4648 if (!UUID.TryParse(agent,out av))
4234 { 4649 {
4235 LSLError("First parameter to llDialog needs to be a key"); 4650 //LSLError("First parameter to llDialog needs to be a key");
4236 return; 4651 return;
4237 } 4652 }
4238 4653
@@ -4269,17 +4684,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4269 UUID soundId = UUID.Zero; 4684 UUID soundId = UUID.Zero;
4270 if (!UUID.TryParse(impact_sound, out soundId)) 4685 if (!UUID.TryParse(impact_sound, out soundId))
4271 { 4686 {
4272 lock (m_host.TaskInventory) 4687 m_host.TaskInventory.LockItemsForRead(true);
4688 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4273 { 4689 {
4274 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4690 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4275 { 4691 {
4276 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4692 soundId = item.AssetID;
4277 { 4693 break;
4278 soundId = item.AssetID;
4279 break;
4280 }
4281 } 4694 }
4282 } 4695 }
4696 m_host.TaskInventory.LockItemsForRead(false);
4283 } 4697 }
4284 m_host.CollisionSound = soundId; 4698 m_host.CollisionSound = soundId;
4285 m_host.CollisionSoundVolume = (float)impact_volume; 4699 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4319,6 +4733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4319 UUID partItemID; 4733 UUID partItemID;
4320 foreach (SceneObjectPart part in parts) 4734 foreach (SceneObjectPart part in parts)
4321 { 4735 {
4736 //Clone is thread safe
4322 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4737 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4323 4738
4324 foreach (TaskInventoryItem item in itemsDictionary.Values) 4739 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4533,17 +4948,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4533 4948
4534 m_host.AddScriptLPS(1); 4949 m_host.AddScriptLPS(1);
4535 4950
4536 lock (m_host.TaskInventory) 4951 m_host.TaskInventory.LockItemsForRead(true);
4952 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4537 { 4953 {
4538 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4954 if (item.Type == 10 && item.ItemID == m_itemID)
4539 { 4955 {
4540 if (item.Type == 10 && item.ItemID == m_itemID) 4956 result = item.Name!=null?item.Name:String.Empty;
4541 { 4957 break;
4542 result = item.Name != null ? item.Name : String.Empty;
4543 break;
4544 }
4545 } 4958 }
4546 } 4959 }
4960 m_host.TaskInventory.LockItemsForRead(false);
4547 4961
4548 return result; 4962 return result;
4549 } 4963 }
@@ -4712,23 +5126,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4712 { 5126 {
4713 m_host.AddScriptLPS(1); 5127 m_host.AddScriptLPS(1);
4714 5128
4715 lock (m_host.TaskInventory) 5129 m_host.TaskInventory.LockItemsForRead(true);
5130 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4716 { 5131 {
4717 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5132 if (inv.Value.Name == name)
4718 { 5133 {
4719 if (inv.Value.Name == name) 5134 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4720 { 5135 {
4721 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5136 m_host.TaskInventory.LockItemsForRead(false);
4722 { 5137 return inv.Value.AssetID.ToString();
4723 return inv.Value.AssetID.ToString(); 5138 }
4724 } 5139 else
4725 else 5140 {
4726 { 5141 m_host.TaskInventory.LockItemsForRead(false);
4727 return UUID.Zero.ToString(); 5142 return UUID.Zero.ToString();
4728 }
4729 } 5143 }
4730 } 5144 }
4731 } 5145 }
5146 m_host.TaskInventory.LockItemsForRead(false);
4732 5147
4733 return UUID.Zero.ToString(); 5148 return UUID.Zero.ToString();
4734 } 5149 }
@@ -4881,14 +5296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4881 { 5296 {
4882 m_host.AddScriptLPS(1); 5297 m_host.AddScriptLPS(1);
4883 5298
4884 if (src == null) 5299 return src.Length;
4885 {
4886 return 0;
4887 }
4888 else
4889 {
4890 return src.Length;
4891 }
4892 } 5300 }
4893 5301
4894 public LSL_Integer llList2Integer(LSL_List src, int index) 5302 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4934,7 +5342,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4934 else if (src.Data[index] is LSL_Float) 5342 else if (src.Data[index] is LSL_Float)
4935 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5343 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4936 else if (src.Data[index] is LSL_String) 5344 else if (src.Data[index] is LSL_String)
4937 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5345 {
5346 string str = ((LSL_String) src.Data[index]).m_string;
5347 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5348 if (m != Match.Empty)
5349 {
5350 str = m.Value;
5351 double d = 0.0;
5352 if (!Double.TryParse(str, out d))
5353 return 0.0;
5354
5355 return d;
5356 }
5357 return 0.0;
5358 }
4938 return Convert.ToDouble(src.Data[index]); 5359 return Convert.ToDouble(src.Data[index]);
4939 } 5360 }
4940 catch (FormatException) 5361 catch (FormatException)
@@ -5207,7 +5628,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5207 } 5628 }
5208 } 5629 }
5209 } 5630 }
5210 else { 5631 else
5632 {
5211 object[] array = new object[src.Length]; 5633 object[] array = new object[src.Length];
5212 Array.Copy(src.Data, 0, array, 0, src.Length); 5634 Array.Copy(src.Data, 0, array, 0, src.Length);
5213 result = new LSL_List(array); 5635 result = new LSL_List(array);
@@ -5658,10 +6080,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5658 m_host.AddScriptLPS(1); 6080 m_host.AddScriptLPS(1);
5659 6081
5660 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6082 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5661 6083 if (parts.Count > 0)
5662 foreach (var part in parts)
5663 { 6084 {
5664 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6085 try
6086 {
6087 parts[0].ParentGroup.areUpdatesSuspended = true;
6088 foreach (var part in parts)
6089 {
6090 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6091 }
6092 }
6093 finally
6094 {
6095 parts[0].ParentGroup.areUpdatesSuspended = false;
6096 }
5665 } 6097 }
5666 } 6098 }
5667 6099
@@ -5715,6 +6147,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5715 ScriptSleep(5000); 6147 ScriptSleep(5000);
5716 } 6148 }
5717 6149
6150 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6151 {
6152 return ParseString2List(str, separators, in_spacers, false);
6153 }
6154
5718 public LSL_Integer llOverMyLand(string id) 6155 public LSL_Integer llOverMyLand(string id)
5719 { 6156 {
5720 m_host.AddScriptLPS(1); 6157 m_host.AddScriptLPS(1);
@@ -5915,7 +6352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5915 return m_host.ParentGroup.AttachmentPoint; 6352 return m_host.ParentGroup.AttachmentPoint;
5916 } 6353 }
5917 6354
5918 public LSL_Integer llGetFreeMemory() 6355 public virtual LSL_Integer llGetFreeMemory()
5919 { 6356 {
5920 m_host.AddScriptLPS(1); 6357 m_host.AddScriptLPS(1);
5921 // Make scripts designed for LSO happy 6358 // Make scripts designed for LSO happy
@@ -6032,7 +6469,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6032 SetParticleSystem(m_host, rules); 6469 SetParticleSystem(m_host, rules);
6033 } 6470 }
6034 6471
6035 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6472 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6473 {
6036 6474
6037 6475
6038 if (rules.Length == 0) 6476 if (rules.Length == 0)
@@ -6226,14 +6664,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6226 6664
6227 protected UUID GetTaskInventoryItem(string name) 6665 protected UUID GetTaskInventoryItem(string name)
6228 { 6666 {
6229 lock (m_host.TaskInventory) 6667 m_host.TaskInventory.LockItemsForRead(true);
6668 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6230 { 6669 {
6231 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6670 if (inv.Value.Name == name)
6232 { 6671 {
6233 if (inv.Value.Name == name) 6672 m_host.TaskInventory.LockItemsForRead(false);
6234 return inv.Key; 6673 return inv.Key;
6235 } 6674 }
6236 } 6675 }
6676 m_host.TaskInventory.LockItemsForRead(false);
6237 6677
6238 return UUID.Zero; 6678 return UUID.Zero;
6239 } 6679 }
@@ -6483,13 +6923,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6483 UUID av = new UUID(); 6923 UUID av = new UUID();
6484 if (!UUID.TryParse(avatar,out av)) 6924 if (!UUID.TryParse(avatar,out av))
6485 { 6925 {
6486 LSLError("First parameter to llDialog needs to be a key"); 6926 //LSLError("First parameter to llDialog needs to be a key");
6487 return; 6927 return;
6488 } 6928 }
6489 if (buttons.Length < 1) 6929 if (buttons.Length < 1)
6490 { 6930 {
6491 LSLError("No less than 1 button can be shown"); 6931 buttons.Add("OK");
6492 return;
6493 } 6932 }
6494 if (buttons.Length > 12) 6933 if (buttons.Length > 12)
6495 { 6934 {
@@ -6506,7 +6945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6506 } 6945 }
6507 if (buttons.Data[i].ToString().Length > 24) 6946 if (buttons.Data[i].ToString().Length > 24)
6508 { 6947 {
6509 LSLError("button label cannot be longer than 24 characters"); 6948 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6510 return; 6949 return;
6511 } 6950 }
6512 buts[i] = buttons.Data[i].ToString(); 6951 buts[i] = buttons.Data[i].ToString();
@@ -6565,22 +7004,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6565 } 7004 }
6566 7005
6567 // copy the first script found with this inventory name 7006 // copy the first script found with this inventory name
6568 lock (m_host.TaskInventory) 7007 TaskInventoryItem scriptItem = null;
7008 m_host.TaskInventory.LockItemsForRead(true);
7009 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6569 { 7010 {
6570 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7011 if (inv.Value.Name == name)
6571 { 7012 {
6572 if (inv.Value.Name == name) 7013 // make sure the object is a script
7014 if (10 == inv.Value.Type)
6573 { 7015 {
6574 // make sure the object is a script 7016 found = true;
6575 if (10 == inv.Value.Type) 7017 srcId = inv.Key;
6576 { 7018 scriptItem = inv.Value;
6577 found = true; 7019 break;
6578 srcId = inv.Key;
6579 break;
6580 }
6581 } 7020 }
6582 } 7021 }
6583 } 7022 }
7023 m_host.TaskInventory.LockItemsForRead(false);
6584 7024
6585 if (!found) 7025 if (!found)
6586 { 7026 {
@@ -6588,8 +7028,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6588 return; 7028 return;
6589 } 7029 }
6590 7030
6591 // the rest of the permission checks are done in RezScript, so check the pin there as well 7031 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6592 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7032 if (dest != null)
7033 {
7034 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7035 {
7036 // the rest of the permission checks are done in RezScript, so check the pin there as well
7037 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7038
7039 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7040 m_host.Inventory.RemoveInventoryItem(srcId);
7041 }
7042 }
6593 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7043 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6594 ScriptSleep(3000); 7044 ScriptSleep(3000);
6595 } 7045 }
@@ -6652,19 +7102,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6652 public LSL_String llMD5String(string src, int nonce) 7102 public LSL_String llMD5String(string src, int nonce)
6653 { 7103 {
6654 m_host.AddScriptLPS(1); 7104 m_host.AddScriptLPS(1);
6655 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7105 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6656 } 7106 }
6657 7107
6658 public LSL_String llSHA1String(string src) 7108 public LSL_String llSHA1String(string src)
6659 { 7109 {
6660 m_host.AddScriptLPS(1); 7110 m_host.AddScriptLPS(1);
6661 return Util.SHA1Hash(src).ToLower(); 7111 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6662 } 7112 }
6663 7113
6664 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7114 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6665 { 7115 {
6666 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7116 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6667 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7117 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7118 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7119 return shapeBlock;
6668 7120
6669 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7121 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6670 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7122 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6769,6 +7221,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6769 // Prim type box, cylinder and prism. 7221 // Prim type box, cylinder and prism.
6770 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7222 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6771 { 7223 {
7224 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7225 return;
7226
6772 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7227 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6773 ObjectShapePacket.ObjectDataBlock shapeBlock; 7228 ObjectShapePacket.ObjectDataBlock shapeBlock;
6774 7229
@@ -6822,6 +7277,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6822 // Prim type sphere. 7277 // Prim type sphere.
6823 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7278 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6824 { 7279 {
7280 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7281 return;
7282
6825 ObjectShapePacket.ObjectDataBlock shapeBlock; 7283 ObjectShapePacket.ObjectDataBlock shapeBlock;
6826 7284
6827 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7285 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6863,6 +7321,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6863 // Prim type torus, tube and ring. 7321 // Prim type torus, tube and ring.
6864 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7322 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
6865 { 7323 {
7324 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7325 return;
7326
6866 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7327 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6867 ObjectShapePacket.ObjectDataBlock shapeBlock; 7328 ObjectShapePacket.ObjectDataBlock shapeBlock;
6868 7329
@@ -6998,6 +7459,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6998 // Prim type sculpt. 7459 // Prim type sculpt.
6999 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7460 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7000 { 7461 {
7462 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7463 return;
7464
7001 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7465 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7002 UUID sculptId; 7466 UUID sculptId;
7003 7467
@@ -7014,13 +7478,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7014 shapeBlock.PathScaleX = 100; 7478 shapeBlock.PathScaleX = 100;
7015 shapeBlock.PathScaleY = 150; 7479 shapeBlock.PathScaleY = 150;
7016 7480
7017 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7481 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7018 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7482 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7019 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7483 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7020 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7484 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7021 { 7485 {
7022 // default 7486 // default
7023 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7487 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7024 } 7488 }
7025 7489
7026 part.Shape.SetSculptProperties((byte)type, sculptId); 7490 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7036,32 +7500,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7036 ScriptSleep(200); 7500 ScriptSleep(200);
7037 } 7501 }
7038 7502
7039 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7503 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7040 { 7504 {
7041 m_host.AddScriptLPS(1); 7505 m_host.AddScriptLPS(1);
7042 7506
7043 setLinkPrimParams(linknumber, rules); 7507 setLinkPrimParams(linknumber, rules);
7044
7045 ScriptSleep(200);
7046 } 7508 }
7047 7509
7048 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7510 private void setLinkPrimParams(int linknumber, LSL_List rules)
7049 { 7511 {
7050 m_host.AddScriptLPS(1); 7512 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7513 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7514 if (parts.Count>0)
7515 {
7516 try
7517 {
7518 parts[0].ParentGroup.areUpdatesSuspended = true;
7519 foreach (SceneObjectPart part in parts)
7520 SetPrimParams(part, rules);
7521 }
7522 finally
7523 {
7524 parts[0].ParentGroup.areUpdatesSuspended = false;
7525 }
7526 }
7527 if (avatars.Count > 0)
7528 {
7529 foreach (ScenePresence avatar in avatars)
7530 SetPrimParams(avatar, rules);
7531 }
7532 }
7051 7533
7052 setLinkPrimParams(linknumber, rules); 7534 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7535 {
7536 llSetLinkPrimitiveParamsFast(linknumber, rules);
7537 ScriptSleep(200);
7053 } 7538 }
7054 7539
7055 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7540 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7056 { 7541 {
7057 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7542 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7543 //We only support PRIM_POSITION and PRIM_ROTATION
7058 7544
7059 foreach (SceneObjectPart part in parts) 7545 int idx = 0;
7060 SetPrimParams(part, rules); 7546
7547 while (idx < rules.Length)
7548 {
7549 int code = rules.GetLSLIntegerItem(idx++);
7550
7551 int remain = rules.Length - idx;
7552
7553
7554
7555 switch (code)
7556 {
7557 case (int)ScriptBaseClass.PRIM_POSITION:
7558 if (remain < 1)
7559 return;
7560 LSL_Vector v;
7561 v = rules.GetVector3Item(idx++);
7562 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7563 av.SendAvatarDataToAllAgents();
7564
7565 break;
7566
7567 case (int)ScriptBaseClass.PRIM_ROTATION:
7568 if (remain < 1)
7569 return;
7570 LSL_Rotation r;
7571 r = rules.GetQuaternionItem(idx++);
7572 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7573 av.SendAvatarDataToAllAgents();
7574 break;
7575 }
7576 }
7061 } 7577 }
7062 7578
7063 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7579 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7064 { 7580 {
7581 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7582 return;
7583
7065 int idx = 0; 7584 int idx = 0;
7066 7585
7067 bool positionChanged = false; 7586 bool positionChanged = false;
@@ -7466,6 +7985,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7466 } 7985 }
7467 } 7986 }
7468 } 7987 }
7988
7989 if (positionChanged)
7990 {
7991 if (part.ParentGroup.RootPart == part)
7992 {
7993 SceneObjectGroup parent = part.ParentGroup;
7994 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7995 }
7996 else
7997 {
7998 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7999 SceneObjectGroup parent = part.ParentGroup;
8000 parent.HasGroupChanged = true;
8001 parent.ScheduleGroupForTerseUpdate();
8002 }
8003 }
7469 } 8004 }
7470 8005
7471 public LSL_String llStringToBase64(string str) 8006 public LSL_String llStringToBase64(string str)
@@ -7614,13 +8149,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7614 public LSL_Integer llGetNumberOfPrims() 8149 public LSL_Integer llGetNumberOfPrims()
7615 { 8150 {
7616 m_host.AddScriptLPS(1); 8151 m_host.AddScriptLPS(1);
7617 int avatarCount = 0; 8152 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7618 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8153
7619 {
7620 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7621 avatarCount++;
7622 });
7623
7624 return m_host.ParentGroup.PrimCount + avatarCount; 8154 return m_host.ParentGroup.PrimCount + avatarCount;
7625 } 8155 }
7626 8156
@@ -7636,55 +8166,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7636 m_host.AddScriptLPS(1); 8166 m_host.AddScriptLPS(1);
7637 UUID objID = UUID.Zero; 8167 UUID objID = UUID.Zero;
7638 LSL_List result = new LSL_List(); 8168 LSL_List result = new LSL_List();
8169
8170 // If the ID is not valid, return null result
7639 if (!UUID.TryParse(obj, out objID)) 8171 if (!UUID.TryParse(obj, out objID))
7640 { 8172 {
7641 result.Add(new LSL_Vector()); 8173 result.Add(new LSL_Vector());
7642 result.Add(new LSL_Vector()); 8174 result.Add(new LSL_Vector());
7643 return result; 8175 return result;
7644 } 8176 }
8177
8178 // Check if this is an attached prim. If so, replace
8179 // the UUID with the avatar UUID and report it's bounding box
8180 SceneObjectPart part = World.GetSceneObjectPart(objID);
8181 if (part != null && part.ParentGroup.IsAttachment)
8182 objID = part.ParentGroup.AttachedAvatar;
8183
8184 // Find out if this is an avatar ID. If so, return it's box
7645 ScenePresence presence = World.GetScenePresence(objID); 8185 ScenePresence presence = World.GetScenePresence(objID);
7646 if (presence != null) 8186 if (presence != null)
7647 { 8187 {
7648 if (presence.ParentID == 0) // not sat on an object 8188 // As per LSL Wiki, there is no difference between sitting
8189 // and standing avatar since server 1.36
8190 LSL_Vector lower;
8191 LSL_Vector upper;
8192 if (presence.Animator.Animations.DefaultAnimation.AnimID
8193 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7649 { 8194 {
7650 LSL_Vector lower; 8195 // This is for ground sitting avatars
7651 LSL_Vector upper; 8196 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7652 if (presence.Animator.Animations.DefaultAnimation.AnimID 8197 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7653 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8198 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7654 {
7655 // This is for ground sitting avatars
7656 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7657 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7658 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7659 }
7660 else
7661 {
7662 // This is for standing/flying avatars
7663 float height = presence.Appearance.AvatarHeight / 2.0f;
7664 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7665 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7666 }
7667 result.Add(lower);
7668 result.Add(upper);
7669 return result;
7670 } 8199 }
7671 else 8200 else
7672 { 8201 {
7673 // sitting on an object so we need the bounding box of that 8202 // This is for standing/flying avatars
7674 // which should include the avatar so set the UUID to the 8203 float height = presence.Appearance.AvatarHeight / 2.0f;
7675 // UUID of the object the avatar is sat on and allow it to fall through 8204 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7676 // to processing an object 8205 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7677 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7678 objID = p.UUID;
7679 } 8206 }
8207
8208 // Adjust to the documented error offsets (see LSL Wiki)
8209 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8210 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8211
8212 if (lower.x > upper.x)
8213 lower.x = upper.x;
8214 if (lower.y > upper.y)
8215 lower.y = upper.y;
8216 if (lower.z > upper.z)
8217 lower.z = upper.z;
8218
8219 result.Add(lower);
8220 result.Add(upper);
8221 return result;
7680 } 8222 }
7681 SceneObjectPart part = World.GetSceneObjectPart(objID); 8223
8224 part = World.GetSceneObjectPart(objID);
7682 // Currently only works for single prims without a sitting avatar 8225 // Currently only works for single prims without a sitting avatar
7683 if (part != null) 8226 if (part != null)
7684 { 8227 {
7685 Vector3 halfSize = part.Scale / 2.0f; 8228 float minX;
7686 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8229 float maxX;
7687 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8230 float minY;
8231 float maxY;
8232 float minZ;
8233 float maxZ;
8234
8235 // This BBox is in sim coordinates, with the offset being
8236 // a contained point.
8237 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8238 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8239
8240 minX -= offsets[0].X;
8241 maxX -= offsets[0].X;
8242 minY -= offsets[0].Y;
8243 maxY -= offsets[0].Y;
8244 minZ -= offsets[0].Z;
8245 maxZ -= offsets[0].Z;
8246
8247 LSL_Vector lower;
8248 LSL_Vector upper;
8249
8250 // Adjust to the documented error offsets (see LSL Wiki)
8251 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8252 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8253
8254 if (lower.x > upper.x)
8255 lower.x = upper.x;
8256 if (lower.y > upper.y)
8257 lower.y = upper.y;
8258 if (lower.z > upper.z)
8259 lower.z = upper.z;
8260
7688 result.Add(lower); 8261 result.Add(lower);
7689 result.Add(upper); 8262 result.Add(upper);
7690 return result; 8263 return result;
@@ -7764,13 +8337,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7764 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8337 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7765 part.AbsolutePosition.Y, 8338 part.AbsolutePosition.Y,
7766 part.AbsolutePosition.Z); 8339 part.AbsolutePosition.Z);
7767 // For some reason, the part.AbsolutePosition.* values do not change if the
7768 // linkset is rotated; they always reflect the child prim's world position
7769 // as though the linkset is unrotated. This is incompatible behavior with SL's
7770 // implementation, so will break scripts imported from there (not to mention it
7771 // makes it more difficult to determine a child prim's actual inworld position).
7772 if (part.ParentID != 0)
7773 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7774 res.Add(v); 8340 res.Add(v);
7775 break; 8341 break;
7776 8342
@@ -7941,56 +8507,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7941 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8507 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7942 if (remain < 1) 8508 if (remain < 1)
7943 return res; 8509 return res;
7944 8510 face = (int)rules.GetLSLIntegerItem(idx++);
7945 face=(int)rules.GetLSLIntegerItem(idx++);
7946 8511
7947 tex = part.Shape.Textures; 8512 tex = part.Shape.Textures;
8513 int shiny;
7948 if (face == ScriptBaseClass.ALL_SIDES) 8514 if (face == ScriptBaseClass.ALL_SIDES)
7949 { 8515 {
7950 for (face = 0; face < GetNumberOfSides(part); face++) 8516 for (face = 0; face < GetNumberOfSides(part); face++)
7951 { 8517 {
7952 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8518 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7953 // Convert Shininess to PRIM_SHINY_* 8519 if (shinyness == Shininess.High)
7954 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8520 {
7955 // PRIM_BUMP_* 8521 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7956 res.Add(new LSL_Integer((int)texface.Bump)); 8522 }
8523 else if (shinyness == Shininess.Medium)
8524 {
8525 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8526 }
8527 else if (shinyness == Shininess.Low)
8528 {
8529 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8530 }
8531 else
8532 {
8533 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8534 }
8535 res.Add(new LSL_Integer(shiny));
8536 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7957 } 8537 }
7958 } 8538 }
7959 else 8539 else
7960 { 8540 {
7961 if (face >= 0 && face < GetNumberOfSides(part)) 8541 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8542 if (shinyness == Shininess.High)
7962 { 8543 {
7963 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8544 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7964 // Convert Shininess to PRIM_SHINY_* 8545 }
7965 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8546 else if (shinyness == Shininess.Medium)
7966 // PRIM_BUMP_* 8547 {
7967 res.Add(new LSL_Integer((int)texface.Bump)); 8548 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8549 }
8550 else if (shinyness == Shininess.Low)
8551 {
8552 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8553 }
8554 else
8555 {
8556 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7968 } 8557 }
8558 res.Add(new LSL_Integer(shiny));
8559 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7969 } 8560 }
7970 break; 8561 break;
7971 8562
7972 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8563 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7973 if (remain < 1) 8564 if (remain < 1)
7974 return res; 8565 return res;
7975 8566 face = (int)rules.GetLSLIntegerItem(idx++);
7976 face=(int)rules.GetLSLIntegerItem(idx++);
7977 8567
7978 tex = part.Shape.Textures; 8568 tex = part.Shape.Textures;
8569 int fullbright;
7979 if (face == ScriptBaseClass.ALL_SIDES) 8570 if (face == ScriptBaseClass.ALL_SIDES)
7980 { 8571 {
7981 for (face = 0; face < GetNumberOfSides(part); face++) 8572 for (face = 0; face < GetNumberOfSides(part); face++)
7982 { 8573 {
7983 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8574 if (tex.GetFace((uint)face).Fullbright == true)
7984 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8575 {
8576 fullbright = ScriptBaseClass.TRUE;
8577 }
8578 else
8579 {
8580 fullbright = ScriptBaseClass.FALSE;
8581 }
8582 res.Add(new LSL_Integer(fullbright));
7985 } 8583 }
7986 } 8584 }
7987 else 8585 else
7988 { 8586 {
7989 if (face >= 0 && face < GetNumberOfSides(part)) 8587 if (tex.GetFace((uint)face).Fullbright == true)
7990 { 8588 {
7991 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8589 fullbright = ScriptBaseClass.TRUE;
7992 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8590 }
8591 else
8592 {
8593 fullbright = ScriptBaseClass.FALSE;
7993 } 8594 }
8595 res.Add(new LSL_Integer(fullbright));
7994 } 8596 }
7995 break; 8597 break;
7996 8598
@@ -8012,27 +8614,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8012 break; 8614 break;
8013 8615
8014 case (int)ScriptBaseClass.PRIM_TEXGEN: 8616 case (int)ScriptBaseClass.PRIM_TEXGEN:
8617 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8015 if (remain < 1) 8618 if (remain < 1)
8016 return res; 8619 return res;
8017 8620 face = (int)rules.GetLSLIntegerItem(idx++);
8018 face=(int)rules.GetLSLIntegerItem(idx++);
8019 8621
8020 tex = part.Shape.Textures; 8622 tex = part.Shape.Textures;
8021 if (face == ScriptBaseClass.ALL_SIDES) 8623 if (face == ScriptBaseClass.ALL_SIDES)
8022 { 8624 {
8023 for (face = 0; face < GetNumberOfSides(part); face++) 8625 for (face = 0; face < GetNumberOfSides(part); face++)
8024 { 8626 {
8025 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8627 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8026 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8628 {
8027 res.Add(new LSL_Integer((uint)texgen >> 1)); 8629 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8630 }
8631 else
8632 {
8633 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8634 }
8028 } 8635 }
8029 } 8636 }
8030 else 8637 else
8031 { 8638 {
8032 if (face >= 0 && face < GetNumberOfSides(part)) 8639 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8640 {
8641 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8642 }
8643 else
8033 { 8644 {
8034 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8645 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8035 res.Add(new LSL_Integer((uint)texgen >> 1));
8036 } 8646 }
8037 } 8647 }
8038 break; 8648 break;
@@ -8055,28 +8665,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8055 case (int)ScriptBaseClass.PRIM_GLOW: 8665 case (int)ScriptBaseClass.PRIM_GLOW:
8056 if (remain < 1) 8666 if (remain < 1)
8057 return res; 8667 return res;
8058 8668 face = (int)rules.GetLSLIntegerItem(idx++);
8059 face=(int)rules.GetLSLIntegerItem(idx++);
8060 8669
8061 tex = part.Shape.Textures; 8670 tex = part.Shape.Textures;
8671 float primglow;
8062 if (face == ScriptBaseClass.ALL_SIDES) 8672 if (face == ScriptBaseClass.ALL_SIDES)
8063 { 8673 {
8064 for (face = 0; face < GetNumberOfSides(part); face++) 8674 for (face = 0; face < GetNumberOfSides(part); face++)
8065 { 8675 {
8066 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8676 primglow = tex.GetFace((uint)face).Glow;
8067 res.Add(new LSL_Float(texface.Glow)); 8677 res.Add(new LSL_Float(primglow));
8068 } 8678 }
8069 } 8679 }
8070 else 8680 else
8071 { 8681 {
8072 if (face >= 0 && face < GetNumberOfSides(part)) 8682 primglow = tex.GetFace((uint)face).Glow;
8073 { 8683 res.Add(new LSL_Float(primglow));
8074 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8075 res.Add(new LSL_Float(texface.Glow));
8076 }
8077 } 8684 }
8078 break; 8685 break;
8079
8080 case (int)ScriptBaseClass.PRIM_TEXT: 8686 case (int)ScriptBaseClass.PRIM_TEXT:
8081 Color4 textColor = part.GetTextColor(); 8687 Color4 textColor = part.GetTextColor();
8082 res.Add(new LSL_String(part.Text)); 8688 res.Add(new LSL_String(part.Text));
@@ -8625,8 +9231,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8625 // The function returns an ordered list 9231 // The function returns an ordered list
8626 // representing the tokens found in the supplied 9232 // representing the tokens found in the supplied
8627 // sources string. If two successive tokenizers 9233 // sources string. If two successive tokenizers
8628 // are encountered, then a NULL entry is added 9234 // are encountered, then a null-string entry is
8629 // to the list. 9235 // added to the list.
8630 // 9236 //
8631 // It is a precondition that the source and 9237 // It is a precondition that the source and
8632 // toekizer lisst are non-null. If they are null, 9238 // toekizer lisst are non-null. If they are null,
@@ -8634,7 +9240,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8634 // while their lengths are being determined. 9240 // while their lengths are being determined.
8635 // 9241 //
8636 // A small amount of working memoryis required 9242 // A small amount of working memoryis required
8637 // of approximately 8*#tokenizers. 9243 // of approximately 8*#tokenizers + 8*srcstrlen.
8638 // 9244 //
8639 // There are many ways in which this function 9245 // There are many ways in which this function
8640 // can be implemented, this implementation is 9246 // can be implemented, this implementation is
@@ -8650,155 +9256,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8650 // and eliminates redundant tokenizers as soon 9256 // and eliminates redundant tokenizers as soon
8651 // as is possible. 9257 // as is possible.
8652 // 9258 //
8653 // The implementation tries to avoid any copying 9259 // The implementation tries to minimize temporary
8654 // of arrays or other objects. 9260 // garbage generation.
8655 // </remarks> 9261 // </remarks>
8656 9262
8657 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9263 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8658 { 9264 {
8659 int beginning = 0; 9265 return ParseString2List(src, separators, spacers, true);
8660 int srclen = src.Length; 9266 }
8661 int seplen = separators.Length;
8662 object[] separray = separators.Data;
8663 int spclen = spacers.Length;
8664 object[] spcarray = spacers.Data;
8665 int mlen = seplen+spclen;
8666
8667 int[] offset = new int[mlen+1];
8668 bool[] active = new bool[mlen];
8669
8670 int best;
8671 int j;
8672
8673 // Initial capacity reduces resize cost
8674 9267
8675 LSL_List tokens = new LSL_List(); 9268 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9269 {
9270 int srclen = src.Length;
9271 int seplen = separators.Length;
9272 object[] separray = separators.Data;
9273 int spclen = spacers.Length;
9274 object[] spcarray = spacers.Data;
9275 int dellen = 0;
9276 string[] delarray = new string[seplen+spclen];
8676 9277
8677 // All entries are initially valid 9278 int outlen = 0;
9279 string[] outarray = new string[srclen*2+1];
8678 9280
8679 for (int i = 0; i < mlen; i++) 9281 int i, j;
8680 active[i] = true; 9282 string d;
8681 9283
8682 offset[mlen] = srclen; 9284 m_host.AddScriptLPS(1);
8683 9285
8684 while (beginning < srclen) 9286 /*
9287 * Convert separator and spacer lists to C# strings.
9288 * Also filter out null strings so we don't hang.
9289 */
9290 for (i = 0; i < seplen; i ++)
8685 { 9291 {
9292 d = separray[i].ToString();
9293 if (d.Length > 0)
9294 {
9295 delarray[dellen++] = d;
9296 }
9297 }
9298 seplen = dellen;
8686 9299
8687 best = mlen; // as bad as it gets 9300 for (i = 0; i < spclen; i ++)
9301 {
9302 d = spcarray[i].ToString();
9303 if (d.Length > 0)
9304 {
9305 delarray[dellen++] = d;
9306 }
9307 }
8688 9308
8689 // Scan for separators 9309 /*
9310 * Scan through source string from beginning to end.
9311 */
9312 for (i = 0;;)
9313 {
8690 9314
8691 for (j = 0; j < seplen; j++) 9315 /*
9316 * Find earliest delimeter in src starting at i (if any).
9317 */
9318 int earliestDel = -1;
9319 int earliestSrc = srclen;
9320 string earliestStr = null;
9321 for (j = 0; j < dellen; j ++)
8692 { 9322 {
8693 if (separray[j].ToString() == String.Empty) 9323 d = delarray[j];
8694 active[j] = false; 9324 if (d != null)
8695
8696 if (active[j])
8697 { 9325 {
8698 // scan all of the markers 9326 int index = src.IndexOf(d, i);
8699 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9327 if (index < 0)
8700 { 9328 {
8701 // not present at all 9329 delarray[j] = null; // delim nowhere in src, don't check it anymore
8702 active[j] = false;
8703 } 9330 }
8704 else 9331 else if (index < earliestSrc)
8705 { 9332 {
8706 // present and correct 9333 earliestSrc = index; // where delimeter starts in source string
8707 if (offset[j] < offset[best]) 9334 earliestDel = j; // where delimeter is in delarray[]
8708 { 9335 earliestStr = d; // the delimeter string from delarray[]
8709 // closest so far 9336 if (index == i) break; // can't do any better than found at beg of string
8710 best = j;
8711 if (offset[best] == beginning)
8712 break;
8713 }
8714 } 9337 }
8715 } 9338 }
8716 } 9339 }
8717 9340
8718 // Scan for spacers 9341 /*
8719 9342 * Output source string starting at i through start of earliest delimeter.
8720 if (offset[best] != beginning) 9343 */
9344 if (keepNulls || (earliestSrc > i))
8721 { 9345 {
8722 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9346 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8723 {
8724 if (spcarray[j-seplen].ToString() == String.Empty)
8725 active[j] = false;
8726
8727 if (active[j])
8728 {
8729 // scan all of the markers
8730 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8731 {
8732 // not present at all
8733 active[j] = false;
8734 }
8735 else
8736 {
8737 // present and correct
8738 if (offset[j] < offset[best])
8739 {
8740 // closest so far
8741 best = j;
8742 }
8743 }
8744 }
8745 }
8746 } 9347 }
8747 9348
8748 // This is the normal exit from the scanning loop 9349 /*
9350 * If no delimeter found at or after i, we're done scanning.
9351 */
9352 if (earliestDel < 0) break;
8749 9353
8750 if (best == mlen) 9354 /*
9355 * If delimeter was a spacer, output the spacer.
9356 */
9357 if (earliestDel >= seplen)
8751 { 9358 {
8752 // no markers were found on this pass 9359 outarray[outlen++] = earliestStr;
8753 // so we're pretty much done
8754 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8755 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8756 break;
8757 } 9360 }
8758 9361
8759 // Otherwise we just add the newly delimited token 9362 /*
8760 // and recalculate where the search should continue. 9363 * Look at rest of src string following delimeter.
8761 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9364 */
8762 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9365 i = earliestSrc + earliestStr.Length;
8763
8764 if (best < seplen)
8765 {
8766 beginning = offset[best] + (separray[best].ToString()).Length;
8767 }
8768 else
8769 {
8770 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8771 string str = spcarray[best - seplen].ToString();
8772 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8773 tokens.Add(new LSL_String(str));
8774 }
8775 } 9366 }
8776 9367
8777 // This an awkward an not very intuitive boundary case. If the 9368 /*
8778 // last substring is a tokenizer, then there is an implied trailing 9369 * Make up an exact-sized output array suitable for an LSL_List object.
8779 // null list entry. Hopefully the single comparison will not be too 9370 */
8780 // arduous. Alternatively the 'break' could be replced with a return 9371 object[] outlist = new object[outlen];
8781 // but that's shabby programming. 9372 for (i = 0; i < outlen; i ++)
8782
8783 if ((beginning == srclen) && (keepNulls))
8784 { 9373 {
8785 if (srclen != 0) 9374 outlist[i] = new LSL_String(outarray[i]);
8786 tokens.Add(new LSL_String(""));
8787 } 9375 }
8788 9376 return new LSL_List(outlist);
8789 return tokens;
8790 }
8791
8792 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8793 {
8794 m_host.AddScriptLPS(1);
8795 return this.ParseString(src, separators, spacers, false);
8796 }
8797
8798 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8799 {
8800 m_host.AddScriptLPS(1);
8801 return this.ParseString(src, separators, spacers, true);
8802 } 9377 }
8803 9378
8804 public LSL_Integer llGetObjectPermMask(int mask) 9379 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8875,28 +9450,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8875 { 9450 {
8876 m_host.AddScriptLPS(1); 9451 m_host.AddScriptLPS(1);
8877 9452
8878 lock (m_host.TaskInventory) 9453 m_host.TaskInventory.LockItemsForRead(true);
9454 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8879 { 9455 {
8880 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9456 if (inv.Value.Name == item)
8881 { 9457 {
8882 if (inv.Value.Name == item) 9458 m_host.TaskInventory.LockItemsForRead(false);
9459 switch (mask)
8883 { 9460 {
8884 switch (mask) 9461 case 0:
8885 { 9462 return (int)inv.Value.BasePermissions;
8886 case 0: 9463 case 1:
8887 return (int)inv.Value.BasePermissions; 9464 return (int)inv.Value.CurrentPermissions;
8888 case 1: 9465 case 2:
8889 return (int)inv.Value.CurrentPermissions; 9466 return (int)inv.Value.GroupPermissions;
8890 case 2: 9467 case 3:
8891 return (int)inv.Value.GroupPermissions; 9468 return (int)inv.Value.EveryonePermissions;
8892 case 3: 9469 case 4:
8893 return (int)inv.Value.EveryonePermissions; 9470 return (int)inv.Value.NextPermissions;
8894 case 4:
8895 return (int)inv.Value.NextPermissions;
8896 }
8897 } 9471 }
8898 } 9472 }
8899 } 9473 }
9474 m_host.TaskInventory.LockItemsForRead(false);
8900 9475
8901 return -1; 9476 return -1;
8902 } 9477 }
@@ -8943,16 +9518,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8943 { 9518 {
8944 m_host.AddScriptLPS(1); 9519 m_host.AddScriptLPS(1);
8945 9520
8946 lock (m_host.TaskInventory) 9521 m_host.TaskInventory.LockItemsForRead(true);
9522 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8947 { 9523 {
8948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9524 if (inv.Value.Name == item)
8949 { 9525 {
8950 if (inv.Value.Name == item) 9526 m_host.TaskInventory.LockItemsForRead(false);
8951 { 9527 return inv.Value.CreatorID.ToString();
8952 return inv.Value.CreatorID.ToString();
8953 }
8954 } 9528 }
8955 } 9529 }
9530 m_host.TaskInventory.LockItemsForRead(false);
8956 9531
8957 llSay(0, "No item name '" + item + "'"); 9532 llSay(0, "No item name '" + item + "'");
8958 9533
@@ -9100,7 +9675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9100 } 9675 }
9101 9676
9102 /// <summary> 9677 /// <summary>
9103 /// illListReplaceList removes the sub-list defined by the inclusive indices 9678 /// llListReplaceList removes the sub-list defined by the inclusive indices
9104 /// start and end and inserts the src list in its place. The inclusive 9679 /// start and end and inserts the src list in its place. The inclusive
9105 /// nature of the indices means that at least one element must be deleted 9680 /// nature of the indices means that at least one element must be deleted
9106 /// if the indices are within the bounds of the existing list. I.e. 2,2 9681 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9157,16 +9732,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9157 // based upon end. Note that if end exceeds the upper 9732 // based upon end. Note that if end exceeds the upper
9158 // bound in this case, the entire destination list 9733 // bound in this case, the entire destination list
9159 // is removed. 9734 // is removed.
9160 else 9735 else if (start == 0)
9161 { 9736 {
9162 if (end + 1 < dest.Length) 9737 if (end + 1 < dest.Length)
9163 {
9164 return src + dest.GetSublist(end + 1, -1); 9738 return src + dest.GetSublist(end + 1, -1);
9165 }
9166 else 9739 else
9167 {
9168 return src; 9740 return src;
9169 } 9741 }
9742 else // Start < 0
9743 {
9744 if (end + 1 < dest.Length)
9745 return dest.GetSublist(end + 1, -1);
9746 else
9747 return new LSL_List();
9170 } 9748 }
9171 } 9749 }
9172 // Finally, if start > end, we strip away a prefix and 9750 // Finally, if start > end, we strip away a prefix and
@@ -9217,17 +9795,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9217 int width = 0; 9795 int width = 0;
9218 int height = 0; 9796 int height = 0;
9219 9797
9220 ParcelMediaCommandEnum? commandToSend = null; 9798 uint commandToSend = 0;
9221 float time = 0.0f; // default is from start 9799 float time = 0.0f; // default is from start
9222 9800
9223 ScenePresence presence = null; 9801 ScenePresence presence = null;
9224 9802
9225 for (int i = 0; i < commandList.Data.Length; i++) 9803 for (int i = 0; i < commandList.Data.Length; i++)
9226 { 9804 {
9227 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9805 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9228 switch (command) 9806 switch (command)
9229 { 9807 {
9230 case ParcelMediaCommandEnum.Agent: 9808 case (uint)ParcelMediaCommandEnum.Agent:
9231 // we send only to one agent 9809 // we send only to one agent
9232 if ((i + 1) < commandList.Length) 9810 if ((i + 1) < commandList.Length)
9233 { 9811 {
@@ -9244,25 +9822,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9244 } 9822 }
9245 break; 9823 break;
9246 9824
9247 case ParcelMediaCommandEnum.Loop: 9825 case (uint)ParcelMediaCommandEnum.Loop:
9248 loop = 1; 9826 loop = 1;
9249 commandToSend = command; 9827 commandToSend = command;
9250 update = true; //need to send the media update packet to set looping 9828 update = true; //need to send the media update packet to set looping
9251 break; 9829 break;
9252 9830
9253 case ParcelMediaCommandEnum.Play: 9831 case (uint)ParcelMediaCommandEnum.Play:
9254 loop = 0; 9832 loop = 0;
9255 commandToSend = command; 9833 commandToSend = command;
9256 update = true; //need to send the media update packet to make sure it doesn't loop 9834 update = true; //need to send the media update packet to make sure it doesn't loop
9257 break; 9835 break;
9258 9836
9259 case ParcelMediaCommandEnum.Pause: 9837 case (uint)ParcelMediaCommandEnum.Pause:
9260 case ParcelMediaCommandEnum.Stop: 9838 case (uint)ParcelMediaCommandEnum.Stop:
9261 case ParcelMediaCommandEnum.Unload: 9839 case (uint)ParcelMediaCommandEnum.Unload:
9262 commandToSend = command; 9840 commandToSend = command;
9263 break; 9841 break;
9264 9842
9265 case ParcelMediaCommandEnum.Url: 9843 case (uint)ParcelMediaCommandEnum.Url:
9266 if ((i + 1) < commandList.Length) 9844 if ((i + 1) < commandList.Length)
9267 { 9845 {
9268 if (commandList.Data[i + 1] is LSL_String) 9846 if (commandList.Data[i + 1] is LSL_String)
@@ -9275,7 +9853,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9275 } 9853 }
9276 break; 9854 break;
9277 9855
9278 case ParcelMediaCommandEnum.Texture: 9856 case (uint)ParcelMediaCommandEnum.Texture:
9279 if ((i + 1) < commandList.Length) 9857 if ((i + 1) < commandList.Length)
9280 { 9858 {
9281 if (commandList.Data[i + 1] is LSL_String) 9859 if (commandList.Data[i + 1] is LSL_String)
@@ -9288,7 +9866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9288 } 9866 }
9289 break; 9867 break;
9290 9868
9291 case ParcelMediaCommandEnum.Time: 9869 case (uint)ParcelMediaCommandEnum.Time:
9292 if ((i + 1) < commandList.Length) 9870 if ((i + 1) < commandList.Length)
9293 { 9871 {
9294 if (commandList.Data[i + 1] is LSL_Float) 9872 if (commandList.Data[i + 1] is LSL_Float)
@@ -9300,7 +9878,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9300 } 9878 }
9301 break; 9879 break;
9302 9880
9303 case ParcelMediaCommandEnum.AutoAlign: 9881 case (uint)ParcelMediaCommandEnum.AutoAlign:
9304 if ((i + 1) < commandList.Length) 9882 if ((i + 1) < commandList.Length)
9305 { 9883 {
9306 if (commandList.Data[i + 1] is LSL_Integer) 9884 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9314,7 +9892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9314 } 9892 }
9315 break; 9893 break;
9316 9894
9317 case ParcelMediaCommandEnum.Type: 9895 case (uint)ParcelMediaCommandEnum.Type:
9318 if ((i + 1) < commandList.Length) 9896 if ((i + 1) < commandList.Length)
9319 { 9897 {
9320 if (commandList.Data[i + 1] is LSL_String) 9898 if (commandList.Data[i + 1] is LSL_String)
@@ -9327,7 +9905,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9327 } 9905 }
9328 break; 9906 break;
9329 9907
9330 case ParcelMediaCommandEnum.Desc: 9908 case (uint)ParcelMediaCommandEnum.Desc:
9331 if ((i + 1) < commandList.Length) 9909 if ((i + 1) < commandList.Length)
9332 { 9910 {
9333 if (commandList.Data[i + 1] is LSL_String) 9911 if (commandList.Data[i + 1] is LSL_String)
@@ -9340,7 +9918,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9340 } 9918 }
9341 break; 9919 break;
9342 9920
9343 case ParcelMediaCommandEnum.Size: 9921 case (uint)ParcelMediaCommandEnum.Size:
9344 if ((i + 2) < commandList.Length) 9922 if ((i + 2) < commandList.Length)
9345 { 9923 {
9346 if (commandList.Data[i + 1] is LSL_Integer) 9924 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9410,7 +9988,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9410 } 9988 }
9411 } 9989 }
9412 9990
9413 if (commandToSend != null) 9991 if (commandToSend != 0)
9414 { 9992 {
9415 // the commandList contained a start/stop/... command, too 9993 // the commandList contained a start/stop/... command, too
9416 if (presence == null) 9994 if (presence == null)
@@ -9447,7 +10025,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9447 10025
9448 if (aList.Data[i] != null) 10026 if (aList.Data[i] != null)
9449 { 10027 {
9450 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10028 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9451 { 10029 {
9452 case ParcelMediaCommandEnum.Url: 10030 case ParcelMediaCommandEnum.Url:
9453 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10031 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9490,16 +10068,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9490 { 10068 {
9491 m_host.AddScriptLPS(1); 10069 m_host.AddScriptLPS(1);
9492 10070
9493 lock (m_host.TaskInventory) 10071 m_host.TaskInventory.LockItemsForRead(true);
10072 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9494 { 10073 {
9495 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10074 if (inv.Value.Name == name)
9496 { 10075 {
9497 if (inv.Value.Name == name) 10076 m_host.TaskInventory.LockItemsForRead(false);
9498 { 10077 return inv.Value.Type;
9499 return inv.Value.Type;
9500 }
9501 } 10078 }
9502 } 10079 }
10080 m_host.TaskInventory.LockItemsForRead(false);
9503 10081
9504 return -1; 10082 return -1;
9505 } 10083 }
@@ -9510,15 +10088,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9510 10088
9511 if (quick_pay_buttons.Data.Length < 4) 10089 if (quick_pay_buttons.Data.Length < 4)
9512 { 10090 {
9513 LSLError("List must have at least 4 elements"); 10091 int x;
9514 return; 10092 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10093 {
10094 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10095 }
9515 } 10096 }
9516 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10097 int[] nPrice = new int[5];
9517 10098 nPrice[0] = price;
9518 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10099 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9519 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10100 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9520 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10101 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9521 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10102 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10103 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9522 m_host.ParentGroup.HasGroupChanged = true; 10104 m_host.ParentGroup.HasGroupChanged = true;
9523 } 10105 }
9524 10106
@@ -9530,17 +10112,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9530 if (invItemID == UUID.Zero) 10112 if (invItemID == UUID.Zero)
9531 return new LSL_Vector(); 10113 return new LSL_Vector();
9532 10114
9533 lock (m_host.TaskInventory) 10115 m_host.TaskInventory.LockItemsForRead(true);
10116 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9534 { 10117 {
9535 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10118 m_host.TaskInventory.LockItemsForRead(false);
9536 return new LSL_Vector(); 10119 return new LSL_Vector();
10120 }
9537 10121
9538 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10122 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9539 { 10123 {
9540 ShoutError("No permissions to track the camera"); 10124 ShoutError("No permissions to track the camera");
9541 return new LSL_Vector(); 10125 m_host.TaskInventory.LockItemsForRead(false);
9542 } 10126 return new LSL_Vector();
9543 } 10127 }
10128 m_host.TaskInventory.LockItemsForRead(false);
9544 10129
9545 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10130 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9546 if (presence != null) 10131 if (presence != null)
@@ -9558,17 +10143,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 if (invItemID == UUID.Zero) 10143 if (invItemID == UUID.Zero)
9559 return new LSL_Rotation(); 10144 return new LSL_Rotation();
9560 10145
9561 lock (m_host.TaskInventory) 10146 m_host.TaskInventory.LockItemsForRead(true);
10147 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9562 { 10148 {
9563 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10149 m_host.TaskInventory.LockItemsForRead(false);
9564 return new LSL_Rotation(); 10150 return new LSL_Rotation();
9565
9566 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9567 {
9568 ShoutError("No permissions to track the camera");
9569 return new LSL_Rotation();
9570 }
9571 } 10151 }
10152 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10153 {
10154 ShoutError("No permissions to track the camera");
10155 m_host.TaskInventory.LockItemsForRead(false);
10156 return new LSL_Rotation();
10157 }
10158 m_host.TaskInventory.LockItemsForRead(false);
9572 10159
9573 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10160 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9574 if (presence != null) 10161 if (presence != null)
@@ -9630,8 +10217,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 { 10217 {
9631 m_host.AddScriptLPS(1); 10218 m_host.AddScriptLPS(1);
9632 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10219 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9633 if (detectedParams == null) return; // only works on the first detected avatar 10220 if (detectedParams == null)
9634 10221 {
10222 if (m_host.ParentGroup.IsAttachment == true)
10223 {
10224 detectedParams = new DetectParams();
10225 detectedParams.Key = m_host.OwnerID;
10226 }
10227 else
10228 {
10229 return;
10230 }
10231 }
10232
9635 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10233 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9636 if (avatar != null) 10234 if (avatar != null)
9637 { 10235 {
@@ -9639,6 +10237,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9639 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10237 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9640 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10238 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9641 } 10239 }
10240
9642 ScriptSleep(1000); 10241 ScriptSleep(1000);
9643 } 10242 }
9644 10243
@@ -9731,14 +10330,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9731 if (objectID == UUID.Zero) return; 10330 if (objectID == UUID.Zero) return;
9732 10331
9733 UUID agentID; 10332 UUID agentID;
9734 lock (m_host.TaskInventory) 10333 m_host.TaskInventory.LockItemsForRead(true);
9735 { 10334 // we need the permission first, to know which avatar we want to set the camera for
9736 // we need the permission first, to know which avatar we want to set the camera for 10335 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9737 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9738 10336
9739 if (agentID == UUID.Zero) return; 10337 if (agentID == UUID.Zero)
9740 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10338 {
10339 m_host.TaskInventory.LockItemsForRead(false);
10340 return;
10341 }
10342 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10343 {
10344 m_host.TaskInventory.LockItemsForRead(false);
10345 return;
9741 } 10346 }
10347 m_host.TaskInventory.LockItemsForRead(false);
9742 10348
9743 ScenePresence presence = World.GetScenePresence(agentID); 10349 ScenePresence presence = World.GetScenePresence(agentID);
9744 10350
@@ -9747,12 +10353,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9747 10353
9748 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10354 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9749 object[] data = rules.Data; 10355 object[] data = rules.Data;
9750 for (int i = 0; i < data.Length; ++i) { 10356 for (int i = 0; i < data.Length; ++i)
10357 {
9751 int type = Convert.ToInt32(data[i++].ToString()); 10358 int type = Convert.ToInt32(data[i++].ToString());
9752 if (i >= data.Length) break; // odd number of entries => ignore the last 10359 if (i >= data.Length) break; // odd number of entries => ignore the last
9753 10360
9754 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10361 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9755 switch (type) { 10362 switch (type)
10363 {
9756 case ScriptBaseClass.CAMERA_FOCUS: 10364 case ScriptBaseClass.CAMERA_FOCUS:
9757 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10365 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9758 case ScriptBaseClass.CAMERA_POSITION: 10366 case ScriptBaseClass.CAMERA_POSITION:
@@ -9788,12 +10396,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9788 10396
9789 // we need the permission first, to know which avatar we want to clear the camera for 10397 // we need the permission first, to know which avatar we want to clear the camera for
9790 UUID agentID; 10398 UUID agentID;
9791 lock (m_host.TaskInventory) 10399 m_host.TaskInventory.LockItemsForRead(true);
10400 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10401 if (agentID == UUID.Zero)
9792 { 10402 {
9793 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10403 m_host.TaskInventory.LockItemsForRead(false);
9794 if (agentID == UUID.Zero) return; 10404 return;
9795 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10405 }
10406 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10407 {
10408 m_host.TaskInventory.LockItemsForRead(false);
10409 return;
9796 } 10410 }
10411 m_host.TaskInventory.LockItemsForRead(false);
9797 10412
9798 ScenePresence presence = World.GetScenePresence(agentID); 10413 ScenePresence presence = World.GetScenePresence(agentID);
9799 10414
@@ -9860,19 +10475,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9860 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10475 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9861 { 10476 {
9862 m_host.AddScriptLPS(1); 10477 m_host.AddScriptLPS(1);
9863 string ret = String.Empty; 10478
9864 string src1 = llBase64ToString(str1); 10479 if (str1 == String.Empty)
9865 string src2 = llBase64ToString(str2); 10480 return String.Empty;
9866 int c = 0; 10481 if (str2 == String.Empty)
9867 for (int i = 0; i < src1.Length; i++) 10482 return str1;
10483
10484 int len = str2.Length;
10485 if ((len % 4) != 0) // LL is EVIL!!!!
9868 { 10486 {
9869 ret += (char) (src1[i] ^ src2[c]); 10487 while (str2.EndsWith("="))
10488 str2 = str2.Substring(0, str2.Length - 1);
10489
10490 len = str2.Length;
10491 int mod = len % 4;
10492
10493 if (mod == 1)
10494 str2 = str2.Substring(0, str2.Length - 1);
10495 else if (mod == 2)
10496 str2 += "==";
10497 else if (mod == 3)
10498 str2 += "=";
10499 }
9870 10500
9871 c++; 10501 byte[] data1;
9872 if (c >= src2.Length) 10502 byte[] data2;
9873 c = 0; 10503 try
10504 {
10505 data1 = Convert.FromBase64String(str1);
10506 data2 = Convert.FromBase64String(str2);
9874 } 10507 }
9875 return llStringToBase64(ret); 10508 catch (Exception)
10509 {
10510 return new LSL_String(String.Empty);
10511 }
10512
10513 byte[] d2 = new Byte[data1.Length];
10514 int pos = 0;
10515
10516 if (data1.Length <= data2.Length)
10517 {
10518 Array.Copy(data2, 0, d2, 0, data1.Length);
10519 }
10520 else
10521 {
10522 while (pos < data1.Length)
10523 {
10524 len = data1.Length - pos;
10525 if (len > data2.Length)
10526 len = data2.Length;
10527
10528 Array.Copy(data2, 0, d2, pos, len);
10529 pos += len;
10530 }
10531 }
10532
10533 for (pos = 0 ; pos < data1.Length ; pos++ )
10534 data1[pos] ^= d2[pos];
10535
10536 return Convert.ToBase64String(data1);
9876 } 10537 }
9877 10538
9878 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10539 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9929,12 +10590,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9929 Regex r = new Regex(authregex); 10590 Regex r = new Regex(authregex);
9930 int[] gnums = r.GetGroupNumbers(); 10591 int[] gnums = r.GetGroupNumbers();
9931 Match m = r.Match(url); 10592 Match m = r.Match(url);
9932 if (m.Success) { 10593 if (m.Success)
9933 for (int i = 1; i < gnums.Length; i++) { 10594 {
10595 for (int i = 1; i < gnums.Length; i++)
10596 {
9934 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10597 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9935 //CaptureCollection cc = g.Captures; 10598 //CaptureCollection cc = g.Captures;
9936 } 10599 }
9937 if (m.Groups.Count == 5) { 10600 if (m.Groups.Count == 5)
10601 {
9938 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10602 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9939 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10603 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9940 } 10604 }
@@ -10220,15 +10884,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10220 10884
10221 internal UUID ScriptByName(string name) 10885 internal UUID ScriptByName(string name)
10222 { 10886 {
10223 lock (m_host.TaskInventory) 10887 m_host.TaskInventory.LockItemsForRead(true);
10888
10889 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10224 { 10890 {
10225 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10891 if (item.Type == 10 && item.Name == name)
10226 { 10892 {
10227 if (item.Type == 10 && item.Name == name) 10893 m_host.TaskInventory.LockItemsForRead(false);
10228 return item.ItemID; 10894 return item.ItemID;
10229 } 10895 }
10230 } 10896 }
10231 10897
10898 m_host.TaskInventory.LockItemsForRead(false);
10899
10232 return UUID.Zero; 10900 return UUID.Zero;
10233 } 10901 }
10234 10902
@@ -10269,6 +10937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10269 { 10937 {
10270 m_host.AddScriptLPS(1); 10938 m_host.AddScriptLPS(1);
10271 10939
10940 //Clone is thread safe
10272 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10941 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10273 10942
10274 UUID assetID = UUID.Zero; 10943 UUID assetID = UUID.Zero;
@@ -10331,6 +11000,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10331 { 11000 {
10332 m_host.AddScriptLPS(1); 11001 m_host.AddScriptLPS(1);
10333 11002
11003 //Clone is thread safe
10334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11004 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10335 11005
10336 UUID assetID = UUID.Zero; 11006 UUID assetID = UUID.Zero;
@@ -10411,15 +11081,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10411 return GetLinkPrimitiveParams(obj, rules); 11081 return GetLinkPrimitiveParams(obj, rules);
10412 } 11082 }
10413 11083
10414 public void print(string str) 11084 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10415 { 11085 {
10416 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11086 List<SceneObjectPart> parts = GetLinkParts(link);
10417 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11087 if (parts.Count < 1)
10418 if (ossl != null) 11088 return 0;
10419 { 11089
10420 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11090 return GetNumberOfSides(parts[0]);
10421 m_log.Info("LSL print():" + str);
10422 }
10423 } 11091 }
10424 11092
10425 private string Name2Username(string name) 11093 private string Name2Username(string name)
@@ -10465,6 +11133,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10465 return rq.ToString(); 11133 return rq.ToString();
10466 } 11134 }
10467 11135
11136 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11137 {
11138 m_SayShoutCount = 0;
11139 }
10468 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11140 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10469 { 11141 {
10470 m_host.AddScriptLPS(1); 11142 m_host.AddScriptLPS(1);
@@ -10634,22 +11306,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10634 NotImplemented("llGetSPMaxMemory"); 11306 NotImplemented("llGetSPMaxMemory");
10635 } 11307 }
10636 11308
10637 public void llGetUsedMemory() 11309 public virtual LSL_Integer llGetUsedMemory()
10638 { 11310 {
10639 m_host.AddScriptLPS(1); 11311 m_host.AddScriptLPS(1);
10640 NotImplemented("llGetUsedMemory"); 11312 NotImplemented("llGetUsedMemory");
11313 return 0;
10641 } 11314 }
10642 11315
10643 public void llScriptProfiler(LSL_Integer flags) 11316 public void llScriptProfiler(LSL_Integer flags)
10644 { 11317 {
10645 m_host.AddScriptLPS(1); 11318 m_host.AddScriptLPS(1);
10646 NotImplemented("llScriptProfiler"); 11319 //NotImplemented("llScriptProfiler");
10647 } 11320 }
10648 11321
10649 public void llSetSoundQueueing(int queue) 11322 public void llSetSoundQueueing(int queue)
10650 { 11323 {
10651 m_host.AddScriptLPS(1); 11324 m_host.AddScriptLPS(1);
10652 NotImplemented("llSetSoundQueueing");
10653 } 11325 }
10654 11326
10655 public void llCollisionSprite(string impact_sprite) 11327 public void llCollisionSprite(string impact_sprite)
@@ -10661,7 +11333,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10661 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11333 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10662 { 11334 {
10663 m_host.AddScriptLPS(1); 11335 m_host.AddScriptLPS(1);
10664 NotImplemented("llGodLikeRezObject"); 11336
11337 if (!World.Permissions.IsGod(m_host.OwnerID))
11338 NotImplemented("llGodLikeRezObject");
11339
11340 AssetBase rezAsset = World.AssetService.Get(inventory);
11341 if (rezAsset == null)
11342 {
11343 llSay(0, "Asset not found");
11344 return;
11345 }
11346
11347 SceneObjectGroup group = null;
11348
11349 try
11350 {
11351 string xmlData = Utils.BytesToString(rezAsset.Data);
11352 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11353 }
11354 catch
11355 {
11356 llSay(0, "Asset not found");
11357 return;
11358 }
11359
11360 if (group == null)
11361 {
11362 llSay(0, "Asset not found");
11363 return;
11364 }
11365
11366 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11367 group.RootPart.AttachOffset = group.AbsolutePosition;
11368
11369 group.ResetIDs();
11370
11371 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11372 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11373 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11374 group.ScheduleGroupForFullUpdate();
11375
11376 // objects rezzed with this method are die_at_edge by default.
11377 group.RootPart.SetDieAtEdge(true);
11378
11379 group.ResumeScripts();
11380
11381 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11382 "object_rez", new Object[] {
11383 new LSL_String(
11384 group.RootPart.UUID.ToString()) },
11385 new DetectParams[0]));
10665 } 11386 }
10666 11387
10667 #endregion 11388 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index f3206ac..c0d2f38 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -203,7 +205,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
203 205
204 internal void OSSLError(string msg) 206 internal void OSSLError(string msg)
205 { 207 {
206 throw new Exception("OSSL Runtime Error: " + msg); 208 if (m_debuggerSafe)
209 {
210 OSSLShoutError(msg);
211 }
212 else
213 {
214 throw new Exception("OSSL Runtime Error: " + msg);
215 }
207 } 216 }
208 217
209 private void InitLSL() 218 private void InitLSL()
@@ -894,18 +903,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
894 if (target != null) 903 if (target != null)
895 { 904 {
896 UUID animID=UUID.Zero; 905 UUID animID=UUID.Zero;
897 lock (m_host.TaskInventory) 906 m_host.TaskInventory.LockItemsForRead(true);
907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
898 { 908 {
899 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 909 if (inv.Value.Name == animation)
900 { 910 {
901 if (inv.Value.Name == animation) 911 if (inv.Value.Type == (int)AssetType.Animation)
902 { 912 animID = inv.Value.AssetID;
903 if (inv.Value.Type == (int)AssetType.Animation) 913 continue;
904 animID = inv.Value.AssetID;
905 continue;
906 }
907 } 914 }
908 } 915 }
916 m_host.TaskInventory.LockItemsForRead(false);
909 if (animID == UUID.Zero) 917 if (animID == UUID.Zero)
910 target.Animator.AddAnimation(animation, m_host.UUID); 918 target.Animator.AddAnimation(animation, m_host.UUID);
911 else 919 else
@@ -927,18 +935,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
927 if (target != null) 935 if (target != null)
928 { 936 {
929 UUID animID = UUID.Zero; 937 UUID animID = UUID.Zero;
930 lock (m_host.TaskInventory) 938 m_host.TaskInventory.LockItemsForRead(true);
939 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
931 { 940 {
932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 941 if (inv.Value.Name == animation)
933 { 942 {
934 if (inv.Value.Name == animation) 943 if (inv.Value.Type == (int)AssetType.Animation)
935 { 944 animID = inv.Value.AssetID;
936 if (inv.Value.Type == (int)AssetType.Animation) 945 continue;
937 animID = inv.Value.AssetID;
938 continue;
939 }
940 } 946 }
941 } 947 }
948 m_host.TaskInventory.LockItemsForRead(false);
942 949
943 if (animID == UUID.Zero) 950 if (animID == UUID.Zero)
944 target.Animator.RemoveAnimation(animation); 951 target.Animator.RemoveAnimation(animation);
@@ -1895,6 +1902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1895 1902
1896 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1903 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1897 { 1904 {
1905 m_host.TaskInventory.LockItemsForRead(true);
1898 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1899 { 1907 {
1900 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1908 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1902,6 +1910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1902 assetID = item.AssetID; 1910 assetID = item.AssetID;
1903 } 1911 }
1904 } 1912 }
1913 m_host.TaskInventory.LockItemsForRead(false);
1905 } 1914 }
1906 1915
1907 if (assetID == UUID.Zero) 1916 if (assetID == UUID.Zero)
@@ -2225,8 +2234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2225 UUID x = module.CreateNPC(firstname, 2234 UUID x = module.CreateNPC(firstname,
2226 lastname, 2235 lastname,
2227 new Vector3((float) position.x, (float) position.y, (float) position.z), 2236 new Vector3((float) position.x, (float) position.y, (float) position.z),
2228 World, 2237 World,appearance);
2229 appearance);
2230 2238
2231 return new LSL_Key(x.ToString()); 2239 return new LSL_Key(x.ToString());
2232 } 2240 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 4ac7f8b..6de0773 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -429,6 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 435 q = avatar.Rotation;
433 } 436 }
434 437
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..4ad4123 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -405,7 +406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 406 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 407 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 408 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 409 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 410
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 3221833..a61d553 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index ce4661c..a1cf3df 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -376,6 +377,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
376 public const int PRIM_SCULPT_TYPE_TORUS = 2; 377 public const int PRIM_SCULPT_TYPE_TORUS = 2;
377 public const int PRIM_SCULPT_TYPE_PLANE = 3; 378 public const int PRIM_SCULPT_TYPE_PLANE = 3;
378 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 379 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
380 public const int PRIM_SCULPT_FLAG_INVERT = 64;
381 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
379 382
380 public const int MASK_BASE = 0; 383 public const int MASK_BASE = 0;
381 public const int MASK_OWNER = 1; 384 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..a88a1f4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -464,6 +466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 466 return m_LSL_Functions.llGetFreeMemory();
465 } 467 }
466 468
469 public LSL_Integer llGetUsedMemory()
470 {
471 return m_LSL_Functions.llGetUsedMemory();
472 }
473
467 public LSL_Integer llGetFreeURLs() 474 public LSL_Integer llGetFreeURLs()
468 { 475 {
469 return m_LSL_Functions.llGetFreeURLs(); 476 return m_LSL_Functions.llGetFreeURLs();
@@ -1878,9 +1885,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1885 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1886 }
1880 1887
1881 public void print(string str) 1888 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1889 {
1883 m_LSL_Functions.print(str); 1890 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1891 }
1885 } 1892 }
1886} 1893}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f9af9c1..9ff2e4d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -263,13 +264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
263 264
264 if (part != null) 265 if (part != null)
265 { 266 {
266 lock (part.TaskInventory) 267 part.TaskInventory.LockItemsForRead(true);
268 if (part.TaskInventory.ContainsKey(m_ItemID))
267 { 269 {
268 if (part.TaskInventory.ContainsKey(m_ItemID)) 270 m_thisScriptTask = part.TaskInventory[m_ItemID];
269 {
270 m_thisScriptTask = part.TaskInventory[m_ItemID];
271 }
272 } 271 }
272 part.TaskInventory.LockItemsForRead(false);
273 } 273 }
274 274
275 ApiManager am = new ApiManager(); 275 ApiManager am = new ApiManager();
@@ -296,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 297// lease.Register(this);
298 } 298 }
299 catch (Exception) 299 catch (Exception e)
300 { 300 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
302 } 303 }
303 304
304 try 305 try
@@ -459,14 +460,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
459 { 460 {
460 int permsMask; 461 int permsMask;
461 UUID permsGranter; 462 UUID permsGranter;
462 lock (part.TaskInventory) 463 part.TaskInventory.LockItemsForRead(true);
464 if (!part.TaskInventory.ContainsKey(m_ItemID))
463 { 465 {
464 if (!part.TaskInventory.ContainsKey(m_ItemID)) 466 part.TaskInventory.LockItemsForRead(false);
465 return; 467 return;
466
467 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
468 permsMask = part.TaskInventory[m_ItemID].PermsMask;
469 } 468 }
469 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
470 permsMask = part.TaskInventory[m_ItemID].PermsMask;
471 part.TaskInventory.LockItemsForRead(false);
470 472
471 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 473 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 { 474 {
@@ -575,6 +577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 return true; 577 return true;
576 } 578 }
577 579
580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
578 public void SetState(string state) 581 public void SetState(string state)
579 { 582 {
580 if (state == State) 583 if (state == State)
@@ -586,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
586 new DetectParams[0])); 589 new DetectParams[0]));
587 PostEvent(new EventParams("state_entry", new Object[0], 590 PostEvent(new EventParams("state_entry", new Object[0],
588 new DetectParams[0])); 591 new DetectParams[0]));
589 592
590 throw new EventAbortException(); 593 throw new EventAbortException();
591 } 594 }
592 595
@@ -669,41 +672,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
669 /// <returns></returns> 672 /// <returns></returns>
670 public object EventProcessor() 673 public object EventProcessor()
671 { 674 {
672 lock (m_Script) 675 EventParams data = null;
673 {
674// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
675 676
676 if (Suspended) 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
677 return 0;
678 678
679 EventParams data = null; 679 if (Suspended)
680 return 0;
680 681
681 lock (m_EventQueue) 682 lock (m_EventQueue)
683 {
684 data = (EventParams) m_EventQueue.Dequeue();
685 if (data == null) // Shouldn't happen
682 { 686 {
683 data = (EventParams) m_EventQueue.Dequeue(); 687 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
684 if (data == null) // Shouldn't happen
685 { 688 {
686 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 689 m_CurrentResult = m_Engine.QueueEventHandler(this);
687 {
688 m_CurrentResult = m_Engine.QueueEventHandler(this);
689 }
690 else
691 {
692 m_CurrentResult = null;
693 }
694 return 0;
695 } 690 }
696 691 else
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 { 692 {
701 if (m_ControlEventsInQueue > 0) 693 m_CurrentResult = null;
702 m_ControlEventsInQueue--;
703 } 694 }
704 if (data.EventName == "collision") 695 return 0;
705 m_CollisionInQueue = false; 696 }
697
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 {
702 if (m_ControlEventsInQueue > 0)
703 m_ControlEventsInQueue--;
706 } 704 }
705 if (data.EventName == "collision")
706 m_CollisionInQueue = false;
707 }
708
709 lock(m_Script)
710 {
707 711
708// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 713
@@ -860,6 +864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 864 new Object[0], new DetectParams[0]));
861 } 865 }
862 866
867 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 868 public void ApiResetScript()
864 { 869 {
865 // bool running = Running; 870 // bool running = Running;
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {