aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2252
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
6 files changed, 1684 insertions, 791 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 070cdc0..4f21c67 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -275,40 +344,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
275 protected UUID InventorySelf() 344 protected UUID InventorySelf()
276 { 345 {
277 UUID invItemID = new UUID(); 346 UUID invItemID = new UUID();
278 347 bool unlock = false;
279 lock (m_host.TaskInventory) 348 if (!m_host.TaskInventory.IsReadLockedByMe())
349 {
350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
280 { 354 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
282 { 356 {
283 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 357 invItemID = inv.Key;
284 { 358 break;
285 invItemID = inv.Key;
286 break;
287 }
288 } 359 }
289 } 360 }
290 361 if (unlock)
362 {
363 m_host.TaskInventory.LockItemsForRead(false);
364 }
291 return invItemID; 365 return invItemID;
292 } 366 }
293 367
294 protected UUID InventoryKey(string name, int type) 368 protected UUID InventoryKey(string name, int type)
295 { 369 {
296 m_host.AddScriptLPS(1); 370 m_host.AddScriptLPS(1);
297 371 m_host.TaskInventory.LockItemsForRead(true);
298 lock (m_host.TaskInventory) 372
373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
299 { 374 {
300 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 375 if (inv.Value.Name == name)
301 { 376 {
302 if (inv.Value.Name == name) 377 m_host.TaskInventory.LockItemsForRead(false);
378
379 if (inv.Value.Type != type)
303 { 380 {
304 if (inv.Value.Type != type) 381 return UUID.Zero;
305 return UUID.Zero;
306
307 return inv.Value.AssetID;
308 } 382 }
383
384 return inv.Value.AssetID;
309 } 385 }
310 } 386 }
311 387
388 m_host.TaskInventory.LockItemsForRead(false);
312 return UUID.Zero; 389 return UUID.Zero;
313 } 390 }
314 391
@@ -316,17 +393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 { 393 {
317 m_host.AddScriptLPS(1); 394 m_host.AddScriptLPS(1);
318 395
319 lock (m_host.TaskInventory) 396
397 m_host.TaskInventory.LockItemsForRead(true);
398
399 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
320 { 400 {
321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 401 if (inv.Value.Name == name)
322 { 402 {
323 if (inv.Value.Name == name) 403 m_host.TaskInventory.LockItemsForRead(false);
324 { 404 return inv.Value.AssetID;
325 return inv.Value.AssetID;
326 }
327 } 405 }
328 } 406 }
329 407
408 m_host.TaskInventory.LockItemsForRead(false);
409
410
330 return UUID.Zero; 411 return UUID.Zero;
331 } 412 }
332 413
@@ -468,26 +549,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 549
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 550 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 551
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 552 // Utility function for llRot2Euler
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 553
554 // normalize an angle between -PI and PI (-180 to +180 degrees)
555 protected double NormalizeAngle(double angle)
556 {
557 if (angle > -Math.PI && angle < Math.PI)
558 return angle;
559
560 int numPis = (int)(Math.PI / angle);
561 double remainder = angle - Math.PI * numPis;
562 if (numPis % 2 == 1)
563 return Math.PI - angle;
564 return remainder;
565 }
473 566
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
475 { 568 {
476 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
479 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
480 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
481 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
482 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
483 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 577 double test = q1.x*q1.z + q1.y*q1.s;
485 Math.Atan2(n, Math.Sqrt(p)), 578 if (test > 0.4999*unit) { // singularity at north pole
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
487 else if (n > 0) 580 eul.y = Math.PI/2;
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 581 eul.x = 0;
489 else 582 return eul;
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
491 } 594 }
492 595
493 /* From wiki: 596 /* From wiki:
@@ -689,77 +792,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 792 {
690 //A and B should both be normalized 793 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 794 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 795 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 796 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 797
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 798 double dotProduct = LSL_Vector.Dot(a, b);
799 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
800 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
801 double angle = Math.Acos(dotProduct / magProduct);
802 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
803 double s = Math.Sin(angle / 2);
804
805 double x = axis.x * s;
806 double y = axis.y * s;
807 double z = axis.z * s;
808 double w = Math.Cos(angle / 2);
809
810 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812
813 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
814 */
815
816 // This method mimics the 180 errors found in SL
817 // See www.euclideanspace.com... angleBetween
818 LSL_Vector vec_a = a;
819 LSL_Vector vec_b = b;
820
821 // Eliminate zero length
822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
824 if (vec_a_mag < 0.00001 ||
825 vec_b_mag < 0.00001)
696 { 826 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 828 }
699 else 829
830 // Normalize
831 vec_a = llVecNorm(vec_a);
832 vec_b = llVecNorm(vec_b);
833
834 // Calculate axis and rotation angle
835 LSL_Vector axis = vec_a % vec_b;
836 LSL_Float cos_theta = vec_a * vec_b;
837
838 // Check if parallel
839 if (cos_theta > 0.99999)
700 { 840 {
701 a = LSL_Vector.Norm(a); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 842 }
703 double dotProduct = LSL_Vector.Dot(a, b); 843
704 // There are two degenerate cases possible. These are for vectors 180 or 844 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 845 else if (cos_theta < -0.99999)
706 // 846 {
707 // Check for vectors 180 degrees apart. 847 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 850 }
711 // First assume X axis is orthogonal to the vectors. 851 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 852 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 853 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 854 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 855 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 856 s = Math.Cos(theta);
717 { 857 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 858 x = axis.x * t;
719 } 859 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 860 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 861 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 862 }
760 return rotBetween;
761 } 863 }
762 864
763 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
764 { 866 {
765 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -779,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 881 {
780 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
781 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 891 {
784 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -801,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 909 {
802 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
803 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
804 if (text.Length > 1023) 918 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
806 920
@@ -1101,10 +1215,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1215 return detectedParams.TouchUV;
1102 } 1216 }
1103 1217
1218 [DebuggerNonUserCode]
1104 public virtual void llDie() 1219 public virtual void llDie()
1105 { 1220 {
1106 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1223 }
1109 1224
1110 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1292
1178 public void llSetStatus(int status, int value) 1293 public void llSetStatus(int status, int value)
1179 { 1294 {
1295 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1296 return;
1180 m_host.AddScriptLPS(1); 1297 m_host.AddScriptLPS(1);
1181 1298
1182 int statusrotationaxis = 0; 1299 int statusrotationaxis = 0;
@@ -1406,6 +1523,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1523 {
1407 m_host.AddScriptLPS(1); 1524 m_host.AddScriptLPS(1);
1408 1525
1526 SetColor(m_host, color, face);
1527 }
1528
1529 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1530 {
1531 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1532 return;
1533
1534 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part))
1537 {
1538 texcolor = tex.CreateFace((uint)face).RGBA;
1539 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1542 tex.FaceTextures[face].RGBA = texcolor;
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546 else if (face == ScriptBaseClass.ALL_SIDES)
1547 {
1548 for (uint i = 0; i < GetNumberOfSides(part); i++)
1549 {
1550 if (tex.FaceTextures[i] != null)
1551 {
1552 texcolor = tex.FaceTextures[i].RGBA;
1553 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1554 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1555 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1556 tex.FaceTextures[i].RGBA = texcolor;
1557 }
1558 texcolor = tex.DefaultTexture.RGBA;
1559 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1560 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1562 tex.DefaultTexture.RGBA = texcolor;
1563 }
1564 part.UpdateTexture(tex);
1565 return;
1566 }
1567
1409 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1411 1570
@@ -1414,6 +1573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1573
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1574 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1575 {
1576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1577 return;
1578
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1579 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1580 MappingType textype;
1419 textype = MappingType.Default; 1581 textype = MappingType.Default;
@@ -1444,6 +1606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1606
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1607 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1608 {
1609 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1610 return;
1611
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1612 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1613 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1614 {
@@ -1469,6 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1634
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1635 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1636 {
1637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1638 return;
1472 1639
1473 Shininess sval = new Shininess(); 1640 Shininess sval = new Shininess();
1474 1641
@@ -1519,6 +1686,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1686
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1687 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1688 {
1689 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1690 return;
1691
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1692 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1693 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1694 {
@@ -1579,13 +1749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1580 1750
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1752 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1753 {
1584 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1585 } 1765 }
1586 1766
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1773 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1640 { 1823 {
1641 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1825 return;
1643 1826
1644 if (flexi) 1827 if (flexi)
@@ -1673,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1673 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1674 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1675 { 1858 {
1676 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return; 1860 return;
1678 1861
1679 if (light) 1862 if (light)
@@ -1750,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1751 1934
1752 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1753 1936 if (parts.Count > 0)
1754 foreach (SceneObjectPart part in parts) 1937 {
1755 SetTexture(part, texture, face); 1938 try
1756 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1757 ScriptSleep(200); 1949 ScriptSleep(200);
1758 } 1950 }
1759 1951
1760 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1761 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1762 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1763 1958
1764 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1803,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1998
1804 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1805 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1806 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1807 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1808 { 2006 {
@@ -1839,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1839 2037
1840 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1841 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1842 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1843 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1844 { 2045 {
@@ -1875,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 2076
1876 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1877 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1878 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1879 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1880 { 2084 {
@@ -1943,10 +2147,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1943 return end; 2147 return end;
1944 } 2148 }
1945 2149
1946 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2150 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1947 { 2151 {
2152 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2153 return fromPos;
2154
1948 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2155 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1949 LSL_Vector currentPos = GetPartLocalPos(part); 2156
1950 2157
1951 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2158 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1952 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2159 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1955,14 +2162,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1955 { 2162 {
1956 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2163 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1957 targetPos.z = ground; 2164 targetPos.z = ground;
2165 }
2166 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2167
2168 return real_vec;
2169 }
2170
2171 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2172 {
2173 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2174 return;
2175
2176 LSL_Vector currentPos = GetPartLocalPos(part);
2177 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2178
2179 if (part.ParentGroup.RootPart == part)
2180 {
1958 SceneObjectGroup parent = part.ParentGroup; 2181 SceneObjectGroup parent = part.ParentGroup;
1959 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2182 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1960 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1961 } 2183 }
1962 else 2184 else
1963 { 2185 {
1964 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2186 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1965 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1966 SceneObjectGroup parent = part.ParentGroup; 2187 SceneObjectGroup parent = part.ParentGroup;
1967 parent.HasGroupChanged = true; 2188 parent.HasGroupChanged = true;
1968 parent.ScheduleGroupForTerseUpdate(); 2189 parent.ScheduleGroupForTerseUpdate();
@@ -2013,9 +2234,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2013 m_host.AddScriptLPS(1); 2234 m_host.AddScriptLPS(1);
2014 2235
2015 // try to let this work as in SL... 2236 // try to let this work as in SL...
2016 if (m_host.ParentID == 0) 2237 if (m_host.LinkNum < 2)
2017 { 2238 {
2018 // special case: If we are root, rotate complete SOG to new rotation 2239 // Special case: If we are root, rotate complete SOG to new
2240 // rotation.
2241 // We are root if the link number is 0 (single prim) or 1
2242 // (root prim). ParentID may be nonzero in attachments and
2243 // using it would cause attachments and HUDs to rotate
2244 // to the wrong positions.
2019 SetRot(m_host, Rot2Quaternion(rot)); 2245 SetRot(m_host, Rot2Quaternion(rot));
2020 } 2246 }
2021 else 2247 else
@@ -2040,6 +2266,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2040 2266
2041 protected void SetRot(SceneObjectPart part, Quaternion rot) 2267 protected void SetRot(SceneObjectPart part, Quaternion rot)
2042 { 2268 {
2269 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2270 return;
2271
2043 part.UpdateRotation(rot); 2272 part.UpdateRotation(rot);
2044 // Update rotation does not move the object in the physics scene if it's a linkset. 2273 // Update rotation does not move the object in the physics scene if it's a linkset.
2045 2274
@@ -2665,12 +2894,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2665 2894
2666 m_host.AddScriptLPS(1); 2895 m_host.AddScriptLPS(1);
2667 2896
2897 m_host.TaskInventory.LockItemsForRead(true);
2668 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2898 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2669 2899 m_host.TaskInventory.LockItemsForRead(false);
2670 lock (m_host.TaskInventory)
2671 {
2672 item = m_host.TaskInventory[invItemID];
2673 }
2674 2900
2675 if (item.PermsGranter == UUID.Zero) 2901 if (item.PermsGranter == UUID.Zero)
2676 return 0; 2902 return 0;
@@ -2745,6 +2971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2745 if (dist > m_ScriptDistanceFactor * 10.0f) 2971 if (dist > m_ScriptDistanceFactor * 10.0f)
2746 return; 2972 return;
2747 2973
2974 //Clone is thread-safe
2748 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2975 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2749 2976
2750 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2977 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2805,6 +3032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2805 3032
2806 public void llLookAt(LSL_Vector target, double strength, double damping) 3033 public void llLookAt(LSL_Vector target, double strength, double damping)
2807 { 3034 {
3035 /*
2808 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
2809 // Determine where we are looking from 3037 // Determine where we are looking from
2810 LSL_Vector from = llGetPos(); 3038 LSL_Vector from = llGetPos();
@@ -2824,10 +3052,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 // the angles of rotation in radians into rotation value 3052 // the angles of rotation in radians into rotation value
2825 3053
2826 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3054 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2827 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3055
2828 m_host.startLookAt(rotation, (float)damping, (float)strength); 3056 // This would only work if your physics system contains an APID controller:
3057 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3058 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3059
2829 // Orient the object to the angle calculated 3060 // Orient the object to the angle calculated
2830 //llSetRot(rot); 3061 llSetRot(rot);
3062 */
3063
3064 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3065 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3066 // http://bugs.meta7.com/view.php?id=28
3067 // - Tom
3068
3069 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3070 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3071 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3072 */
3073 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3074 {
3075 // Part is non-phys, convert this to a llSetRot()
3076 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3077 Vector3 dir = tgt - m_host.GroupPosition;
3078 dir.Normalize();
3079 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3080 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3081 float terot = (float)Math.Atan2(-dir.Z, txy);
3082 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3083 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3084 LSL_Types.Quaternion spin = llEuler2Rot(az);
3085 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3086 llSetRot(rot);
3087 }
3088 else
3089 {
3090 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3091 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3092 m_host.RotLookAt(q, (float)strength, (float)damping);
3093 }
3094
3095 }
3096
3097 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3098 {
3099 m_host.AddScriptLPS(1);
3100// NotImplemented("llRotLookAt");
3101 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3102
2831 } 3103 }
2832 3104
2833 public void llStopLookAt() 3105 public void llStopLookAt()
@@ -2876,13 +3148,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2876 { 3148 {
2877 TaskInventoryItem item; 3149 TaskInventoryItem item;
2878 3150
2879 lock (m_host.TaskInventory) 3151 m_host.TaskInventory.LockItemsForRead(true);
3152 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2880 { 3153 {
2881 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3154 m_host.TaskInventory.LockItemsForRead(false);
2882 return; 3155 return;
2883 else
2884 item = m_host.TaskInventory[InventorySelf()];
2885 } 3156 }
3157 else
3158 {
3159 item = m_host.TaskInventory[InventorySelf()];
3160 }
3161 m_host.TaskInventory.LockItemsForRead(false);
2886 3162
2887 if (item.PermsGranter != UUID.Zero) 3163 if (item.PermsGranter != UUID.Zero)
2888 { 3164 {
@@ -2904,13 +3180,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2904 { 3180 {
2905 TaskInventoryItem item; 3181 TaskInventoryItem item;
2906 3182
3183 m_host.TaskInventory.LockItemsForRead(true);
2907 lock (m_host.TaskInventory) 3184 lock (m_host.TaskInventory)
2908 { 3185 {
3186
2909 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3187 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3188 {
3189 m_host.TaskInventory.LockItemsForRead(false);
2910 return; 3190 return;
3191 }
2911 else 3192 else
3193 {
2912 item = m_host.TaskInventory[InventorySelf()]; 3194 item = m_host.TaskInventory[InventorySelf()];
3195 }
2913 } 3196 }
3197 m_host.TaskInventory.LockItemsForRead(false);
2914 3198
2915 m_host.AddScriptLPS(1); 3199 m_host.AddScriptLPS(1);
2916 3200
@@ -2942,19 +3226,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2942 { 3226 {
2943 m_host.AddScriptLPS(1); 3227 m_host.AddScriptLPS(1);
2944 3228
2945// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2946// return;
2947
2948 TaskInventoryItem item; 3229 TaskInventoryItem item;
2949 3230
2950 lock (m_host.TaskInventory) 3231 m_host.TaskInventory.LockItemsForRead(true);
3232
3233 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2951 { 3234 {
2952 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3235 m_host.TaskInventory.LockItemsForRead(false);
2953 return; 3236 return;
2954 else 3237 }
2955 item = m_host.TaskInventory[InventorySelf()]; 3238 else
3239 {
3240 item = m_host.TaskInventory[InventorySelf()];
2956 } 3241 }
2957 3242
3243 m_host.TaskInventory.LockItemsForRead(false);
3244
2958 if (item.PermsGranter != m_host.OwnerID) 3245 if (item.PermsGranter != m_host.OwnerID)
2959 return; 3246 return;
2960 3247
@@ -2963,11 +3250,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2963 SceneObjectGroup grp = m_host.ParentGroup; 3250 SceneObjectGroup grp = m_host.ParentGroup;
2964 3251
2965 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3252 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2966 3253 if (presence.Scene.AttachmentsModule != null)
2967 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3254 {
2968 if (attachmentsModule != null) 3255 presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false);
2969 attachmentsModule.AttachObject(presence.ControllingClient, 3256 }
2970 grp, (uint)attachment, false);
2971 } 3257 }
2972 } 3258 }
2973 3259
@@ -2980,13 +3266,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 3266
2981 TaskInventoryItem item; 3267 TaskInventoryItem item;
2982 3268
2983 lock (m_host.TaskInventory) 3269 m_host.TaskInventory.LockItemsForRead(true);
3270
3271 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2984 { 3272 {
2985 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3273 m_host.TaskInventory.LockItemsForRead(false);
2986 return; 3274 return;
2987 else 3275 }
2988 item = m_host.TaskInventory[InventorySelf()]; 3276 else
3277 {
3278 item = m_host.TaskInventory[InventorySelf()];
2989 } 3279 }
3280 m_host.TaskInventory.LockItemsForRead(false);
3281
2990 3282
2991 if (item.PermsGranter != m_host.OwnerID) 3283 if (item.PermsGranter != m_host.OwnerID)
2992 return; 3284 return;
@@ -3033,6 +3325,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3033 3325
3034 public void llInstantMessage(string user, string message) 3326 public void llInstantMessage(string user, string message)
3035 { 3327 {
3328 UUID result;
3329 if (!UUID.TryParse(user, out result))
3330 {
3331 ShoutError("An invalid key was passed to llInstantMessage");
3332 ScriptSleep(2000);
3333 return;
3334 }
3335
3336
3036 m_host.AddScriptLPS(1); 3337 m_host.AddScriptLPS(1);
3037 3338
3038 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3339 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3047,14 +3348,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 UUID friendTransactionID = UUID.Random(); 3348 UUID friendTransactionID = UUID.Random();
3048 3349
3049 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3350 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3050 3351
3051 GridInstantMessage msg = new GridInstantMessage(); 3352 GridInstantMessage msg = new GridInstantMessage();
3052 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3353 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3053 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3354 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3054 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3355 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3055// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3356// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3056// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3357// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3057 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3358// DateTime dt = DateTime.UtcNow;
3359//
3360// // Ticks from UtcNow, but make it look like local. Evil, huh?
3361// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3362//
3363// try
3364// {
3365// // Convert that to the PST timezone
3366// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3367// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3368// }
3369// catch
3370// {
3371// // No logging here, as it could be VERY spammy
3372// }
3373//
3374// // And make it look local again to fool the unix time util
3375// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3376
3377 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3378
3058 //if (client != null) 3379 //if (client != null)
3059 //{ 3380 //{
3060 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3381 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3068,12 +3389,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3068 msg.message = message.Substring(0, 1024); 3389 msg.message = message.Substring(0, 1024);
3069 else 3390 else
3070 msg.message = message; 3391 msg.message = message;
3071 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3392 msg.dialog = (byte)19; // MessageFromObject
3072 msg.fromGroup = false;// fromGroup; 3393 msg.fromGroup = false;// fromGroup;
3073 msg.offline = (byte)0; //offline; 3394 msg.offline = (byte)0; //offline;
3074 msg.ParentEstateID = 0; //ParentEstateID; 3395 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3075 msg.Position = new Vector3(m_host.AbsolutePosition); 3396 msg.Position = new Vector3(m_host.AbsolutePosition);
3076 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3397 msg.RegionID = World.RegionInfo.RegionID.Guid;
3077 msg.binaryBucket 3398 msg.binaryBucket
3078 = Util.StringToBytes256( 3399 = Util.StringToBytes256(
3079 "{0}/{1}/{2}/{3}", 3400 "{0}/{1}/{2}/{3}",
@@ -3101,7 +3422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 } 3422 }
3102 3423
3103 emailModule.SendEmail(m_host.UUID, address, subject, message); 3424 emailModule.SendEmail(m_host.UUID, address, subject, message);
3104 ScriptSleep(20000); 3425 ScriptSleep(15000);
3105 } 3426 }
3106 3427
3107 public void llGetNextEmail(string address, string subject) 3428 public void llGetNextEmail(string address, string subject)
@@ -3201,13 +3522,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3201 m_host.AddScriptLPS(1); 3522 m_host.AddScriptLPS(1);
3202 } 3523 }
3203 3524
3204 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3205 {
3206 m_host.AddScriptLPS(1);
3207 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3208 m_host.RotLookAt(rot, (float)strength, (float)damping);
3209 }
3210
3211 public LSL_Integer llStringLength(string str) 3525 public LSL_Integer llStringLength(string str)
3212 { 3526 {
3213 m_host.AddScriptLPS(1); 3527 m_host.AddScriptLPS(1);
@@ -3231,14 +3545,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3231 3545
3232 TaskInventoryItem item; 3546 TaskInventoryItem item;
3233 3547
3234 lock (m_host.TaskInventory) 3548 m_host.TaskInventory.LockItemsForRead(true);
3549 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3235 { 3550 {
3236 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3551 m_host.TaskInventory.LockItemsForRead(false);
3237 return; 3552 return;
3238 else
3239 item = m_host.TaskInventory[InventorySelf()];
3240 } 3553 }
3241 3554 else
3555 {
3556 item = m_host.TaskInventory[InventorySelf()];
3557 }
3558 m_host.TaskInventory.LockItemsForRead(false);
3242 if (item.PermsGranter == UUID.Zero) 3559 if (item.PermsGranter == UUID.Zero)
3243 return; 3560 return;
3244 3561
@@ -3268,13 +3585,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 3585
3269 TaskInventoryItem item; 3586 TaskInventoryItem item;
3270 3587
3271 lock (m_host.TaskInventory) 3588 m_host.TaskInventory.LockItemsForRead(true);
3589 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3272 { 3590 {
3273 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3591 m_host.TaskInventory.LockItemsForRead(false);
3274 return; 3592 return;
3275 else 3593 }
3276 item = m_host.TaskInventory[InventorySelf()]; 3594 else
3595 {
3596 item = m_host.TaskInventory[InventorySelf()];
3277 } 3597 }
3598 m_host.TaskInventory.LockItemsForRead(false);
3599
3278 3600
3279 if (item.PermsGranter == UUID.Zero) 3601 if (item.PermsGranter == UUID.Zero)
3280 return; 3602 return;
@@ -3339,10 +3661,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3339 3661
3340 TaskInventoryItem item; 3662 TaskInventoryItem item;
3341 3663
3342 lock (m_host.TaskInventory) 3664
3665 m_host.TaskInventory.LockItemsForRead(true);
3666 if (!m_host.TaskInventory.ContainsKey(invItemID))
3667 {
3668 m_host.TaskInventory.LockItemsForRead(false);
3669 return;
3670 }
3671 else
3343 { 3672 {
3344 item = m_host.TaskInventory[invItemID]; 3673 item = m_host.TaskInventory[invItemID];
3345 } 3674 }
3675 m_host.TaskInventory.LockItemsForRead(false);
3346 3676
3347 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3677 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3348 { 3678 {
@@ -3370,15 +3700,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3370 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3700 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3371 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3701 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3372 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3702 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3703 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3373 ScriptBaseClass.PERMISSION_ATTACH; 3704 ScriptBaseClass.PERMISSION_ATTACH;
3374 3705
3375 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3706 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3376 { 3707 {
3377 lock (m_host.TaskInventory) 3708 m_host.TaskInventory.LockItemsForWrite(true);
3378 { 3709 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3379 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3710 m_host.TaskInventory[invItemID].PermsMask = perm;
3380 m_host.TaskInventory[invItemID].PermsMask = perm; 3711 m_host.TaskInventory.LockItemsForWrite(false);
3381 }
3382 3712
3383 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3713 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3384 "run_time_permissions", new Object[] { 3714 "run_time_permissions", new Object[] {
@@ -3388,28 +3718,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3388 return; 3718 return;
3389 } 3719 }
3390 } 3720 }
3391 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3721 else
3392 { 3722 {
3393 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3723 bool sitting = false;
3394 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3724 if (m_host.SitTargetAvatar == agentID)
3395 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3725 {
3396 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3726 sitting = true;
3397 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3727 }
3728 else
3729 {
3730 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3731 {
3732 if (p.SitTargetAvatar == agentID)
3733 sitting = true;
3734 }
3735 }
3398 3736
3399 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3737 if (sitting)
3400 { 3738 {
3401 lock (m_host.TaskInventory) 3739 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3740 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3741 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3742 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3743 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3744
3745 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3402 { 3746 {
3747 m_host.TaskInventory.LockItemsForWrite(true);
3403 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3748 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3404 m_host.TaskInventory[invItemID].PermsMask = perm; 3749 m_host.TaskInventory[invItemID].PermsMask = perm;
3405 } 3750 m_host.TaskInventory.LockItemsForWrite(false);
3406 3751
3407 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3752 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3408 "run_time_permissions", new Object[] { 3753 "run_time_permissions", new Object[] {
3409 new LSL_Integer(perm) }, 3754 new LSL_Integer(perm) },
3410 new DetectParams[0])); 3755 new DetectParams[0]));
3411 3756
3412 return; 3757 return;
3758 }
3413 } 3759 }
3414 } 3760 }
3415 3761
@@ -3423,11 +3769,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3423 3769
3424 if (!m_waitingForScriptAnswer) 3770 if (!m_waitingForScriptAnswer)
3425 { 3771 {
3426 lock (m_host.TaskInventory) 3772 m_host.TaskInventory.LockItemsForWrite(true);
3427 { 3773 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3428 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3774 m_host.TaskInventory[invItemID].PermsMask = 0;
3429 m_host.TaskInventory[invItemID].PermsMask = 0; 3775 m_host.TaskInventory.LockItemsForWrite(false);
3430 }
3431 3776
3432 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3777 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3433 m_waitingForScriptAnswer=true; 3778 m_waitingForScriptAnswer=true;
@@ -3462,10 +3807,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3807 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3463 llReleaseControls(); 3808 llReleaseControls();
3464 3809
3465 lock (m_host.TaskInventory) 3810
3466 { 3811 m_host.TaskInventory.LockItemsForWrite(true);
3467 m_host.TaskInventory[invItemID].PermsMask = answer; 3812 m_host.TaskInventory[invItemID].PermsMask = answer;
3468 } 3813 m_host.TaskInventory.LockItemsForWrite(false);
3814
3469 3815
3470 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3816 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3471 "run_time_permissions", new Object[] { 3817 "run_time_permissions", new Object[] {
@@ -3477,16 +3823,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3477 { 3823 {
3478 m_host.AddScriptLPS(1); 3824 m_host.AddScriptLPS(1);
3479 3825
3480 lock (m_host.TaskInventory) 3826 m_host.TaskInventory.LockItemsForRead(true);
3827
3828 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3481 { 3829 {
3482 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3830 if (item.Type == 10 && item.ItemID == m_itemID)
3483 { 3831 {
3484 if (item.Type == 10 && item.ItemID == m_itemID) 3832 m_host.TaskInventory.LockItemsForRead(false);
3485 { 3833 return item.PermsGranter.ToString();
3486 return item.PermsGranter.ToString();
3487 }
3488 } 3834 }
3489 } 3835 }
3836 m_host.TaskInventory.LockItemsForRead(false);
3490 3837
3491 return UUID.Zero.ToString(); 3838 return UUID.Zero.ToString();
3492 } 3839 }
@@ -3495,19 +3842,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3495 { 3842 {
3496 m_host.AddScriptLPS(1); 3843 m_host.AddScriptLPS(1);
3497 3844
3498 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3846
3847 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3499 { 3848 {
3500 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3849 if (item.Type == 10 && item.ItemID == m_itemID)
3501 { 3850 {
3502 if (item.Type == 10 && item.ItemID == m_itemID) 3851 int perms = item.PermsMask;
3503 { 3852 if (m_automaticLinkPermission)
3504 int perms = item.PermsMask; 3853 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3505 if (m_automaticLinkPermission) 3854 m_host.TaskInventory.LockItemsForRead(false);
3506 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3855 return perms;
3507 return perms;
3508 }
3509 } 3856 }
3510 } 3857 }
3858 m_host.TaskInventory.LockItemsForRead(false);
3511 3859
3512 return 0; 3860 return 0;
3513 } 3861 }
@@ -3529,9 +3877,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3529 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3877 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3530 { 3878 {
3531 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3879 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3532 3880 if (parts.Count > 0)
3533 foreach (SceneObjectPart part in parts) 3881 {
3534 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3882 try
3883 {
3884 parts[0].ParentGroup.areUpdatesSuspended = true;
3885 foreach (SceneObjectPart part in parts)
3886 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3887 }
3888 finally
3889 {
3890 parts[0].ParentGroup.areUpdatesSuspended = false;
3891 }
3892 }
3535 } 3893 }
3536 3894
3537 public void llCreateLink(string target, int parent) 3895 public void llCreateLink(string target, int parent)
@@ -3544,11 +3902,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3544 return; 3902 return;
3545 3903
3546 TaskInventoryItem item; 3904 TaskInventoryItem item;
3547 lock (m_host.TaskInventory) 3905 m_host.TaskInventory.LockItemsForRead(true);
3548 { 3906 item = m_host.TaskInventory[invItemID];
3549 item = m_host.TaskInventory[invItemID]; 3907 m_host.TaskInventory.LockItemsForRead(false);
3550 } 3908
3551
3552 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3909 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3553 && !m_automaticLinkPermission) 3910 && !m_automaticLinkPermission)
3554 { 3911 {
@@ -3565,11 +3922,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3565 3922
3566 if (targetPart.ParentGroup.AttachmentPoint != 0) 3923 if (targetPart.ParentGroup.AttachmentPoint != 0)
3567 return; // Fail silently if attached 3924 return; // Fail silently if attached
3925
3926 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3927 return;
3928
3568 SceneObjectGroup parentPrim = null, childPrim = null; 3929 SceneObjectGroup parentPrim = null, childPrim = null;
3569 3930
3570 if (targetPart != null) 3931 if (targetPart != null)
3571 { 3932 {
3572 if (parent != 0) { 3933 if (parent != 0)
3934 {
3573 parentPrim = m_host.ParentGroup; 3935 parentPrim = m_host.ParentGroup;
3574 childPrim = targetPart.ParentGroup; 3936 childPrim = targetPart.ParentGroup;
3575 } 3937 }
@@ -3601,16 +3963,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3601 m_host.AddScriptLPS(1); 3963 m_host.AddScriptLPS(1);
3602 UUID invItemID = InventorySelf(); 3964 UUID invItemID = InventorySelf();
3603 3965
3604 lock (m_host.TaskInventory) 3966 m_host.TaskInventory.LockItemsForRead(true);
3605 {
3606 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3967 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3607 && !m_automaticLinkPermission) 3968 && !m_automaticLinkPermission)
3608 { 3969 {
3609 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3970 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3971 m_host.TaskInventory.LockItemsForRead(false);
3610 return; 3972 return;
3611 } 3973 }
3612 } 3974 m_host.TaskInventory.LockItemsForRead(false);
3613 3975
3614 if (linknum < ScriptBaseClass.LINK_THIS) 3976 if (linknum < ScriptBaseClass.LINK_THIS)
3615 return; 3977 return;
3616 3978
@@ -3649,10 +4011,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3649 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3650 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3651 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3652 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3653 { 4015 {
3654 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 parts[0].ParentGroup.areUpdatesSuspended = true;
4019 foreach (SceneObjectPart part in parts)
4020 {
4021 parentPrim.DelinkFromGroup(part.LocalId, true);
4022 }
4023 }
4024 finally
4025 {
4026 parts[0].ParentGroup.areUpdatesSuspended = false;
4027 }
3655 } 4028 }
4029
3656 parentPrim.HasGroupChanged = true; 4030 parentPrim.HasGroupChanged = true;
3657 parentPrim.ScheduleGroupForFullUpdate(); 4031 parentPrim.ScheduleGroupForFullUpdate();
3658 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4032 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3661,11 +4035,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 { 4035 {
3662 SceneObjectPart newRoot = parts[0]; 4036 SceneObjectPart newRoot = parts[0];
3663 parts.Remove(newRoot); 4037 parts.Remove(newRoot);
3664 foreach (SceneObjectPart part in parts) 4038
4039 try
3665 { 4040 {
3666 part.UpdateFlag = 0; 4041 parts[0].ParentGroup.areUpdatesSuspended = true;
3667 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4042 foreach (SceneObjectPart part in parts)
4043 {
4044 part.UpdateFlag = 0;
4045 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4046 }
3668 } 4047 }
4048 finally
4049 {
4050 parts[0].ParentGroup.areUpdatesSuspended = false;
4051 }
4052
4053
3669 newRoot.ParentGroup.HasGroupChanged = true; 4054 newRoot.ParentGroup.HasGroupChanged = true;
3670 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4055 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3671 } 4056 }
@@ -3685,6 +4070,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 public void llBreakAllLinks() 4070 public void llBreakAllLinks()
3686 { 4071 {
3687 m_host.AddScriptLPS(1); 4072 m_host.AddScriptLPS(1);
4073
4074 UUID invItemID = InventorySelf();
4075
4076 TaskInventoryItem item;
4077 m_host.TaskInventory.LockItemsForRead(true);
4078 item = m_host.TaskInventory[invItemID];
4079 m_host.TaskInventory.LockItemsForRead(false);
4080
4081 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4082 && !m_automaticLinkPermission)
4083 {
4084 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4085 return;
4086 }
4087
3688 SceneObjectGroup parentPrim = m_host.ParentGroup; 4088 SceneObjectGroup parentPrim = m_host.ParentGroup;
3689 if (parentPrim.AttachmentPoint != 0) 4089 if (parentPrim.AttachmentPoint != 0)
3690 return; // Fail silently if attached 4090 return; // Fail silently if attached
@@ -3711,6 +4111,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3711 } 4111 }
3712 else 4112 else
3713 { 4113 {
4114 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4115 {
4116 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4117
4118 if (linknum < 0)
4119 return UUID.Zero.ToString();
4120
4121 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4122 if (avatars.Count > linknum)
4123 {
4124 return avatars[linknum].UUID.ToString();
4125 }
4126 }
3714 return UUID.Zero.ToString(); 4127 return UUID.Zero.ToString();
3715 } 4128 }
3716 } 4129 }
@@ -3787,17 +4200,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3787 m_host.AddScriptLPS(1); 4200 m_host.AddScriptLPS(1);
3788 int count = 0; 4201 int count = 0;
3789 4202
3790 lock (m_host.TaskInventory) 4203 m_host.TaskInventory.LockItemsForRead(true);
4204 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3791 { 4205 {
3792 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4206 if (inv.Value.Type == type || type == -1)
3793 { 4207 {
3794 if (inv.Value.Type == type || type == -1) 4208 count = count + 1;
3795 {
3796 count = count + 1;
3797 }
3798 } 4209 }
3799 } 4210 }
3800 4211
4212 m_host.TaskInventory.LockItemsForRead(false);
3801 return count; 4213 return count;
3802 } 4214 }
3803 4215
@@ -3806,16 +4218,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3806 m_host.AddScriptLPS(1); 4218 m_host.AddScriptLPS(1);
3807 ArrayList keys = new ArrayList(); 4219 ArrayList keys = new ArrayList();
3808 4220
3809 lock (m_host.TaskInventory) 4221 m_host.TaskInventory.LockItemsForRead(true);
4222 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3810 { 4223 {
3811 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4224 if (inv.Value.Type == type || type == -1)
3812 { 4225 {
3813 if (inv.Value.Type == type || type == -1) 4226 keys.Add(inv.Value.Name);
3814 {
3815 keys.Add(inv.Value.Name);
3816 }
3817 } 4227 }
3818 } 4228 }
4229 m_host.TaskInventory.LockItemsForRead(false);
3819 4230
3820 if (keys.Count == 0) 4231 if (keys.Count == 0)
3821 { 4232 {
@@ -3852,25 +4263,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3852 } 4263 }
3853 4264
3854 // move the first object found with this inventory name 4265 // move the first object found with this inventory name
3855 lock (m_host.TaskInventory) 4266 m_host.TaskInventory.LockItemsForRead(true);
4267 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3856 { 4268 {
3857 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4269 if (inv.Value.Name == inventory)
3858 { 4270 {
3859 if (inv.Value.Name == inventory) 4271 found = true;
3860 { 4272 objId = inv.Key;
3861 found = true; 4273 assetType = inv.Value.Type;
3862 objId = inv.Key; 4274 objName = inv.Value.Name;
3863 assetType = inv.Value.Type; 4275 break;
3864 objName = inv.Value.Name;
3865 break;
3866 }
3867 } 4276 }
3868 } 4277 }
4278 m_host.TaskInventory.LockItemsForRead(false);
3869 4279
3870 if (!found) 4280 if (!found)
3871 { 4281 {
3872 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4282 llSay(0, String.Format("Could not find object '{0}'", inventory));
3873 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4283 return;
4284// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3874 } 4285 }
3875 4286
3876 // check if destination is an object 4287 // check if destination is an object
@@ -3896,6 +4307,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 return; 4307 return;
3897 } 4308 }
3898 } 4309 }
4310
3899 // destination is an avatar 4311 // destination is an avatar
3900 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3901 4313
@@ -3918,26 +4330,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3918 bucket); 4330 bucket);
3919 if (m_TransferModule != null) 4331 if (m_TransferModule != null)
3920 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4332 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4333
4334 //This delay should only occur when giving inventory to avatars.
3921 ScriptSleep(3000); 4335 ScriptSleep(3000);
3922 } 4336 }
3923 } 4337 }
3924 4338
4339 [DebuggerNonUserCode]
3925 public void llRemoveInventory(string name) 4340 public void llRemoveInventory(string name)
3926 { 4341 {
3927 m_host.AddScriptLPS(1); 4342 m_host.AddScriptLPS(1);
3928 4343
3929 lock (m_host.TaskInventory) 4344 List<TaskInventoryItem> inv;
4345 try
3930 { 4346 {
3931 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4347 m_host.TaskInventory.LockItemsForRead(true);
4348 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4349 }
4350 finally
4351 {
4352 m_host.TaskInventory.LockItemsForRead(false);
4353 }
4354 foreach (TaskInventoryItem item in inv)
4355 {
4356 if (item.Name == name)
3932 { 4357 {
3933 if (item.Name == name) 4358 if (item.ItemID == m_itemID)
3934 { 4359 throw new ScriptDeleteException();
3935 if (item.ItemID == m_itemID) 4360 else
3936 throw new ScriptDeleteException(); 4361 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3937 else 4362 return;
3938 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3939 return;
3940 }
3941 } 4363 }
3942 } 4364 }
3943 } 4365 }
@@ -3972,112 +4394,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 { 4394 {
3973 m_host.AddScriptLPS(1); 4395 m_host.AddScriptLPS(1);
3974 4396
3975 UUID uuid = (UUID)id; 4397 UUID uuid;
3976 PresenceInfo pinfo = null; 4398 if (UUID.TryParse(id, out uuid))
3977 UserAccount account;
3978
3979 UserInfoCacheEntry ce;
3980 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3981 { 4399 {
3982 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4400 PresenceInfo pinfo = null;
3983 if (account == null) 4401 UserAccount account;
4402
4403 UserInfoCacheEntry ce;
4404 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3984 { 4405 {
3985 m_userInfoCache[uuid] = null; // Cache negative 4406 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3986 return UUID.Zero.ToString(); 4407 if (account == null)
3987 } 4408 {
4409 m_userInfoCache[uuid] = null; // Cache negative
4410 return UUID.Zero.ToString();
4411 }
3988 4412
3989 4413
3990 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4414 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3991 if (pinfos != null && pinfos.Length > 0) 4415 if (pinfos != null && pinfos.Length > 0)
3992 {
3993 foreach (PresenceInfo p in pinfos)
3994 { 4416 {
3995 if (p.RegionID != UUID.Zero) 4417 foreach (PresenceInfo p in pinfos)
3996 { 4418 {
3997 pinfo = p; 4419 if (p.RegionID != UUID.Zero)
4420 {
4421 pinfo = p;
4422 }
3998 } 4423 }
3999 } 4424 }
4000 }
4001 4425
4002 ce = new UserInfoCacheEntry(); 4426 ce = new UserInfoCacheEntry();
4003 ce.time = Util.EnvironmentTickCount(); 4427 ce.time = Util.EnvironmentTickCount();
4004 ce.account = account; 4428 ce.account = account;
4005 ce.pinfo = pinfo; 4429 ce.pinfo = pinfo;
4006 } 4430 m_userInfoCache[uuid] = ce;
4007 else 4431 }
4008 { 4432 else
4009 if (ce == null) 4433 {
4010 return UUID.Zero.ToString(); 4434 if (ce == null)
4435 return UUID.Zero.ToString();
4011 4436
4012 account = ce.account; 4437 account = ce.account;
4013 pinfo = ce.pinfo; 4438 pinfo = ce.pinfo;
4014 } 4439 }
4015 4440
4016 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4441 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4017 {
4018 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4019 if (pinfos != null && pinfos.Length > 0)
4020 { 4442 {
4021 foreach (PresenceInfo p in pinfos) 4443 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4444 if (pinfos != null && pinfos.Length > 0)
4022 { 4445 {
4023 if (p.RegionID != UUID.Zero) 4446 foreach (PresenceInfo p in pinfos)
4024 { 4447 {
4025 pinfo = p; 4448 if (p.RegionID != UUID.Zero)
4449 {
4450 pinfo = p;
4451 }
4026 } 4452 }
4027 } 4453 }
4028 } 4454 else
4029 else 4455 pinfo = null;
4030 pinfo = null;
4031 4456
4032 ce.time = Util.EnvironmentTickCount(); 4457 ce.time = Util.EnvironmentTickCount();
4033 ce.pinfo = pinfo; 4458 ce.pinfo = pinfo;
4034 } 4459 }
4035 4460
4036 string reply = String.Empty; 4461 string reply = String.Empty;
4037 4462
4038 switch (data) 4463 switch (data)
4039 { 4464 {
4040 case 1: // DATA_ONLINE (0|1) 4465 case 1: // DATA_ONLINE (0|1)
4041 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4466 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4042 reply = "1"; 4467 reply = "1";
4043 else 4468 else
4044 reply = "0"; 4469 reply = "0";
4045 break; 4470 break;
4046 case 2: // DATA_NAME (First Last) 4471 case 2: // DATA_NAME (First Last)
4047 reply = account.FirstName + " " + account.LastName; 4472 reply = account.FirstName + " " + account.LastName;
4048 break; 4473 break;
4049 case 3: // DATA_BORN (YYYY-MM-DD) 4474 case 3: // DATA_BORN (YYYY-MM-DD)
4050 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4475 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4051 born = born.AddSeconds(account.Created); 4476 born = born.AddSeconds(account.Created);
4052 reply = born.ToString("yyyy-MM-dd"); 4477 reply = born.ToString("yyyy-MM-dd");
4053 break; 4478 break;
4054 case 4: // DATA_RATING (0,0,0,0,0,0) 4479 case 4: // DATA_RATING (0,0,0,0,0,0)
4055 reply = "0,0,0,0,0,0"; 4480 reply = "0,0,0,0,0,0";
4056 break; 4481 break;
4057 case 8: // DATA_PAYINFO (0|1|2|3) 4482 case 8: // DATA_PAYINFO (0|1|2|3)
4058 reply = "0"; 4483 reply = "0";
4059 break; 4484 break;
4060 default: 4485 default:
4061 return UUID.Zero.ToString(); // Raise no event 4486 return UUID.Zero.ToString(); // Raise no event
4062 } 4487 }
4063 4488
4064 UUID rq = UUID.Random(); 4489 UUID rq = UUID.Random();
4065 4490
4066 UUID tid = AsyncCommands. 4491 UUID tid = AsyncCommands.
4067 DataserverPlugin.RegisterRequest(m_localID, 4492 DataserverPlugin.RegisterRequest(m_localID,
4068 m_itemID, rq.ToString()); 4493 m_itemID, rq.ToString());
4069 4494
4070 AsyncCommands. 4495 AsyncCommands.
4071 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4496 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4072 4497
4073 ScriptSleep(100); 4498 ScriptSleep(100);
4074 return tid.ToString(); 4499 return tid.ToString();
4500 }
4501 else
4502 {
4503 ShoutError("Invalid UUID passed to llRequestAgentData.");
4504 }
4505 return "";
4075 } 4506 }
4076 4507
4077 public LSL_String llRequestInventoryData(string name) 4508 public LSL_String llRequestInventoryData(string name)
4078 { 4509 {
4079 m_host.AddScriptLPS(1); 4510 m_host.AddScriptLPS(1);
4080 4511
4512 //Clone is thread safe
4081 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4513 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4082 4514
4083 foreach (TaskInventoryItem item in itemDictionary.Values) 4515 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4131,6 +4563,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4131 ScenePresence presence = World.GetScenePresence(agentId); 4563 ScenePresence presence = World.GetScenePresence(agentId);
4132 if (presence != null) 4564 if (presence != null)
4133 { 4565 {
4566 // agent must not be a god
4567 if (presence.UserLevel >= 200) return;
4568
4134 // agent must be over the owners land 4569 // agent must be over the owners land
4135 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4570 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4136 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4571 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4153,7 +4588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4153 UUID av = new UUID(); 4588 UUID av = new UUID();
4154 if (!UUID.TryParse(agent,out av)) 4589 if (!UUID.TryParse(agent,out av))
4155 { 4590 {
4156 LSLError("First parameter to llDialog needs to be a key"); 4591 //LSLError("First parameter to llDialog needs to be a key");
4157 return; 4592 return;
4158 } 4593 }
4159 4594
@@ -4190,17 +4625,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4190 UUID soundId = UUID.Zero; 4625 UUID soundId = UUID.Zero;
4191 if (!UUID.TryParse(impact_sound, out soundId)) 4626 if (!UUID.TryParse(impact_sound, out soundId))
4192 { 4627 {
4193 lock (m_host.TaskInventory) 4628 m_host.TaskInventory.LockItemsForRead(true);
4629 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4194 { 4630 {
4195 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4631 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4196 { 4632 {
4197 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4633 soundId = item.AssetID;
4198 { 4634 break;
4199 soundId = item.AssetID;
4200 break;
4201 }
4202 } 4635 }
4203 } 4636 }
4637 m_host.TaskInventory.LockItemsForRead(false);
4204 } 4638 }
4205 m_host.CollisionSound = soundId; 4639 m_host.CollisionSound = soundId;
4206 m_host.CollisionSoundVolume = (float)impact_volume; 4640 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4240,6 +4674,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4240 UUID partItemID; 4674 UUID partItemID;
4241 foreach (SceneObjectPart part in parts) 4675 foreach (SceneObjectPart part in parts)
4242 { 4676 {
4677 //Clone is thread safe
4243 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4678 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4244 4679
4245 foreach (TaskInventoryItem item in itemsDictionary.Values) 4680 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4454,17 +4889,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4454 4889
4455 m_host.AddScriptLPS(1); 4890 m_host.AddScriptLPS(1);
4456 4891
4457 lock (m_host.TaskInventory) 4892 m_host.TaskInventory.LockItemsForRead(true);
4893 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4458 { 4894 {
4459 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4895 if (item.Type == 10 && item.ItemID == m_itemID)
4460 { 4896 {
4461 if (item.Type == 10 && item.ItemID == m_itemID) 4897 result = item.Name!=null?item.Name:String.Empty;
4462 { 4898 break;
4463 result = item.Name != null ? item.Name : String.Empty;
4464 break;
4465 }
4466 } 4899 }
4467 } 4900 }
4901 m_host.TaskInventory.LockItemsForRead(false);
4468 4902
4469 return result; 4903 return result;
4470 } 4904 }
@@ -4633,23 +5067,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4633 { 5067 {
4634 m_host.AddScriptLPS(1); 5068 m_host.AddScriptLPS(1);
4635 5069
4636 lock (m_host.TaskInventory) 5070 m_host.TaskInventory.LockItemsForRead(true);
5071 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4637 { 5072 {
4638 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5073 if (inv.Value.Name == name)
4639 { 5074 {
4640 if (inv.Value.Name == name) 5075 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4641 { 5076 {
4642 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5077 m_host.TaskInventory.LockItemsForRead(false);
4643 { 5078 return inv.Value.AssetID.ToString();
4644 return inv.Value.AssetID.ToString(); 5079 }
4645 } 5080 else
4646 else 5081 {
4647 { 5082 m_host.TaskInventory.LockItemsForRead(false);
4648 return UUID.Zero.ToString(); 5083 return UUID.Zero.ToString();
4649 }
4650 } 5084 }
4651 } 5085 }
4652 } 5086 }
5087 m_host.TaskInventory.LockItemsForRead(false);
4653 5088
4654 return UUID.Zero.ToString(); 5089 return UUID.Zero.ToString();
4655 } 5090 }
@@ -4802,14 +5237,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4802 { 5237 {
4803 m_host.AddScriptLPS(1); 5238 m_host.AddScriptLPS(1);
4804 5239
4805 if (src == null) 5240 return src.Length;
4806 {
4807 return 0;
4808 }
4809 else
4810 {
4811 return src.Length;
4812 }
4813 } 5241 }
4814 5242
4815 public LSL_Integer llList2Integer(LSL_List src, int index) 5243 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4855,7 +5283,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4855 else if (src.Data[index] is LSL_Float) 5283 else if (src.Data[index] is LSL_Float)
4856 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5284 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4857 else if (src.Data[index] is LSL_String) 5285 else if (src.Data[index] is LSL_String)
4858 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5286 {
5287 string str = ((LSL_String) src.Data[index]).m_string;
5288 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5289 if (m != Match.Empty)
5290 {
5291 str = m.Value;
5292 double d = 0.0;
5293 if (!Double.TryParse(str, out d))
5294 return 0.0;
5295
5296 return d;
5297 }
5298 return 0.0;
5299 }
4859 return Convert.ToDouble(src.Data[index]); 5300 return Convert.ToDouble(src.Data[index]);
4860 } 5301 }
4861 catch (FormatException) 5302 catch (FormatException)
@@ -5128,7 +5569,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5128 } 5569 }
5129 } 5570 }
5130 } 5571 }
5131 else { 5572 else
5573 {
5132 object[] array = new object[src.Length]; 5574 object[] array = new object[src.Length];
5133 Array.Copy(src.Data, 0, array, 0, src.Length); 5575 Array.Copy(src.Data, 0, array, 0, src.Length);
5134 result = new LSL_List(array); 5576 result = new LSL_List(array);
@@ -5579,10 +6021,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5579 m_host.AddScriptLPS(1); 6021 m_host.AddScriptLPS(1);
5580 6022
5581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6023 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5582 6024 if (parts.Count > 0)
5583 foreach (var part in parts)
5584 { 6025 {
5585 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6026 try
6027 {
6028 parts[0].ParentGroup.areUpdatesSuspended = true;
6029 foreach (var part in parts)
6030 {
6031 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6032 }
6033 }
6034 finally
6035 {
6036 parts[0].ParentGroup.areUpdatesSuspended = false;
6037 }
5586 } 6038 }
5587 } 6039 }
5588 6040
@@ -5636,6 +6088,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5636 ScriptSleep(5000); 6088 ScriptSleep(5000);
5637 } 6089 }
5638 6090
6091 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6092 {
6093 return ParseString2List(str, separators, in_spacers, false);
6094 }
6095
5639 public LSL_Integer llOverMyLand(string id) 6096 public LSL_Integer llOverMyLand(string id)
5640 { 6097 {
5641 m_host.AddScriptLPS(1); 6098 m_host.AddScriptLPS(1);
@@ -5836,7 +6293,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5836 return m_host.ParentGroup.AttachmentPoint; 6293 return m_host.ParentGroup.AttachmentPoint;
5837 } 6294 }
5838 6295
5839 public LSL_Integer llGetFreeMemory() 6296 public virtual LSL_Integer llGetFreeMemory()
5840 { 6297 {
5841 m_host.AddScriptLPS(1); 6298 m_host.AddScriptLPS(1);
5842 // Make scripts designed for LSO happy 6299 // Make scripts designed for LSO happy
@@ -5953,7 +6410,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5953 SetParticleSystem(m_host, rules); 6410 SetParticleSystem(m_host, rules);
5954 } 6411 }
5955 6412
5956 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6413 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6414 {
5957 6415
5958 6416
5959 if (rules.Length == 0) 6417 if (rules.Length == 0)
@@ -6147,14 +6605,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6147 6605
6148 protected UUID GetTaskInventoryItem(string name) 6606 protected UUID GetTaskInventoryItem(string name)
6149 { 6607 {
6150 lock (m_host.TaskInventory) 6608 m_host.TaskInventory.LockItemsForRead(true);
6609 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6151 { 6610 {
6152 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6611 if (inv.Value.Name == name)
6153 { 6612 {
6154 if (inv.Value.Name == name) 6613 m_host.TaskInventory.LockItemsForRead(false);
6155 return inv.Key; 6614 return inv.Key;
6156 } 6615 }
6157 } 6616 }
6617 m_host.TaskInventory.LockItemsForRead(false);
6158 6618
6159 return UUID.Zero; 6619 return UUID.Zero;
6160 } 6620 }
@@ -6390,13 +6850,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6390 UUID av = new UUID(); 6850 UUID av = new UUID();
6391 if (!UUID.TryParse(avatar,out av)) 6851 if (!UUID.TryParse(avatar,out av))
6392 { 6852 {
6393 LSLError("First parameter to llDialog needs to be a key"); 6853 //LSLError("First parameter to llDialog needs to be a key");
6394 return; 6854 return;
6395 } 6855 }
6396 if (buttons.Length < 1) 6856 if (buttons.Length < 1)
6397 { 6857 {
6398 LSLError("No less than 1 button can be shown"); 6858 buttons.Add("OK");
6399 return;
6400 } 6859 }
6401 if (buttons.Length > 12) 6860 if (buttons.Length > 12)
6402 { 6861 {
@@ -6413,7 +6872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6413 } 6872 }
6414 if (buttons.Data[i].ToString().Length > 24) 6873 if (buttons.Data[i].ToString().Length > 24)
6415 { 6874 {
6416 LSLError("button label cannot be longer than 24 characters"); 6875 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6417 return; 6876 return;
6418 } 6877 }
6419 buts[i] = buttons.Data[i].ToString(); 6878 buts[i] = buttons.Data[i].ToString();
@@ -6472,22 +6931,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6472 } 6931 }
6473 6932
6474 // copy the first script found with this inventory name 6933 // copy the first script found with this inventory name
6475 lock (m_host.TaskInventory) 6934 TaskInventoryItem scriptItem = null;
6935 m_host.TaskInventory.LockItemsForRead(true);
6936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6476 { 6937 {
6477 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6938 if (inv.Value.Name == name)
6478 { 6939 {
6479 if (inv.Value.Name == name) 6940 // make sure the object is a script
6941 if (10 == inv.Value.Type)
6480 { 6942 {
6481 // make sure the object is a script 6943 found = true;
6482 if (10 == inv.Value.Type) 6944 srcId = inv.Key;
6483 { 6945 scriptItem = inv.Value;
6484 found = true; 6946 break;
6485 srcId = inv.Key;
6486 break;
6487 }
6488 } 6947 }
6489 } 6948 }
6490 } 6949 }
6950 m_host.TaskInventory.LockItemsForRead(false);
6491 6951
6492 if (!found) 6952 if (!found)
6493 { 6953 {
@@ -6495,8 +6955,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6495 return; 6955 return;
6496 } 6956 }
6497 6957
6498 // the rest of the permission checks are done in RezScript, so check the pin there as well 6958 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6499 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6959 if (dest != null)
6960 {
6961 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6962 {
6963 // the rest of the permission checks are done in RezScript, so check the pin there as well
6964 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6965
6966 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6967 m_host.Inventory.RemoveInventoryItem(srcId);
6968 }
6969 }
6500 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6970 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6501 ScriptSleep(3000); 6971 ScriptSleep(3000);
6502 } 6972 }
@@ -6559,19 +7029,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6559 public LSL_String llMD5String(string src, int nonce) 7029 public LSL_String llMD5String(string src, int nonce)
6560 { 7030 {
6561 m_host.AddScriptLPS(1); 7031 m_host.AddScriptLPS(1);
6562 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7032 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6563 } 7033 }
6564 7034
6565 public LSL_String llSHA1String(string src) 7035 public LSL_String llSHA1String(string src)
6566 { 7036 {
6567 m_host.AddScriptLPS(1); 7037 m_host.AddScriptLPS(1);
6568 return Util.SHA1Hash(src).ToLower(); 7038 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6569 } 7039 }
6570 7040
6571 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7041 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6572 { 7042 {
6573 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7043 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6574 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7044 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7045 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7046 return shapeBlock;
6575 7047
6576 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7048 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6577 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7049 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6676,6 +7148,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6676 // Prim type box, cylinder and prism. 7148 // Prim type box, cylinder and prism.
6677 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) 7149 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)
6678 { 7150 {
7151 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7152 return;
7153
6679 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7154 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6680 ObjectShapePacket.ObjectDataBlock shapeBlock; 7155 ObjectShapePacket.ObjectDataBlock shapeBlock;
6681 7156
@@ -6729,6 +7204,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6729 // Prim type sphere. 7204 // Prim type sphere.
6730 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7205 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6731 { 7206 {
7207 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7208 return;
7209
6732 ObjectShapePacket.ObjectDataBlock shapeBlock; 7210 ObjectShapePacket.ObjectDataBlock shapeBlock;
6733 7211
6734 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7212 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6770,6 +7248,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6770 // Prim type torus, tube and ring. 7248 // Prim type torus, tube and ring.
6771 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) 7249 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)
6772 { 7250 {
7251 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7252 return;
7253
6773 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7254 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6774 ObjectShapePacket.ObjectDataBlock shapeBlock; 7255 ObjectShapePacket.ObjectDataBlock shapeBlock;
6775 7256
@@ -6905,6 +7386,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6905 // Prim type sculpt. 7386 // Prim type sculpt.
6906 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7387 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6907 { 7388 {
7389 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7390 return;
7391
6908 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7392 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6909 UUID sculptId; 7393 UUID sculptId;
6910 7394
@@ -6921,13 +7405,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6921 shapeBlock.PathScaleX = 100; 7405 shapeBlock.PathScaleX = 100;
6922 shapeBlock.PathScaleY = 150; 7406 shapeBlock.PathScaleY = 150;
6923 7407
6924 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7408 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6925 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7409 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6926 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7410 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6927 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7411 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6928 { 7412 {
6929 // default 7413 // default
6930 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7414 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6931 } 7415 }
6932 7416
6933 part.Shape.SetSculptProperties((byte)type, sculptId); 7417 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -6943,32 +7427,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 ScriptSleep(200); 7427 ScriptSleep(200);
6944 } 7428 }
6945 7429
6946 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7430 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6947 { 7431 {
6948 m_host.AddScriptLPS(1); 7432 m_host.AddScriptLPS(1);
6949 7433
6950 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7434 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7435 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7436 if (parts.Count>0)
7437 {
7438 try
7439 {
7440 parts[0].ParentGroup.areUpdatesSuspended = true;
7441 foreach (SceneObjectPart part in parts)
7442 SetPrimParams(part, rules);
7443 }
7444 finally
7445 {
7446 parts[0].ParentGroup.areUpdatesSuspended = false;
7447 }
7448 }
7449 if (avatars.Count > 0)
7450 {
7451 foreach (ScenePresence avatar in avatars)
7452 SetPrimParams(avatar, rules);
7453 }
7454 }
6951 7455
6952 foreach (SceneObjectPart part in parts) 7456 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6953 SetPrimParams(part, rules); 7457 {
6954 7458 llSetLinkPrimitiveParamsFast(linknumber, rules);
6955 ScriptSleep(200); 7459 ScriptSleep(200);
6956 } 7460 }
6957 7461
6958 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7462 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6959 { 7463 {
6960 m_host.AddScriptLPS(1); 7464 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7465 //We only support PRIM_POSITION and PRIM_ROTATION
6961 7466
6962 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7467 int idx = 0;
6963 7468
6964 foreach (SceneObjectPart part in parts) 7469 while (idx < rules.Length)
6965 SetPrimParams(part, rules); 7470 {
7471 int code = rules.GetLSLIntegerItem(idx++);
7472
7473 int remain = rules.Length - idx;
7474
7475
7476
7477 switch (code)
7478 {
7479 case (int)ScriptBaseClass.PRIM_POSITION:
7480 if (remain < 1)
7481 return;
7482 LSL_Vector v;
7483 v = rules.GetVector3Item(idx++);
7484 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7485 av.SendAvatarDataToAllAgents();
7486
7487 break;
7488
7489 case (int)ScriptBaseClass.PRIM_ROTATION:
7490 if (remain < 1)
7491 return;
7492 LSL_Rotation r;
7493 r = rules.GetQuaternionItem(idx++);
7494 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7495 av.SendAvatarDataToAllAgents();
7496 break;
7497 }
7498 }
6966 } 7499 }
6967 7500
6968 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7501 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6969 { 7502 {
7503 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7504 return;
7505
6970 int idx = 0; 7506 int idx = 0;
6971 7507
7508 bool positionChanged = false;
7509 LSL_Vector currentPosition = GetPartLocalPos(part);
7510
6972 while (idx < rules.Length) 7511 while (idx < rules.Length)
6973 { 7512 {
6974 int code = rules.GetLSLIntegerItem(idx++); 7513 int code = rules.GetLSLIntegerItem(idx++);
@@ -6977,7 +7516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6977 7516
6978 int face; 7517 int face;
6979 LSL_Vector v; 7518 LSL_Vector v;
6980 7519
6981 switch (code) 7520 switch (code)
6982 { 7521 {
6983 case (int)ScriptBaseClass.PRIM_POSITION: 7522 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6985,7 +7524,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6985 return; 7524 return;
6986 7525
6987 v=rules.GetVector3Item(idx++); 7526 v=rules.GetVector3Item(idx++);
6988 SetPos(part, v); 7527 positionChanged = true;
7528 currentPosition = GetSetPosTarget(part, v, currentPosition);
6989 7529
6990 break; 7530 break;
6991 case (int)ScriptBaseClass.PRIM_SIZE: 7531 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7330,6 +7870,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7330 break; 7870 break;
7331 } 7871 }
7332 } 7872 }
7873
7874 if (positionChanged)
7875 {
7876 if (part.ParentGroup.RootPart == part)
7877 {
7878 SceneObjectGroup parent = part.ParentGroup;
7879 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7880 }
7881 else
7882 {
7883 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7884 SceneObjectGroup parent = part.ParentGroup;
7885 parent.HasGroupChanged = true;
7886 parent.ScheduleGroupForTerseUpdate();
7887 }
7888 }
7333 } 7889 }
7334 7890
7335 public LSL_String llStringToBase64(string str) 7891 public LSL_String llStringToBase64(string str)
@@ -7478,13 +8034,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7478 public LSL_Integer llGetNumberOfPrims() 8034 public LSL_Integer llGetNumberOfPrims()
7479 { 8035 {
7480 m_host.AddScriptLPS(1); 8036 m_host.AddScriptLPS(1);
7481 int avatarCount = 0; 8037 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7482 World.ForEachScenePresence(delegate(ScenePresence presence) 8038
7483 {
7484 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7485 avatarCount++;
7486 });
7487
7488 return m_host.ParentGroup.PrimCount + avatarCount; 8039 return m_host.ParentGroup.PrimCount + avatarCount;
7489 } 8040 }
7490 8041
@@ -7500,55 +8051,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7500 m_host.AddScriptLPS(1); 8051 m_host.AddScriptLPS(1);
7501 UUID objID = UUID.Zero; 8052 UUID objID = UUID.Zero;
7502 LSL_List result = new LSL_List(); 8053 LSL_List result = new LSL_List();
8054
8055 // If the ID is not valid, return null result
7503 if (!UUID.TryParse(obj, out objID)) 8056 if (!UUID.TryParse(obj, out objID))
7504 { 8057 {
7505 result.Add(new LSL_Vector()); 8058 result.Add(new LSL_Vector());
7506 result.Add(new LSL_Vector()); 8059 result.Add(new LSL_Vector());
7507 return result; 8060 return result;
7508 } 8061 }
8062
8063 // Check if this is an attached prim. If so, replace
8064 // the UUID with the avatar UUID and report it's bounding box
8065 SceneObjectPart part = World.GetSceneObjectPart(objID);
8066 if (part != null && part.ParentGroup.IsAttachment)
8067 objID = part.ParentGroup.AttachedAvatar;
8068
8069 // Find out if this is an avatar ID. If so, return it's box
7509 ScenePresence presence = World.GetScenePresence(objID); 8070 ScenePresence presence = World.GetScenePresence(objID);
7510 if (presence != null) 8071 if (presence != null)
7511 { 8072 {
7512 if (presence.ParentID == 0) // not sat on an object 8073 // As per LSL Wiki, there is no difference between sitting
8074 // and standing avatar since server 1.36
8075 LSL_Vector lower;
8076 LSL_Vector upper;
8077 if (presence.Animator.Animations.DefaultAnimation.AnimID
8078 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7513 { 8079 {
7514 LSL_Vector lower; 8080 // This is for ground sitting avatars
7515 LSL_Vector upper; 8081 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7516 if (presence.Animator.Animations.DefaultAnimation.AnimID 8082 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7517 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8083 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7518 {
7519 // This is for ground sitting avatars
7520 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7521 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7522 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7523 }
7524 else
7525 {
7526 // This is for standing/flying avatars
7527 float height = presence.Appearance.AvatarHeight / 2.0f;
7528 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7529 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7530 }
7531 result.Add(lower);
7532 result.Add(upper);
7533 return result;
7534 } 8084 }
7535 else 8085 else
7536 { 8086 {
7537 // sitting on an object so we need the bounding box of that 8087 // This is for standing/flying avatars
7538 // which should include the avatar so set the UUID to the 8088 float height = presence.Appearance.AvatarHeight / 2.0f;
7539 // UUID of the object the avatar is sat on and allow it to fall through 8089 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7540 // to processing an object 8090 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7541 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7542 objID = p.UUID;
7543 } 8091 }
8092
8093 // Adjust to the documented error offsets (see LSL Wiki)
8094 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8095 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8096
8097 if (lower.x > upper.x)
8098 lower.x = upper.x;
8099 if (lower.y > upper.y)
8100 lower.y = upper.y;
8101 if (lower.z > upper.z)
8102 lower.z = upper.z;
8103
8104 result.Add(lower);
8105 result.Add(upper);
8106 return result;
7544 } 8107 }
7545 SceneObjectPart part = World.GetSceneObjectPart(objID); 8108
8109 part = World.GetSceneObjectPart(objID);
7546 // Currently only works for single prims without a sitting avatar 8110 // Currently only works for single prims without a sitting avatar
7547 if (part != null) 8111 if (part != null)
7548 { 8112 {
7549 Vector3 halfSize = part.Scale / 2.0f; 8113 float minX;
7550 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8114 float maxX;
7551 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8115 float minY;
8116 float maxY;
8117 float minZ;
8118 float maxZ;
8119
8120 // This BBox is in sim coordinates, with the offset being
8121 // a contained point.
8122 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8123 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8124
8125 minX -= offsets[0].X;
8126 maxX -= offsets[0].X;
8127 minY -= offsets[0].Y;
8128 maxY -= offsets[0].Y;
8129 minZ -= offsets[0].Z;
8130 maxZ -= offsets[0].Z;
8131
8132 LSL_Vector lower;
8133 LSL_Vector upper;
8134
8135 // Adjust to the documented error offsets (see LSL Wiki)
8136 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8137 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8138
8139 if (lower.x > upper.x)
8140 lower.x = upper.x;
8141 if (lower.y > upper.y)
8142 lower.y = upper.y;
8143 if (lower.z > upper.z)
8144 lower.z = upper.z;
8145
7552 result.Add(lower); 8146 result.Add(lower);
7553 result.Add(upper); 8147 result.Add(upper);
7554 return result; 8148 return result;
@@ -7628,13 +8222,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7628 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8222 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7629 part.AbsolutePosition.Y, 8223 part.AbsolutePosition.Y,
7630 part.AbsolutePosition.Z); 8224 part.AbsolutePosition.Z);
7631 // For some reason, the part.AbsolutePosition.* values do not change if the
7632 // linkset is rotated; they always reflect the child prim's world position
7633 // as though the linkset is unrotated. This is incompatible behavior with SL's
7634 // implementation, so will break scripts imported from there (not to mention it
7635 // makes it more difficult to determine a child prim's actual inworld position).
7636 if (part.ParentID != 0)
7637 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7638 res.Add(v); 8225 res.Add(v);
7639 break; 8226 break;
7640 8227
@@ -7805,56 +8392,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7805 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8392 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7806 if (remain < 1) 8393 if (remain < 1)
7807 return res; 8394 return res;
7808 8395 face = (int)rules.GetLSLIntegerItem(idx++);
7809 face=(int)rules.GetLSLIntegerItem(idx++);
7810 8396
7811 tex = part.Shape.Textures; 8397 tex = part.Shape.Textures;
8398 int shiny;
7812 if (face == ScriptBaseClass.ALL_SIDES) 8399 if (face == ScriptBaseClass.ALL_SIDES)
7813 { 8400 {
7814 for (face = 0; face < GetNumberOfSides(part); face++) 8401 for (face = 0; face < GetNumberOfSides(part); face++)
7815 { 8402 {
7816 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8403 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7817 // Convert Shininess to PRIM_SHINY_* 8404 if (shinyness == Shininess.High)
7818 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8405 {
7819 // PRIM_BUMP_* 8406 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7820 res.Add(new LSL_Integer((int)texface.Bump)); 8407 }
8408 else if (shinyness == Shininess.Medium)
8409 {
8410 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8411 }
8412 else if (shinyness == Shininess.Low)
8413 {
8414 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8415 }
8416 else
8417 {
8418 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8419 }
8420 res.Add(new LSL_Integer(shiny));
8421 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7821 } 8422 }
7822 } 8423 }
7823 else 8424 else
7824 { 8425 {
7825 if (face >= 0 && face < GetNumberOfSides(part)) 8426 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8427 if (shinyness == Shininess.High)
7826 { 8428 {
7827 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8429 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7828 // Convert Shininess to PRIM_SHINY_*
7829 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7830 // PRIM_BUMP_*
7831 res.Add(new LSL_Integer((int)texface.Bump));
7832 } 8430 }
8431 else if (shinyness == Shininess.Medium)
8432 {
8433 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8434 }
8435 else if (shinyness == Shininess.Low)
8436 {
8437 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8438 }
8439 else
8440 {
8441 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8442 }
8443 res.Add(new LSL_Integer(shiny));
8444 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7833 } 8445 }
7834 break; 8446 break;
7835 8447
7836 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8448 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7837 if (remain < 1) 8449 if (remain < 1)
7838 return res; 8450 return res;
7839 8451 face = (int)rules.GetLSLIntegerItem(idx++);
7840 face=(int)rules.GetLSLIntegerItem(idx++);
7841 8452
7842 tex = part.Shape.Textures; 8453 tex = part.Shape.Textures;
8454 int fullbright;
7843 if (face == ScriptBaseClass.ALL_SIDES) 8455 if (face == ScriptBaseClass.ALL_SIDES)
7844 { 8456 {
7845 for (face = 0; face < GetNumberOfSides(part); face++) 8457 for (face = 0; face < GetNumberOfSides(part); face++)
7846 { 8458 {
7847 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8459 if (tex.GetFace((uint)face).Fullbright == true)
7848 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8460 {
8461 fullbright = ScriptBaseClass.TRUE;
8462 }
8463 else
8464 {
8465 fullbright = ScriptBaseClass.FALSE;
8466 }
8467 res.Add(new LSL_Integer(fullbright));
7849 } 8468 }
7850 } 8469 }
7851 else 8470 else
7852 { 8471 {
7853 if (face >= 0 && face < GetNumberOfSides(part)) 8472 if (tex.GetFace((uint)face).Fullbright == true)
7854 { 8473 {
7855 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8474 fullbright = ScriptBaseClass.TRUE;
7856 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7857 } 8475 }
8476 else
8477 {
8478 fullbright = ScriptBaseClass.FALSE;
8479 }
8480 res.Add(new LSL_Integer(fullbright));
7858 } 8481 }
7859 break; 8482 break;
7860 8483
@@ -7876,27 +8499,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7876 break; 8499 break;
7877 8500
7878 case (int)ScriptBaseClass.PRIM_TEXGEN: 8501 case (int)ScriptBaseClass.PRIM_TEXGEN:
8502 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7879 if (remain < 1) 8503 if (remain < 1)
7880 return res; 8504 return res;
7881 8505 face = (int)rules.GetLSLIntegerItem(idx++);
7882 face=(int)rules.GetLSLIntegerItem(idx++);
7883 8506
7884 tex = part.Shape.Textures; 8507 tex = part.Shape.Textures;
7885 if (face == ScriptBaseClass.ALL_SIDES) 8508 if (face == ScriptBaseClass.ALL_SIDES)
7886 { 8509 {
7887 for (face = 0; face < GetNumberOfSides(part); face++) 8510 for (face = 0; face < GetNumberOfSides(part); face++)
7888 { 8511 {
7889 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8512 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7890 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8513 {
7891 res.Add(new LSL_Integer((uint)texgen >> 1)); 8514 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8515 }
8516 else
8517 {
8518 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8519 }
7892 } 8520 }
7893 } 8521 }
7894 else 8522 else
7895 { 8523 {
7896 if (face >= 0 && face < GetNumberOfSides(part)) 8524 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8525 {
8526 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8527 }
8528 else
7897 { 8529 {
7898 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8530 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7899 res.Add(new LSL_Integer((uint)texgen >> 1));
7900 } 8531 }
7901 } 8532 }
7902 break; 8533 break;
@@ -7919,28 +8550,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7919 case (int)ScriptBaseClass.PRIM_GLOW: 8550 case (int)ScriptBaseClass.PRIM_GLOW:
7920 if (remain < 1) 8551 if (remain < 1)
7921 return res; 8552 return res;
7922 8553 face = (int)rules.GetLSLIntegerItem(idx++);
7923 face=(int)rules.GetLSLIntegerItem(idx++);
7924 8554
7925 tex = part.Shape.Textures; 8555 tex = part.Shape.Textures;
8556 float primglow;
7926 if (face == ScriptBaseClass.ALL_SIDES) 8557 if (face == ScriptBaseClass.ALL_SIDES)
7927 { 8558 {
7928 for (face = 0; face < GetNumberOfSides(part); face++) 8559 for (face = 0; face < GetNumberOfSides(part); face++)
7929 { 8560 {
7930 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8561 primglow = tex.GetFace((uint)face).Glow;
7931 res.Add(new LSL_Float(texface.Glow)); 8562 res.Add(new LSL_Float(primglow));
7932 } 8563 }
7933 } 8564 }
7934 else 8565 else
7935 { 8566 {
7936 if (face >= 0 && face < GetNumberOfSides(part)) 8567 primglow = tex.GetFace((uint)face).Glow;
7937 { 8568 res.Add(new LSL_Float(primglow));
7938 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7939 res.Add(new LSL_Float(texface.Glow));
7940 }
7941 } 8569 }
7942 break; 8570 break;
7943
7944 case (int)ScriptBaseClass.PRIM_TEXT: 8571 case (int)ScriptBaseClass.PRIM_TEXT:
7945 Color4 textColor = part.GetTextColor(); 8572 Color4 textColor = part.GetTextColor();
7946 res.Add(new LSL_String(part.Text)); 8573 res.Add(new LSL_String(part.Text));
@@ -8489,8 +9116,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8489 // The function returns an ordered list 9116 // The function returns an ordered list
8490 // representing the tokens found in the supplied 9117 // representing the tokens found in the supplied
8491 // sources string. If two successive tokenizers 9118 // sources string. If two successive tokenizers
8492 // are encountered, then a NULL entry is added 9119 // are encountered, then a null-string entry is
8493 // to the list. 9120 // added to the list.
8494 // 9121 //
8495 // It is a precondition that the source and 9122 // It is a precondition that the source and
8496 // toekizer lisst are non-null. If they are null, 9123 // toekizer lisst are non-null. If they are null,
@@ -8498,7 +9125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8498 // while their lengths are being determined. 9125 // while their lengths are being determined.
8499 // 9126 //
8500 // A small amount of working memoryis required 9127 // A small amount of working memoryis required
8501 // of approximately 8*#tokenizers. 9128 // of approximately 8*#tokenizers + 8*srcstrlen.
8502 // 9129 //
8503 // There are many ways in which this function 9130 // There are many ways in which this function
8504 // can be implemented, this implementation is 9131 // can be implemented, this implementation is
@@ -8514,155 +9141,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8514 // and eliminates redundant tokenizers as soon 9141 // and eliminates redundant tokenizers as soon
8515 // as is possible. 9142 // as is possible.
8516 // 9143 //
8517 // The implementation tries to avoid any copying 9144 // The implementation tries to minimize temporary
8518 // of arrays or other objects. 9145 // garbage generation.
8519 // </remarks> 9146 // </remarks>
8520 9147
8521 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9148 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8522 { 9149 {
8523 int beginning = 0; 9150 return ParseString2List(src, separators, spacers, true);
8524 int srclen = src.Length; 9151 }
8525 int seplen = separators.Length;
8526 object[] separray = separators.Data;
8527 int spclen = spacers.Length;
8528 object[] spcarray = spacers.Data;
8529 int mlen = seplen+spclen;
8530
8531 int[] offset = new int[mlen+1];
8532 bool[] active = new bool[mlen];
8533
8534 int best;
8535 int j;
8536
8537 // Initial capacity reduces resize cost
8538 9152
8539 LSL_List tokens = new LSL_List(); 9153 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9154 {
9155 int srclen = src.Length;
9156 int seplen = separators.Length;
9157 object[] separray = separators.Data;
9158 int spclen = spacers.Length;
9159 object[] spcarray = spacers.Data;
9160 int dellen = 0;
9161 string[] delarray = new string[seplen+spclen];
8540 9162
8541 // All entries are initially valid 9163 int outlen = 0;
9164 string[] outarray = new string[srclen*2+1];
8542 9165
8543 for (int i = 0; i < mlen; i++) 9166 int i, j;
8544 active[i] = true; 9167 string d;
8545 9168
8546 offset[mlen] = srclen; 9169 m_host.AddScriptLPS(1);
8547 9170
8548 while (beginning < srclen) 9171 /*
9172 * Convert separator and spacer lists to C# strings.
9173 * Also filter out null strings so we don't hang.
9174 */
9175 for (i = 0; i < seplen; i ++)
8549 { 9176 {
9177 d = separray[i].ToString();
9178 if (d.Length > 0)
9179 {
9180 delarray[dellen++] = d;
9181 }
9182 }
9183 seplen = dellen;
8550 9184
8551 best = mlen; // as bad as it gets 9185 for (i = 0; i < spclen; i ++)
9186 {
9187 d = spcarray[i].ToString();
9188 if (d.Length > 0)
9189 {
9190 delarray[dellen++] = d;
9191 }
9192 }
8552 9193
8553 // Scan for separators 9194 /*
9195 * Scan through source string from beginning to end.
9196 */
9197 for (i = 0;;)
9198 {
8554 9199
8555 for (j = 0; j < seplen; j++) 9200 /*
9201 * Find earliest delimeter in src starting at i (if any).
9202 */
9203 int earliestDel = -1;
9204 int earliestSrc = srclen;
9205 string earliestStr = null;
9206 for (j = 0; j < dellen; j ++)
8556 { 9207 {
8557 if (separray[j].ToString() == String.Empty) 9208 d = delarray[j];
8558 active[j] = false; 9209 if (d != null)
8559
8560 if (active[j])
8561 { 9210 {
8562 // scan all of the markers 9211 int index = src.IndexOf(d, i);
8563 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9212 if (index < 0)
8564 { 9213 {
8565 // not present at all 9214 delarray[j] = null; // delim nowhere in src, don't check it anymore
8566 active[j] = false;
8567 } 9215 }
8568 else 9216 else if (index < earliestSrc)
8569 { 9217 {
8570 // present and correct 9218 earliestSrc = index; // where delimeter starts in source string
8571 if (offset[j] < offset[best]) 9219 earliestDel = j; // where delimeter is in delarray[]
8572 { 9220 earliestStr = d; // the delimeter string from delarray[]
8573 // closest so far 9221 if (index == i) break; // can't do any better than found at beg of string
8574 best = j;
8575 if (offset[best] == beginning)
8576 break;
8577 }
8578 } 9222 }
8579 } 9223 }
8580 } 9224 }
8581 9225
8582 // Scan for spacers 9226 /*
8583 9227 * Output source string starting at i through start of earliest delimeter.
8584 if (offset[best] != beginning) 9228 */
9229 if (keepNulls || (earliestSrc > i))
8585 { 9230 {
8586 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9231 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8587 {
8588 if (spcarray[j-seplen].ToString() == String.Empty)
8589 active[j] = false;
8590
8591 if (active[j])
8592 {
8593 // scan all of the markers
8594 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8595 {
8596 // not present at all
8597 active[j] = false;
8598 }
8599 else
8600 {
8601 // present and correct
8602 if (offset[j] < offset[best])
8603 {
8604 // closest so far
8605 best = j;
8606 }
8607 }
8608 }
8609 }
8610 } 9232 }
8611 9233
8612 // This is the normal exit from the scanning loop 9234 /*
9235 * If no delimeter found at or after i, we're done scanning.
9236 */
9237 if (earliestDel < 0) break;
8613 9238
8614 if (best == mlen) 9239 /*
9240 * If delimeter was a spacer, output the spacer.
9241 */
9242 if (earliestDel >= seplen)
8615 { 9243 {
8616 // no markers were found on this pass 9244 outarray[outlen++] = earliestStr;
8617 // so we're pretty much done
8618 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8619 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8620 break;
8621 } 9245 }
8622 9246
8623 // Otherwise we just add the newly delimited token 9247 /*
8624 // and recalculate where the search should continue. 9248 * Look at rest of src string following delimeter.
8625 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9249 */
8626 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9250 i = earliestSrc + earliestStr.Length;
8627
8628 if (best < seplen)
8629 {
8630 beginning = offset[best] + (separray[best].ToString()).Length;
8631 }
8632 else
8633 {
8634 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8635 string str = spcarray[best - seplen].ToString();
8636 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8637 tokens.Add(new LSL_String(str));
8638 }
8639 } 9251 }
8640 9252
8641 // This an awkward an not very intuitive boundary case. If the 9253 /*
8642 // last substring is a tokenizer, then there is an implied trailing 9254 * Make up an exact-sized output array suitable for an LSL_List object.
8643 // null list entry. Hopefully the single comparison will not be too 9255 */
8644 // arduous. Alternatively the 'break' could be replced with a return 9256 object[] outlist = new object[outlen];
8645 // but that's shabby programming. 9257 for (i = 0; i < outlen; i ++)
8646
8647 if ((beginning == srclen) && (keepNulls))
8648 { 9258 {
8649 if (srclen != 0) 9259 outlist[i] = new LSL_String(outarray[i]);
8650 tokens.Add(new LSL_String(""));
8651 } 9260 }
8652 9261 return new LSL_List(outlist);
8653 return tokens;
8654 }
8655
8656 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8657 {
8658 m_host.AddScriptLPS(1);
8659 return this.ParseString(src, separators, spacers, false);
8660 }
8661
8662 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8663 {
8664 m_host.AddScriptLPS(1);
8665 return this.ParseString(src, separators, spacers, true);
8666 } 9262 }
8667 9263
8668 public LSL_Integer llGetObjectPermMask(int mask) 9264 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8739,28 +9335,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8739 { 9335 {
8740 m_host.AddScriptLPS(1); 9336 m_host.AddScriptLPS(1);
8741 9337
8742 lock (m_host.TaskInventory) 9338 m_host.TaskInventory.LockItemsForRead(true);
9339 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8743 { 9340 {
8744 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9341 if (inv.Value.Name == item)
8745 { 9342 {
8746 if (inv.Value.Name == item) 9343 m_host.TaskInventory.LockItemsForRead(false);
9344 switch (mask)
8747 { 9345 {
8748 switch (mask) 9346 case 0:
8749 { 9347 return (int)inv.Value.BasePermissions;
8750 case 0: 9348 case 1:
8751 return (int)inv.Value.BasePermissions; 9349 return (int)inv.Value.CurrentPermissions;
8752 case 1: 9350 case 2:
8753 return (int)inv.Value.CurrentPermissions; 9351 return (int)inv.Value.GroupPermissions;
8754 case 2: 9352 case 3:
8755 return (int)inv.Value.GroupPermissions; 9353 return (int)inv.Value.EveryonePermissions;
8756 case 3: 9354 case 4:
8757 return (int)inv.Value.EveryonePermissions; 9355 return (int)inv.Value.NextPermissions;
8758 case 4:
8759 return (int)inv.Value.NextPermissions;
8760 }
8761 } 9356 }
8762 } 9357 }
8763 } 9358 }
9359 m_host.TaskInventory.LockItemsForRead(false);
8764 9360
8765 return -1; 9361 return -1;
8766 } 9362 }
@@ -8807,16 +9403,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8807 { 9403 {
8808 m_host.AddScriptLPS(1); 9404 m_host.AddScriptLPS(1);
8809 9405
8810 lock (m_host.TaskInventory) 9406 m_host.TaskInventory.LockItemsForRead(true);
9407 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8811 { 9408 {
8812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9409 if (inv.Value.Name == item)
8813 { 9410 {
8814 if (inv.Value.Name == item) 9411 m_host.TaskInventory.LockItemsForRead(false);
8815 { 9412 return inv.Value.CreatorID.ToString();
8816 return inv.Value.CreatorID.ToString();
8817 }
8818 } 9413 }
8819 } 9414 }
9415 m_host.TaskInventory.LockItemsForRead(false);
8820 9416
8821 llSay(0, "No item name '" + item + "'"); 9417 llSay(0, "No item name '" + item + "'");
8822 9418
@@ -8964,7 +9560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8964 } 9560 }
8965 9561
8966 /// <summary> 9562 /// <summary>
8967 /// illListReplaceList removes the sub-list defined by the inclusive indices 9563 /// llListReplaceList removes the sub-list defined by the inclusive indices
8968 /// start and end and inserts the src list in its place. The inclusive 9564 /// start and end and inserts the src list in its place. The inclusive
8969 /// nature of the indices means that at least one element must be deleted 9565 /// nature of the indices means that at least one element must be deleted
8970 /// if the indices are within the bounds of the existing list. I.e. 2,2 9566 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9021,16 +9617,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9021 // based upon end. Note that if end exceeds the upper 9617 // based upon end. Note that if end exceeds the upper
9022 // bound in this case, the entire destination list 9618 // bound in this case, the entire destination list
9023 // is removed. 9619 // is removed.
9024 else 9620 else if (start == 0)
9025 { 9621 {
9026 if (end + 1 < dest.Length) 9622 if (end + 1 < dest.Length)
9027 {
9028 return src + dest.GetSublist(end + 1, -1); 9623 return src + dest.GetSublist(end + 1, -1);
9029 }
9030 else 9624 else
9031 {
9032 return src; 9625 return src;
9033 } 9626 }
9627 else // Start < 0
9628 {
9629 if (end + 1 < dest.Length)
9630 return dest.GetSublist(end + 1, -1);
9631 else
9632 return new LSL_List();
9034 } 9633 }
9035 } 9634 }
9036 // Finally, if start > end, we strip away a prefix and 9635 // Finally, if start > end, we strip away a prefix and
@@ -9081,17 +9680,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9081 int width = 0; 9680 int width = 0;
9082 int height = 0; 9681 int height = 0;
9083 9682
9084 ParcelMediaCommandEnum? commandToSend = null; 9683 uint commandToSend = 0;
9085 float time = 0.0f; // default is from start 9684 float time = 0.0f; // default is from start
9086 9685
9087 ScenePresence presence = null; 9686 ScenePresence presence = null;
9088 9687
9089 for (int i = 0; i < commandList.Data.Length; i++) 9688 for (int i = 0; i < commandList.Data.Length; i++)
9090 { 9689 {
9091 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9690 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9092 switch (command) 9691 switch (command)
9093 { 9692 {
9094 case ParcelMediaCommandEnum.Agent: 9693 case (uint)ParcelMediaCommandEnum.Agent:
9095 // we send only to one agent 9694 // we send only to one agent
9096 if ((i + 1) < commandList.Length) 9695 if ((i + 1) < commandList.Length)
9097 { 9696 {
@@ -9108,25 +9707,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9108 } 9707 }
9109 break; 9708 break;
9110 9709
9111 case ParcelMediaCommandEnum.Loop: 9710 case (uint)ParcelMediaCommandEnum.Loop:
9112 loop = 1; 9711 loop = 1;
9113 commandToSend = command; 9712 commandToSend = command;
9114 update = true; //need to send the media update packet to set looping 9713 update = true; //need to send the media update packet to set looping
9115 break; 9714 break;
9116 9715
9117 case ParcelMediaCommandEnum.Play: 9716 case (uint)ParcelMediaCommandEnum.Play:
9118 loop = 0; 9717 loop = 0;
9119 commandToSend = command; 9718 commandToSend = command;
9120 update = true; //need to send the media update packet to make sure it doesn't loop 9719 update = true; //need to send the media update packet to make sure it doesn't loop
9121 break; 9720 break;
9122 9721
9123 case ParcelMediaCommandEnum.Pause: 9722 case (uint)ParcelMediaCommandEnum.Pause:
9124 case ParcelMediaCommandEnum.Stop: 9723 case (uint)ParcelMediaCommandEnum.Stop:
9125 case ParcelMediaCommandEnum.Unload: 9724 case (uint)ParcelMediaCommandEnum.Unload:
9126 commandToSend = command; 9725 commandToSend = command;
9127 break; 9726 break;
9128 9727
9129 case ParcelMediaCommandEnum.Url: 9728 case (uint)ParcelMediaCommandEnum.Url:
9130 if ((i + 1) < commandList.Length) 9729 if ((i + 1) < commandList.Length)
9131 { 9730 {
9132 if (commandList.Data[i + 1] is LSL_String) 9731 if (commandList.Data[i + 1] is LSL_String)
@@ -9139,7 +9738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9139 } 9738 }
9140 break; 9739 break;
9141 9740
9142 case ParcelMediaCommandEnum.Texture: 9741 case (uint)ParcelMediaCommandEnum.Texture:
9143 if ((i + 1) < commandList.Length) 9742 if ((i + 1) < commandList.Length)
9144 { 9743 {
9145 if (commandList.Data[i + 1] is LSL_String) 9744 if (commandList.Data[i + 1] is LSL_String)
@@ -9152,7 +9751,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9152 } 9751 }
9153 break; 9752 break;
9154 9753
9155 case ParcelMediaCommandEnum.Time: 9754 case (uint)ParcelMediaCommandEnum.Time:
9156 if ((i + 1) < commandList.Length) 9755 if ((i + 1) < commandList.Length)
9157 { 9756 {
9158 if (commandList.Data[i + 1] is LSL_Float) 9757 if (commandList.Data[i + 1] is LSL_Float)
@@ -9164,7 +9763,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9164 } 9763 }
9165 break; 9764 break;
9166 9765
9167 case ParcelMediaCommandEnum.AutoAlign: 9766 case (uint)ParcelMediaCommandEnum.AutoAlign:
9168 if ((i + 1) < commandList.Length) 9767 if ((i + 1) < commandList.Length)
9169 { 9768 {
9170 if (commandList.Data[i + 1] is LSL_Integer) 9769 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9178,7 +9777,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9178 } 9777 }
9179 break; 9778 break;
9180 9779
9181 case ParcelMediaCommandEnum.Type: 9780 case (uint)ParcelMediaCommandEnum.Type:
9182 if ((i + 1) < commandList.Length) 9781 if ((i + 1) < commandList.Length)
9183 { 9782 {
9184 if (commandList.Data[i + 1] is LSL_String) 9783 if (commandList.Data[i + 1] is LSL_String)
@@ -9191,7 +9790,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9191 } 9790 }
9192 break; 9791 break;
9193 9792
9194 case ParcelMediaCommandEnum.Desc: 9793 case (uint)ParcelMediaCommandEnum.Desc:
9195 if ((i + 1) < commandList.Length) 9794 if ((i + 1) < commandList.Length)
9196 { 9795 {
9197 if (commandList.Data[i + 1] is LSL_String) 9796 if (commandList.Data[i + 1] is LSL_String)
@@ -9204,7 +9803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9204 } 9803 }
9205 break; 9804 break;
9206 9805
9207 case ParcelMediaCommandEnum.Size: 9806 case (uint)ParcelMediaCommandEnum.Size:
9208 if ((i + 2) < commandList.Length) 9807 if ((i + 2) < commandList.Length)
9209 { 9808 {
9210 if (commandList.Data[i + 1] is LSL_Integer) 9809 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9274,7 +9873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9274 } 9873 }
9275 } 9874 }
9276 9875
9277 if (commandToSend != null) 9876 if (commandToSend != 0)
9278 { 9877 {
9279 // the commandList contained a start/stop/... command, too 9878 // the commandList contained a start/stop/... command, too
9280 if (presence == null) 9879 if (presence == null)
@@ -9311,7 +9910,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9311 9910
9312 if (aList.Data[i] != null) 9911 if (aList.Data[i] != null)
9313 { 9912 {
9314 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9913 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9315 { 9914 {
9316 case ParcelMediaCommandEnum.Url: 9915 case ParcelMediaCommandEnum.Url:
9317 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9916 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9354,16 +9953,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9354 { 9953 {
9355 m_host.AddScriptLPS(1); 9954 m_host.AddScriptLPS(1);
9356 9955
9357 lock (m_host.TaskInventory) 9956 m_host.TaskInventory.LockItemsForRead(true);
9957 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9358 { 9958 {
9359 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9959 if (inv.Value.Name == name)
9360 { 9960 {
9361 if (inv.Value.Name == name) 9961 m_host.TaskInventory.LockItemsForRead(false);
9362 { 9962 return inv.Value.Type;
9363 return inv.Value.Type;
9364 }
9365 } 9963 }
9366 } 9964 }
9965 m_host.TaskInventory.LockItemsForRead(false);
9367 9966
9368 return -1; 9967 return -1;
9369 } 9968 }
@@ -9374,15 +9973,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9374 9973
9375 if (quick_pay_buttons.Data.Length < 4) 9974 if (quick_pay_buttons.Data.Length < 4)
9376 { 9975 {
9377 LSLError("List must have at least 4 elements"); 9976 int x;
9378 return; 9977 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9978 {
9979 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9980 }
9379 } 9981 }
9380 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9982 int[] nPrice = new int[5];
9381 9983 nPrice[0] = price;
9382 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9984 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9383 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9985 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9384 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9986 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9385 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9987 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9988 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9386 m_host.ParentGroup.HasGroupChanged = true; 9989 m_host.ParentGroup.HasGroupChanged = true;
9387 } 9990 }
9388 9991
@@ -9394,17 +9997,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9394 if (invItemID == UUID.Zero) 9997 if (invItemID == UUID.Zero)
9395 return new LSL_Vector(); 9998 return new LSL_Vector();
9396 9999
9397 lock (m_host.TaskInventory) 10000 m_host.TaskInventory.LockItemsForRead(true);
10001 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9398 { 10002 {
9399 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10003 m_host.TaskInventory.LockItemsForRead(false);
9400 return new LSL_Vector(); 10004 return new LSL_Vector();
10005 }
9401 10006
9402 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10007 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9403 { 10008 {
9404 ShoutError("No permissions to track the camera"); 10009 ShoutError("No permissions to track the camera");
9405 return new LSL_Vector(); 10010 m_host.TaskInventory.LockItemsForRead(false);
9406 } 10011 return new LSL_Vector();
9407 } 10012 }
10013 m_host.TaskInventory.LockItemsForRead(false);
9408 10014
9409 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10015 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9410 if (presence != null) 10016 if (presence != null)
@@ -9422,17 +10028,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9422 if (invItemID == UUID.Zero) 10028 if (invItemID == UUID.Zero)
9423 return new LSL_Rotation(); 10029 return new LSL_Rotation();
9424 10030
9425 lock (m_host.TaskInventory) 10031 m_host.TaskInventory.LockItemsForRead(true);
10032 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9426 { 10033 {
9427 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10034 m_host.TaskInventory.LockItemsForRead(false);
9428 return new LSL_Rotation(); 10035 return new LSL_Rotation();
9429
9430 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9431 {
9432 ShoutError("No permissions to track the camera");
9433 return new LSL_Rotation();
9434 }
9435 } 10036 }
10037 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10038 {
10039 ShoutError("No permissions to track the camera");
10040 m_host.TaskInventory.LockItemsForRead(false);
10041 return new LSL_Rotation();
10042 }
10043 m_host.TaskInventory.LockItemsForRead(false);
9436 10044
9437 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10045 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9438 if (presence != null) 10046 if (presence != null)
@@ -9494,8 +10102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9494 { 10102 {
9495 m_host.AddScriptLPS(1); 10103 m_host.AddScriptLPS(1);
9496 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10104 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9497 if (detectedParams == null) return; // only works on the first detected avatar 10105 if (detectedParams == null)
9498 10106 {
10107 if (m_host.ParentGroup.IsAttachment == true)
10108 {
10109 detectedParams = new DetectParams();
10110 detectedParams.Key = m_host.OwnerID;
10111 }
10112 else
10113 {
10114 return;
10115 }
10116 }
10117
9499 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10118 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9500 if (avatar != null) 10119 if (avatar != null)
9501 { 10120 {
@@ -9503,6 +10122,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9503 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10122 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9504 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10123 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9505 } 10124 }
10125
9506 ScriptSleep(1000); 10126 ScriptSleep(1000);
9507 } 10127 }
9508 10128
@@ -9595,14 +10215,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9595 if (objectID == UUID.Zero) return; 10215 if (objectID == UUID.Zero) return;
9596 10216
9597 UUID agentID; 10217 UUID agentID;
9598 lock (m_host.TaskInventory) 10218 m_host.TaskInventory.LockItemsForRead(true);
9599 { 10219 // we need the permission first, to know which avatar we want to set the camera for
9600 // we need the permission first, to know which avatar we want to set the camera for 10220 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9601 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9602 10221
9603 if (agentID == UUID.Zero) return; 10222 if (agentID == UUID.Zero)
9604 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10223 {
10224 m_host.TaskInventory.LockItemsForRead(false);
10225 return;
10226 }
10227 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10228 {
10229 m_host.TaskInventory.LockItemsForRead(false);
10230 return;
9605 } 10231 }
10232 m_host.TaskInventory.LockItemsForRead(false);
9606 10233
9607 ScenePresence presence = World.GetScenePresence(agentID); 10234 ScenePresence presence = World.GetScenePresence(agentID);
9608 10235
@@ -9611,12 +10238,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9611 10238
9612 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10239 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9613 object[] data = rules.Data; 10240 object[] data = rules.Data;
9614 for (int i = 0; i < data.Length; ++i) { 10241 for (int i = 0; i < data.Length; ++i)
10242 {
9615 int type = Convert.ToInt32(data[i++].ToString()); 10243 int type = Convert.ToInt32(data[i++].ToString());
9616 if (i >= data.Length) break; // odd number of entries => ignore the last 10244 if (i >= data.Length) break; // odd number of entries => ignore the last
9617 10245
9618 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10246 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9619 switch (type) { 10247 switch (type)
10248 {
9620 case ScriptBaseClass.CAMERA_FOCUS: 10249 case ScriptBaseClass.CAMERA_FOCUS:
9621 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10250 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9622 case ScriptBaseClass.CAMERA_POSITION: 10251 case ScriptBaseClass.CAMERA_POSITION:
@@ -9652,12 +10281,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9652 10281
9653 // we need the permission first, to know which avatar we want to clear the camera for 10282 // we need the permission first, to know which avatar we want to clear the camera for
9654 UUID agentID; 10283 UUID agentID;
9655 lock (m_host.TaskInventory) 10284 m_host.TaskInventory.LockItemsForRead(true);
10285 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10286 if (agentID == UUID.Zero)
9656 { 10287 {
9657 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10288 m_host.TaskInventory.LockItemsForRead(false);
9658 if (agentID == UUID.Zero) return; 10289 return;
9659 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10290 }
10291 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10292 {
10293 m_host.TaskInventory.LockItemsForRead(false);
10294 return;
9660 } 10295 }
10296 m_host.TaskInventory.LockItemsForRead(false);
9661 10297
9662 ScenePresence presence = World.GetScenePresence(agentID); 10298 ScenePresence presence = World.GetScenePresence(agentID);
9663 10299
@@ -9724,19 +10360,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10360 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9725 { 10361 {
9726 m_host.AddScriptLPS(1); 10362 m_host.AddScriptLPS(1);
9727 string ret = String.Empty; 10363
9728 string src1 = llBase64ToString(str1); 10364 if (str1 == String.Empty)
9729 string src2 = llBase64ToString(str2); 10365 return String.Empty;
9730 int c = 0; 10366 if (str2 == String.Empty)
9731 for (int i = 0; i < src1.Length; i++) 10367 return str1;
10368
10369 int len = str2.Length;
10370 if ((len % 4) != 0) // LL is EVIL!!!!
9732 { 10371 {
9733 ret += (char) (src1[i] ^ src2[c]); 10372 while (str2.EndsWith("="))
10373 str2 = str2.Substring(0, str2.Length - 1);
10374
10375 len = str2.Length;
10376 int mod = len % 4;
10377
10378 if (mod == 1)
10379 str2 = str2.Substring(0, str2.Length - 1);
10380 else if (mod == 2)
10381 str2 += "==";
10382 else if (mod == 3)
10383 str2 += "=";
10384 }
9734 10385
9735 c++; 10386 byte[] data1;
9736 if (c >= src2.Length) 10387 byte[] data2;
9737 c = 0; 10388 try
10389 {
10390 data1 = Convert.FromBase64String(str1);
10391 data2 = Convert.FromBase64String(str2);
9738 } 10392 }
9739 return llStringToBase64(ret); 10393 catch (Exception)
10394 {
10395 return new LSL_String(String.Empty);
10396 }
10397
10398 byte[] d2 = new Byte[data1.Length];
10399 int pos = 0;
10400
10401 if (data1.Length <= data2.Length)
10402 {
10403 Array.Copy(data2, 0, d2, 0, data1.Length);
10404 }
10405 else
10406 {
10407 while (pos < data1.Length)
10408 {
10409 len = data1.Length - pos;
10410 if (len > data2.Length)
10411 len = data2.Length;
10412
10413 Array.Copy(data2, 0, d2, pos, len);
10414 pos += len;
10415 }
10416 }
10417
10418 for (pos = 0 ; pos < data1.Length ; pos++ )
10419 data1[pos] ^= d2[pos];
10420
10421 return Convert.ToBase64String(data1);
9740 } 10422 }
9741 10423
9742 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10424 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9795,12 +10477,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9795 Regex r = new Regex(authregex); 10477 Regex r = new Regex(authregex);
9796 int[] gnums = r.GetGroupNumbers(); 10478 int[] gnums = r.GetGroupNumbers();
9797 Match m = r.Match(url); 10479 Match m = r.Match(url);
9798 if (m.Success) { 10480 if (m.Success)
9799 for (int i = 1; i < gnums.Length; i++) { 10481 {
10482 for (int i = 1; i < gnums.Length; i++)
10483 {
9800 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10484 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9801 //CaptureCollection cc = g.Captures; 10485 //CaptureCollection cc = g.Captures;
9802 } 10486 }
9803 if (m.Groups.Count == 5) { 10487 if (m.Groups.Count == 5)
10488 {
9804 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10489 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9805 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10490 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9806 } 10491 }
@@ -10086,15 +10771,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10086 10771
10087 internal UUID ScriptByName(string name) 10772 internal UUID ScriptByName(string name)
10088 { 10773 {
10089 lock (m_host.TaskInventory) 10774 m_host.TaskInventory.LockItemsForRead(true);
10775
10776 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10090 { 10777 {
10091 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10778 if (item.Type == 10 && item.Name == name)
10092 { 10779 {
10093 if (item.Type == 10 && item.Name == name) 10780 m_host.TaskInventory.LockItemsForRead(false);
10094 return item.ItemID; 10781 return item.ItemID;
10095 } 10782 }
10096 } 10783 }
10097 10784
10785 m_host.TaskInventory.LockItemsForRead(false);
10786
10098 return UUID.Zero; 10787 return UUID.Zero;
10099 } 10788 }
10100 10789
@@ -10135,6 +10824,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10135 { 10824 {
10136 m_host.AddScriptLPS(1); 10825 m_host.AddScriptLPS(1);
10137 10826
10827 //Clone is thread safe
10138 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10828 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10139 10829
10140 UUID assetID = UUID.Zero; 10830 UUID assetID = UUID.Zero;
@@ -10197,6 +10887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10197 { 10887 {
10198 m_host.AddScriptLPS(1); 10888 m_host.AddScriptLPS(1);
10199 10889
10890 //Clone is thread safe
10200 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10891 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10201 10892
10202 UUID assetID = UUID.Zero; 10893 UUID assetID = UUID.Zero;
@@ -10277,15 +10968,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10277 return GetLinkPrimitiveParams(obj, rules); 10968 return GetLinkPrimitiveParams(obj, rules);
10278 } 10969 }
10279 10970
10280 public void print(string str) 10971 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10281 { 10972 {
10282 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10973 List<SceneObjectPart> parts = GetLinkParts(link);
10283 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10974 if (parts.Count < 1)
10284 if (ossl != null) 10975 return 0;
10285 { 10976
10286 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10977 return GetNumberOfSides(parts[0]);
10287 m_log.Info("LSL print():" + str);
10288 }
10289 } 10978 }
10290 10979
10291 private string Name2Username(string name) 10980 private string Name2Username(string name)
@@ -10331,6 +11020,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10331 return rq.ToString(); 11020 return rq.ToString();
10332 } 11021 }
10333 11022
11023 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11024 {
11025 m_SayShoutCount = 0;
11026 }
10334 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11027 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10335 { 11028 {
10336 m_host.AddScriptLPS(1); 11029 m_host.AddScriptLPS(1);
@@ -10500,22 +11193,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10500 NotImplemented("llGetSPMaxMemory"); 11193 NotImplemented("llGetSPMaxMemory");
10501 } 11194 }
10502 11195
10503 public void llGetUsedMemory() 11196 public virtual LSL_Integer llGetUsedMemory()
10504 { 11197 {
10505 m_host.AddScriptLPS(1); 11198 m_host.AddScriptLPS(1);
10506 NotImplemented("llGetUsedMemory"); 11199 NotImplemented("llGetUsedMemory");
11200 return 0;
10507 } 11201 }
10508 11202
10509 public void llScriptProfiler(LSL_Integer flags) 11203 public void llScriptProfiler(LSL_Integer flags)
10510 { 11204 {
10511 m_host.AddScriptLPS(1); 11205 m_host.AddScriptLPS(1);
10512 NotImplemented("llScriptProfiler"); 11206 //NotImplemented("llScriptProfiler");
10513 } 11207 }
10514 11208
10515 public void llSetSoundQueueing(int queue) 11209 public void llSetSoundQueueing(int queue)
10516 { 11210 {
10517 m_host.AddScriptLPS(1); 11211 m_host.AddScriptLPS(1);
10518 NotImplemented("llSetSoundQueueing");
10519 } 11212 }
10520 11213
10521 public void llCollisionSprite(string impact_sprite) 11214 public void llCollisionSprite(string impact_sprite)
@@ -10527,7 +11220,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10527 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11220 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10528 { 11221 {
10529 m_host.AddScriptLPS(1); 11222 m_host.AddScriptLPS(1);
10530 NotImplemented("llGodLikeRezObject"); 11223
11224 if (!World.Permissions.IsGod(m_host.OwnerID))
11225 NotImplemented("llGodLikeRezObject");
11226
11227 AssetBase rezAsset = World.AssetService.Get(inventory);
11228 if (rezAsset == null)
11229 {
11230 llSay(0, "Asset not found");
11231 return;
11232 }
11233
11234 SceneObjectGroup group = null;
11235
11236 try
11237 {
11238 string xmlData = Utils.BytesToString(rezAsset.Data);
11239 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11240 }
11241 catch
11242 {
11243 llSay(0, "Asset not found");
11244 return;
11245 }
11246
11247 if (group == null)
11248 {
11249 llSay(0, "Asset not found");
11250 return;
11251 }
11252
11253 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11254 group.RootPart.AttachOffset = group.AbsolutePosition;
11255
11256 group.ResetIDs();
11257
11258 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11259 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11260 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11261 group.ScheduleGroupForFullUpdate();
11262
11263 // objects rezzed with this method are die_at_edge by default.
11264 group.RootPart.SetDieAtEdge(true);
11265
11266 group.ResumeScripts();
11267
11268 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11269 "object_rez", new Object[] {
11270 new LSL_String(
11271 group.RootPart.UUID.ToString()) },
11272 new DetectParams[0]));
10531 } 11273 }
10532 11274
10533 #endregion 11275 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index e1c837e..8f450f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
136 internal float m_ScriptDelayFactor = 1.0f; 136 internal float m_ScriptDelayFactor = 1.0f;
137 internal float m_ScriptDistanceFactor = 1.0f; 137 internal float m_ScriptDistanceFactor = 1.0f;
138 internal bool m_debuggerSafe = false;
138 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 139 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
139 140
140 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -143,6 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 m_host = host; 144 m_host = host;
144 m_localID = localID; 145 m_localID = localID;
145 m_itemID = itemID; 146 m_itemID = itemID;
147 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 148
147 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
148 m_OSFunctionsEnabled = true; 150 m_OSFunctionsEnabled = true;
@@ -201,7 +203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 203
202 internal void OSSLError(string msg) 204 internal void OSSLError(string msg)
203 { 205 {
204 throw new Exception("OSSL Runtime Error: " + msg); 206 if (m_debuggerSafe)
207 {
208 OSSLShoutError(msg);
209 }
210 else
211 {
212 throw new Exception("OSSL Runtime Error: " + msg);
213 }
205 } 214 }
206 215
207 private void InitLSL() 216 private void InitLSL()
@@ -840,18 +849,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
840 if (target != null) 849 if (target != null)
841 { 850 {
842 UUID animID=UUID.Zero; 851 UUID animID=UUID.Zero;
843 lock (m_host.TaskInventory) 852 m_host.TaskInventory.LockItemsForRead(true);
853 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
844 { 854 {
845 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 855 if (inv.Value.Name == animation)
846 { 856 {
847 if (inv.Value.Name == animation) 857 if (inv.Value.Type == (int)AssetType.Animation)
848 { 858 animID = inv.Value.AssetID;
849 if (inv.Value.Type == (int)AssetType.Animation) 859 continue;
850 animID = inv.Value.AssetID;
851 continue;
852 }
853 } 860 }
854 } 861 }
862 m_host.TaskInventory.LockItemsForRead(false);
855 if (animID == UUID.Zero) 863 if (animID == UUID.Zero)
856 target.Animator.AddAnimation(animation, m_host.UUID); 864 target.Animator.AddAnimation(animation, m_host.UUID);
857 else 865 else
@@ -873,18 +881,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
873 if (target != null) 881 if (target != null)
874 { 882 {
875 UUID animID = UUID.Zero; 883 UUID animID = UUID.Zero;
876 lock (m_host.TaskInventory) 884 m_host.TaskInventory.LockItemsForRead(true);
885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
877 { 886 {
878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 887 if (inv.Value.Name == animation)
879 { 888 {
880 if (inv.Value.Name == animation) 889 if (inv.Value.Type == (int)AssetType.Animation)
881 { 890 animID = inv.Value.AssetID;
882 if (inv.Value.Type == (int)AssetType.Animation) 891 continue;
883 animID = inv.Value.AssetID;
884 continue;
885 }
886 } 892 }
887 } 893 }
894 m_host.TaskInventory.LockItemsForRead(false);
888 895
889 if (animID == UUID.Zero) 896 if (animID == UUID.Zero)
890 target.Animator.RemoveAnimation(animation); 897 target.Animator.RemoveAnimation(animation);
@@ -1834,6 +1841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1834 1841
1835 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1842 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1836 { 1843 {
1844 m_host.TaskInventory.LockItemsForRead(true);
1837 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1838 { 1846 {
1839 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1847 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1841,6 +1849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 assetID = item.AssetID; 1849 assetID = item.AssetID;
1842 } 1850 }
1843 } 1851 }
1852 m_host.TaskInventory.LockItemsForRead(false);
1844 } 1853 }
1845 1854
1846 if (assetID == UUID.Zero) 1855 if (assetID == UUID.Zero)
@@ -2164,8 +2173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2164 UUID x = module.CreateNPC(firstname, 2173 UUID x = module.CreateNPC(firstname,
2165 lastname, 2174 lastname,
2166 new Vector3((float) position.x, (float) position.y, (float) position.z), 2175 new Vector3((float) position.x, (float) position.y, (float) position.z),
2167 World, 2176 World,appearance);
2168 appearance);
2169 2177
2170 return new LSL_Key(x.ToString()); 2178 return new LSL_Key(x.ToString());
2171 } 2179 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 4ac7f8b..6de0773 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -429,6 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 435 q = avatar.Rotation;
433 } 436 }
434 437
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }