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.cs2190
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
6 files changed, 1641 insertions, 788 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 1cf03b8..c240edf 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;
@@ -65,6 +67,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 69using System.Reflection;
70using Timer = System.Timers.Timer;
68 71
69namespace OpenSim.Region.ScriptEngine.Shared.Api 72namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 73{
@@ -81,7 +84,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 84 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 85 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 86 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 87// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 88 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 89 protected SceneObjectPart m_host;
87 protected uint m_localID; 90 protected uint m_localID;
@@ -99,16 +102,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 102 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 103 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 104 protected bool m_scriptConsoleChannelEnabled = false;
105 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 106 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 108 new Dictionary<UUID, UserInfoCacheEntry>();
105 109
110 protected Timer m_ShoutSayTimer;
111 protected int m_SayShoutCount = 0;
112
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 113 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 114 {
115 m_ShoutSayTimer = new Timer(1000);
116 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
117 m_ShoutSayTimer.AutoReset = true;
118 m_ShoutSayTimer.Start();
119
108 m_ScriptEngine = ScriptEngine; 120 m_ScriptEngine = ScriptEngine;
109 m_host = host; 121 m_host = host;
110 m_localID = localID; 122 m_localID = localID;
111 m_itemID = itemID; 123 m_itemID = itemID;
124 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 125
113 m_ScriptDelayFactor = 126 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 127 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 174 get { return m_ScriptEngine.World; }
162 } 175 }
163 176
177 [DebuggerNonUserCode]
164 public void state(string newState) 178 public void state(string newState)
165 { 179 {
166 m_ScriptEngine.SetState(m_itemID, newState); 180 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 184 /// Reset the named script. The script must be present
171 /// in the same prim. 185 /// in the same prim.
172 /// </summary> 186 /// </summary>
187 [DebuggerNonUserCode]
173 public void llResetScript() 188 public void llResetScript()
174 { 189 {
175 m_host.AddScriptLPS(1); 190 m_host.AddScriptLPS(1);
@@ -226,9 +241,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 241 }
227 } 242 }
228 243
244 public List<ScenePresence> GetLinkAvatars(int linkType)
245 {
246 List<ScenePresence> ret = new List<ScenePresence>();
247 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
248 return ret;
249
250 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
251
252 switch (linkType)
253 {
254 case ScriptBaseClass.LINK_SET:
255 return avs;
256
257 case ScriptBaseClass.LINK_ROOT:
258 return ret;
259
260 case ScriptBaseClass.LINK_ALL_OTHERS:
261 return avs;
262
263 case ScriptBaseClass.LINK_ALL_CHILDREN:
264 return avs;
265
266 case ScriptBaseClass.LINK_THIS:
267 return ret;
268
269 default:
270 if (linkType < 0)
271 return ret;
272
273 int partCount = m_host.ParentGroup.GetPartCount();
274
275 if (linkType <= partCount)
276 {
277 return ret;
278 }
279 else
280 {
281 linkType = linkType - partCount;
282 if (linkType > avs.Count)
283 {
284 return ret;
285 }
286 else
287 {
288 ret.Add(avs[linkType-1]);
289 return ret;
290 }
291 }
292 }
293 }
294
229 public List<SceneObjectPart> GetLinkParts(int linkType) 295 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 296 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 297 List<SceneObjectPart> ret = new List<SceneObjectPart>();
298 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
299 return ret;
232 ret.Add(m_host); 300 ret.Add(m_host);
233 301
234 switch (linkType) 302 switch (linkType)
@@ -288,40 +356,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 356 protected UUID InventorySelf()
289 { 357 {
290 UUID invItemID = new UUID(); 358 UUID invItemID = new UUID();
291 359 bool unlock = false;
292 lock (m_host.TaskInventory) 360 if (!m_host.TaskInventory.IsReadLockedByMe())
361 {
362 m_host.TaskInventory.LockItemsForRead(true);
363 unlock = true;
364 }
365 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 366 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 367 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 368 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 369 invItemID = inv.Key;
297 { 370 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 371 }
302 } 372 }
303 373 if (unlock)
374 {
375 m_host.TaskInventory.LockItemsForRead(false);
376 }
304 return invItemID; 377 return invItemID;
305 } 378 }
306 379
307 protected UUID InventoryKey(string name, int type) 380 protected UUID InventoryKey(string name, int type)
308 { 381 {
309 m_host.AddScriptLPS(1); 382 m_host.AddScriptLPS(1);
310 383 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 384
385 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 386 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 387 if (inv.Value.Name == name)
314 { 388 {
315 if (inv.Value.Name == name) 389 m_host.TaskInventory.LockItemsForRead(false);
390
391 if (inv.Value.Type != type)
316 { 392 {
317 if (inv.Value.Type != type) 393 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 394 }
395
396 return inv.Value.AssetID;
322 } 397 }
323 } 398 }
324 399
400 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 401 return UUID.Zero;
326 } 402 }
327 403
@@ -329,17 +405,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 405 {
330 m_host.AddScriptLPS(1); 406 m_host.AddScriptLPS(1);
331 407
332 lock (m_host.TaskInventory) 408
409 m_host.TaskInventory.LockItemsForRead(true);
410
411 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 412 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 413 if (inv.Value.Name == name)
335 { 414 {
336 if (inv.Value.Name == name) 415 m_host.TaskInventory.LockItemsForRead(false);
337 { 416 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 417 }
341 } 418 }
342 419
420 m_host.TaskInventory.LockItemsForRead(false);
421
422
343 return UUID.Zero; 423 return UUID.Zero;
344 } 424 }
345 425
@@ -481,26 +561,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 561
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 562 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 563
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 564 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
486 565
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 566 // normalize an angle between -PI and PI (-180 to +180 degrees)
567 protected double NormalizeAngle(double angle)
568 {
569 if (angle > -Math.PI && angle < Math.PI)
570 return angle;
571
572 int numPis = (int)(Math.PI / angle);
573 double remainder = angle - Math.PI * numPis;
574 if (numPis % 2 == 1)
575 return Math.PI - angle;
576 return remainder;
577 }
578
579 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 580 {
489 m_host.AddScriptLPS(1); 581 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 582 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 583
492 double m = (t.x + t.y + t.z + t.s); 584 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 585 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 586 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 587 double sqz = q1.y*q1.y;
496 if (p > 0) 588 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 589 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 590 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 591 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 592 eul.y = Math.PI/2;
501 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)); 593 eul.x = 0;
502 else 594 return eul;
503 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)); 595 }
596 if (test < -0.4999*unit) { // singularity at south pole
597 eul.z = -2 * Math.Atan2(q1.x,q1.s);
598 eul.y = -Math.PI/2;
599 eul.x = 0;
600 return eul;
601 }
602 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
603 eul.y = Math.Asin(2*test/unit);
604 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
605 return eul;
504 } 606 }
505 607
506 /* From wiki: 608 /* From wiki:
@@ -702,77 +804,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 804 {
703 //A and B should both be normalized 805 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 806 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 807 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 808 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 809
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 810 double dotProduct = LSL_Vector.Dot(a, b);
811 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
812 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
813 double angle = Math.Acos(dotProduct / magProduct);
814 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
815 double s = Math.Sin(angle / 2);
816
817 double x = axis.x * s;
818 double y = axis.y * s;
819 double z = axis.z * s;
820 double w = Math.Cos(angle / 2);
821
822 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
823 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
824
825 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
826 */
827
828 // This method mimics the 180 errors found in SL
829 // See www.euclideanspace.com... angleBetween
830 LSL_Vector vec_a = a;
831 LSL_Vector vec_b = b;
832
833 // Eliminate zero length
834 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
835 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
836 if (vec_a_mag < 0.00001 ||
837 vec_b_mag < 0.00001)
709 { 838 {
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 839 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 } 840 }
712 else 841
842 // Normalize
843 vec_a = llVecNorm(vec_a);
844 vec_b = llVecNorm(vec_b);
845
846 // Calculate axis and rotation angle
847 LSL_Vector axis = vec_a % vec_b;
848 LSL_Float cos_theta = vec_a * vec_b;
849
850 // Check if parallel
851 if (cos_theta > 0.99999)
713 { 852 {
714 a = LSL_Vector.Norm(a); 853 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 b = LSL_Vector.Norm(b); 854 }
716 double dotProduct = LSL_Vector.Dot(a, b); 855
717 // There are two degenerate cases possible. These are for vectors 180 or 856 // Check if anti-parallel
718 // 0 degrees apart. These have to be detected and handled individually. 857 else if (cos_theta < -0.99999)
719 // 858 {
720 // Check for vectors 180 degrees apart. 859 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 860 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
722 if (dotProduct < -0.9999999f) 861 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
723 { 862 }
724 // First assume X axis is orthogonal to the vectors. 863 else // other rotation
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 864 {
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 865 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
727 // Check for near zero vector. A very small non-zero number here will create 866 axis = llVecNorm(axis);
728 // a rotation in an undesired direction. 867 double x, y, z, s, t;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 868 s = Math.Cos(theta);
730 { 869 t = Math.Sin(theta);
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 870 x = axis.x * t;
732 } 871 y = axis.y * t;
733 // If the magnitude of the vector was near zero, then assume the X axis is not 872 z = axis.z * t;
734 // orthogonal and use the Z axis instead. 873 return new LSL_Rotation(x,y,z,s);
735 else
736 {
737 // Set 180 z rotation.
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
739 }
740 }
741 // Check for parallel vectors.
742 // A dot product of 1 would mean the angle between vectors is 0 degrees.
743 else if (dotProduct > 0.9999999f)
744 {
745 // Set zero rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
747 }
748 else
749 {
750 // All special checks have been performed so get the axis of rotation.
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
752 // Quarternion s value is the length of the unit vector + dot product.
753 double qs = 1.0 + dotProduct;
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
755 // Normalize the rotation.
756 double mag = LSL_Rotation.Mag(rotBetween);
757 // We shouldn't have to worry about a divide by zero here. The qs value will be
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the
760 // crossProduct vector should also not be zero.
761 rotBetween.x = rotBetween.x / mag;
762 rotBetween.y = rotBetween.y / mag;
763 rotBetween.z = rotBetween.z / mag;
764 rotBetween.s = rotBetween.s / mag;
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required
766 // any longer since zero vectors are checked for at the top.
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
768 {
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
770 }
771 }
772 } 874 }
773 return rotBetween;
774 } 875 }
775 876
776 public void llWhisper(int channelID, string text) 877 public void llWhisper(int channelID, string text)
777 { 878 {
778 m_host.AddScriptLPS(1); 879 m_host.AddScriptLPS(1);
@@ -792,6 +893,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
792 { 893 {
793 m_host.AddScriptLPS(1); 894 m_host.AddScriptLPS(1);
794 895
896 if (channelID == 0)
897 m_SayShoutCount++;
898
899 if (m_SayShoutCount >= 11)
900 ScriptSleep(2000);
901
795 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 902 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
796 { 903 {
797 Console.WriteLine(text); 904 Console.WriteLine(text);
@@ -814,6 +921,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
814 { 921 {
815 m_host.AddScriptLPS(1); 922 m_host.AddScriptLPS(1);
816 923
924 if (channelID == 0)
925 m_SayShoutCount++;
926
927 if (m_SayShoutCount >= 11)
928 ScriptSleep(2000);
929
817 if (text.Length > 1023) 930 if (text.Length > 1023)
818 text = text.Substring(0, 1023); 931 text = text.Substring(0, 1023);
819 932
@@ -1096,10 +1209,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1209 return detectedParams.TouchUV;
1097 } 1210 }
1098 1211
1212 [DebuggerNonUserCode]
1099 public virtual void llDie() 1213 public virtual void llDie()
1100 { 1214 {
1101 m_host.AddScriptLPS(1); 1215 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1216 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1217 }
1104 1218
1105 public LSL_Float llGround(LSL_Vector offset) 1219 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1286,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1286
1173 public void llSetStatus(int status, int value) 1287 public void llSetStatus(int status, int value)
1174 { 1288 {
1289 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1290 return;
1175 m_host.AddScriptLPS(1); 1291 m_host.AddScriptLPS(1);
1176 1292
1177 int statusrotationaxis = 0; 1293 int statusrotationaxis = 0;
@@ -1402,6 +1518,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1518 {
1403 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1404 1520
1521 SetColor(m_host, color, face);
1522 }
1523
1524 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1525 {
1526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1527 return;
1528
1529 Primitive.TextureEntry tex = part.Shape.Textures;
1530 Color4 texcolor;
1531 if (face >= 0 && face < GetNumberOfSides(part))
1532 {
1533 texcolor = tex.CreateFace((uint)face).RGBA;
1534 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1535 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1536 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1537 tex.FaceTextures[face].RGBA = texcolor;
1538 part.UpdateTexture(tex);
1539 return;
1540 }
1541 else if (face == ScriptBaseClass.ALL_SIDES)
1542 {
1543 for (uint i = 0; i < GetNumberOfSides(part); i++)
1544 {
1545 if (tex.FaceTextures[i] != null)
1546 {
1547 texcolor = tex.FaceTextures[i].RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[i].RGBA = texcolor;
1552 }
1553 texcolor = tex.DefaultTexture.RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.DefaultTexture.RGBA = texcolor;
1558 }
1559 part.UpdateTexture(tex);
1560 return;
1561 }
1562
1405 if (face == ScriptBaseClass.ALL_SIDES) 1563 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1564 face = SceneObjectPart.ALL_SIDES;
1407 1565
@@ -1410,6 +1568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1568
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1569 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1570 {
1571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1572 return;
1573
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1574 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1575 MappingType textype;
1415 textype = MappingType.Default; 1576 textype = MappingType.Default;
@@ -1440,6 +1601,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1601
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1602 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1607 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1608 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1609 {
@@ -1465,6 +1629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1629
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1630 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1631 {
1632 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1633 return;
1468 1634
1469 Shininess sval = new Shininess(); 1635 Shininess sval = new Shininess();
1470 1636
@@ -1515,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1681
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1682 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1689 {
@@ -1575,13 +1744,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1744 m_host.AddScriptLPS(1);
1576 1745
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1746 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1747 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1748 {
1580 SetAlpha(part, alpha, face); 1749 try
1750 {
1751 parts[0].ParentGroup.areUpdatesSuspended = true;
1752 foreach (SceneObjectPart part in parts)
1753 SetAlpha(part, alpha, face);
1754 }
1755 finally
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = false;
1758 }
1759 }
1581 } 1760 }
1582 1761
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1762 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1768 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1809 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1810 float wind, float tension, LSL_Vector Force)
1629 { 1811 {
1630 if (part == null) 1812 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1813 return;
1632 1814
1633 if (flexi) 1815 if (flexi)
@@ -1662,7 +1844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1844 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1845 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1846 {
1665 if (part == null) 1847 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1848 return;
1667 1849
1668 if (light) 1850 if (light)
@@ -1739,15 +1921,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1921 m_host.AddScriptLPS(1);
1740 1922
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1923 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1924 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1925 {
1744 SetTexture(part, texture, face); 1926 try
1745 1927 {
1928 parts[0].ParentGroup.areUpdatesSuspended = true;
1929 foreach (SceneObjectPart part in parts)
1930 SetTexture(part, texture, face);
1931 }
1932 finally
1933 {
1934 parts[0].ParentGroup.areUpdatesSuspended = false;
1935 }
1936 }
1746 ScriptSleep(200); 1937 ScriptSleep(200);
1747 } 1938 }
1748 1939
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1940 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1941 {
1942 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1943 return;
1944
1751 UUID textureID = new UUID(); 1945 UUID textureID = new UUID();
1752 1946
1753 textureID = InventoryKey(texture, (int)AssetType.Texture); 1947 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1792,6 +1986,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1986
1793 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1987 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1794 { 1988 {
1989 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1990 return;
1991
1795 Primitive.TextureEntry tex = part.Shape.Textures; 1992 Primitive.TextureEntry tex = part.Shape.Textures;
1796 if (face >= 0 && face < GetNumberOfSides(part)) 1993 if (face >= 0 && face < GetNumberOfSides(part))
1797 { 1994 {
@@ -1828,6 +2025,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 2025
1829 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2026 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1830 { 2027 {
2028 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2029 return;
2030
1831 Primitive.TextureEntry tex = part.Shape.Textures; 2031 Primitive.TextureEntry tex = part.Shape.Textures;
1832 if (face >= 0 && face < GetNumberOfSides(part)) 2032 if (face >= 0 && face < GetNumberOfSides(part))
1833 { 2033 {
@@ -1864,6 +2064,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1864 2064
1865 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2065 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1866 { 2066 {
2067 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2068 return;
2069
1867 Primitive.TextureEntry tex = part.Shape.Textures; 2070 Primitive.TextureEntry tex = part.Shape.Textures;
1868 if (face >= 0 && face < GetNumberOfSides(part)) 2071 if (face >= 0 && face < GetNumberOfSides(part))
1869 { 2072 {
@@ -1932,10 +2135,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 return end; 2135 return end;
1933 } 2136 }
1934 2137
1935 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2138 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1936 { 2139 {
2140 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2141 return fromPos;
2142
1937 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2143 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1938 LSL_Vector currentPos = GetPartLocalPos(part); 2144
1939 2145
1940 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2146 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1941 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2147 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1944,14 +2150,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 { 2150 {
1945 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2151 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
1946 targetPos.z = ground; 2152 targetPos.z = ground;
2153 }
2154 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2155
2156 return real_vec;
2157 }
2158
2159 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2160 {
2161 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2162 return;
2163
2164 LSL_Vector currentPos = GetPartLocalPos(part);
2165 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2166
2167 if (part.ParentGroup.RootPart == part)
2168 {
1947 SceneObjectGroup parent = part.ParentGroup; 2169 SceneObjectGroup parent = part.ParentGroup;
1948 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2170 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1949 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1950 } 2171 }
1951 else 2172 else
1952 { 2173 {
1953 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2174 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1954 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1955 SceneObjectGroup parent = part.ParentGroup; 2175 SceneObjectGroup parent = part.ParentGroup;
1956 parent.HasGroupChanged = true; 2176 parent.HasGroupChanged = true;
1957 parent.ScheduleGroupForTerseUpdate(); 2177 parent.ScheduleGroupForTerseUpdate();
@@ -2002,9 +2222,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 m_host.AddScriptLPS(1); 2222 m_host.AddScriptLPS(1);
2003 2223
2004 // try to let this work as in SL... 2224 // try to let this work as in SL...
2005 if (m_host.ParentID == 0) 2225 if (m_host.LinkNum < 2)
2006 { 2226 {
2007 // special case: If we are root, rotate complete SOG to new rotation 2227 // Special case: If we are root, rotate complete SOG to new
2228 // rotation.
2229 // We are root if the link number is 0 (single prim) or 1
2230 // (root prim). ParentID may be nonzero in attachments and
2231 // using it would cause attachments and HUDs to rotate
2232 // to the wrong positions.
2008 SetRot(m_host, Rot2Quaternion(rot)); 2233 SetRot(m_host, Rot2Quaternion(rot));
2009 } 2234 }
2010 else 2235 else
@@ -2033,6 +2258,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2033 2258
2034 protected void SetRot(SceneObjectPart part, Quaternion rot) 2259 protected void SetRot(SceneObjectPart part, Quaternion rot)
2035 { 2260 {
2261 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2262 return;
2263
2036 part.UpdateRotation(rot); 2264 part.UpdateRotation(rot);
2037 // Update rotation does not move the object in the physics scene if it's a linkset. 2265 // Update rotation does not move the object in the physics scene if it's a linkset.
2038 2266
@@ -2652,12 +2880,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 2880
2653 m_host.AddScriptLPS(1); 2881 m_host.AddScriptLPS(1);
2654 2882
2883 m_host.TaskInventory.LockItemsForRead(true);
2655 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2884 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2656 2885 m_host.TaskInventory.LockItemsForRead(false);
2657 lock (m_host.TaskInventory)
2658 {
2659 item = m_host.TaskInventory[invItemID];
2660 }
2661 2886
2662 if (item.PermsGranter == UUID.Zero) 2887 if (item.PermsGranter == UUID.Zero)
2663 return 0; 2888 return 0;
@@ -2732,6 +2957,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 if (dist > m_ScriptDistanceFactor * 10.0f) 2957 if (dist > m_ScriptDistanceFactor * 10.0f)
2733 return; 2958 return;
2734 2959
2960 //Clone is thread-safe
2735 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2961 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2736 2962
2737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2963 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2794,6 +3020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 3020
2795 public void llLookAt(LSL_Vector target, double strength, double damping) 3021 public void llLookAt(LSL_Vector target, double strength, double damping)
2796 { 3022 {
3023 /*
2797 m_host.AddScriptLPS(1); 3024 m_host.AddScriptLPS(1);
2798 // Determine where we are looking from 3025 // Determine where we are looking from
2799 LSL_Vector from = llGetPos(); 3026 LSL_Vector from = llGetPos();
@@ -2813,10 +3040,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 // the angles of rotation in radians into rotation value 3040 // the angles of rotation in radians into rotation value
2814 3041
2815 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3042 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2816 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3043
2817 m_host.startLookAt(rotation, (float)damping, (float)strength); 3044 // This would only work if your physics system contains an APID controller:
3045 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3046 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3047
2818 // Orient the object to the angle calculated 3048 // Orient the object to the angle calculated
2819 //llSetRot(rot); 3049 llSetRot(rot);
3050 */
3051
3052 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3053 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3054 // http://bugs.meta7.com/view.php?id=28
3055 // - Tom
3056
3057 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3058 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3059 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3060 */
3061 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3062 {
3063 // Part is non-phys, convert this to a llSetRot()
3064 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3065 Vector3 dir = tgt - m_host.GroupPosition;
3066 dir.Normalize();
3067 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3068 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3069 float terot = (float)Math.Atan2(-dir.Z, txy);
3070 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3071 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3072 LSL_Types.Quaternion spin = llEuler2Rot(az);
3073 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3074 llSetRot(rot);
3075 }
3076 else
3077 {
3078 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3079 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3080 m_host.RotLookAt(q, (float)strength, (float)damping);
3081 }
3082
3083 }
3084
3085 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3086 {
3087 m_host.AddScriptLPS(1);
3088// NotImplemented("llRotLookAt");
3089 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3090
2820 } 3091 }
2821 3092
2822 public void llStopLookAt() 3093 public void llStopLookAt()
@@ -2865,13 +3136,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 { 3136 {
2866 TaskInventoryItem item; 3137 TaskInventoryItem item;
2867 3138
2868 lock (m_host.TaskInventory) 3139 m_host.TaskInventory.LockItemsForRead(true);
3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2869 { 3141 {
2870 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3142 m_host.TaskInventory.LockItemsForRead(false);
2871 return; 3143 return;
2872 else
2873 item = m_host.TaskInventory[InventorySelf()];
2874 } 3144 }
3145 else
3146 {
3147 item = m_host.TaskInventory[InventorySelf()];
3148 }
3149 m_host.TaskInventory.LockItemsForRead(false);
2875 3150
2876 if (item.PermsGranter != UUID.Zero) 3151 if (item.PermsGranter != UUID.Zero)
2877 { 3152 {
@@ -2893,13 +3168,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2893 { 3168 {
2894 TaskInventoryItem item; 3169 TaskInventoryItem item;
2895 3170
3171 m_host.TaskInventory.LockItemsForRead(true);
2896 lock (m_host.TaskInventory) 3172 lock (m_host.TaskInventory)
2897 { 3173 {
3174
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3175 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3176 {
3177 m_host.TaskInventory.LockItemsForRead(false);
2899 return; 3178 return;
3179 }
2900 else 3180 else
3181 {
2901 item = m_host.TaskInventory[InventorySelf()]; 3182 item = m_host.TaskInventory[InventorySelf()];
3183 }
2902 } 3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
2903 3186
2904 m_host.AddScriptLPS(1); 3187 m_host.AddScriptLPS(1);
2905 3188
@@ -2931,19 +3214,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2931 { 3214 {
2932 m_host.AddScriptLPS(1); 3215 m_host.AddScriptLPS(1);
2933 3216
2934 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2935 return;
2936
2937 TaskInventoryItem item; 3217 TaskInventoryItem item;
2938 3218
2939 lock (m_host.TaskInventory) 3219 m_host.TaskInventory.LockItemsForRead(true);
3220
3221 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2940 { 3222 {
2941 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3223 m_host.TaskInventory.LockItemsForRead(false);
2942 return; 3224 return;
2943 else 3225 }
2944 item = m_host.TaskInventory[InventorySelf()]; 3226 else
3227 {
3228 item = m_host.TaskInventory[InventorySelf()];
2945 } 3229 }
2946 3230
3231 m_host.TaskInventory.LockItemsForRead(false);
3232
2947 if (item.PermsGranter != m_host.OwnerID) 3233 if (item.PermsGranter != m_host.OwnerID)
2948 return; 3234 return;
2949 3235
@@ -2953,10 +3239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 3239
2954 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3240 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2955 3241
2956 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3242 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2957 if (attachmentsModule != null)
2958 attachmentsModule.AttachObject(presence.ControllingClient,
2959 grp, (uint)attachment, false);
2960 } 3243 }
2961 } 3244 }
2962 3245
@@ -2969,13 +3252,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2969 3252
2970 TaskInventoryItem item; 3253 TaskInventoryItem item;
2971 3254
2972 lock (m_host.TaskInventory) 3255 m_host.TaskInventory.LockItemsForRead(true);
3256
3257 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2973 { 3258 {
2974 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3259 m_host.TaskInventory.LockItemsForRead(false);
2975 return; 3260 return;
2976 else 3261 }
2977 item = m_host.TaskInventory[InventorySelf()]; 3262 else
3263 {
3264 item = m_host.TaskInventory[InventorySelf()];
2978 } 3265 }
3266 m_host.TaskInventory.LockItemsForRead(false);
3267
2979 3268
2980 if (item.PermsGranter != m_host.OwnerID) 3269 if (item.PermsGranter != m_host.OwnerID)
2981 return; 3270 return;
@@ -3022,6 +3311,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3311
3023 public void llInstantMessage(string user, string message) 3312 public void llInstantMessage(string user, string message)
3024 { 3313 {
3314 UUID result;
3315 if (!UUID.TryParse(user, out result))
3316 {
3317 ShoutError("An invalid key was passed to llInstantMessage");
3318 ScriptSleep(2000);
3319 return;
3320 }
3321
3322
3025 m_host.AddScriptLPS(1); 3323 m_host.AddScriptLPS(1);
3026 3324
3027 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3325 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3036,14 +3334,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 UUID friendTransactionID = UUID.Random(); 3334 UUID friendTransactionID = UUID.Random();
3037 3335
3038 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3336 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3039 3337
3040 GridInstantMessage msg = new GridInstantMessage(); 3338 GridInstantMessage msg = new GridInstantMessage();
3041 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3339 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3042 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3340 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3043 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3341 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3044// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3342// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3045// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3343// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3046 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3344// DateTime dt = DateTime.UtcNow;
3345//
3346// // Ticks from UtcNow, but make it look like local. Evil, huh?
3347// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3348//
3349// try
3350// {
3351// // Convert that to the PST timezone
3352// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3353// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3354// }
3355// catch
3356// {
3357// // No logging here, as it could be VERY spammy
3358// }
3359//
3360// // And make it look local again to fool the unix time util
3361// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3362
3363 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3364
3047 //if (client != null) 3365 //if (client != null)
3048 //{ 3366 //{
3049 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3367 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3057,12 +3375,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 msg.message = message.Substring(0, 1024); 3375 msg.message = message.Substring(0, 1024);
3058 else 3376 else
3059 msg.message = message; 3377 msg.message = message;
3060 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3378 msg.dialog = (byte)19; // MessageFromObject
3061 msg.fromGroup = false;// fromGroup; 3379 msg.fromGroup = false;// fromGroup;
3062 msg.offline = (byte)0; //offline; 3380 msg.offline = (byte)0; //offline;
3063 msg.ParentEstateID = 0; //ParentEstateID; 3381 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3064 msg.Position = new Vector3(m_host.AbsolutePosition); 3382 msg.Position = new Vector3(m_host.AbsolutePosition);
3065 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3383 msg.RegionID = World.RegionInfo.RegionID.Guid;
3066 msg.binaryBucket 3384 msg.binaryBucket
3067 = Util.StringToBytes256( 3385 = Util.StringToBytes256(
3068 "{0}/{1}/{2}/{3}", 3386 "{0}/{1}/{2}/{3}",
@@ -3090,7 +3408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3408 }
3091 3409
3092 emailModule.SendEmail(m_host.UUID, address, subject, message); 3410 emailModule.SendEmail(m_host.UUID, address, subject, message);
3093 ScriptSleep(20000); 3411 ScriptSleep(15000);
3094 } 3412 }
3095 3413
3096 public void llGetNextEmail(string address, string subject) 3414 public void llGetNextEmail(string address, string subject)
@@ -3192,13 +3510,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 m_host.AddScriptLPS(1); 3510 m_host.AddScriptLPS(1);
3193 } 3511 }
3194 3512
3195 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3196 {
3197 m_host.AddScriptLPS(1);
3198 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3199 m_host.RotLookAt(rot, (float)strength, (float)damping);
3200 }
3201
3202 public LSL_Integer llStringLength(string str) 3513 public LSL_Integer llStringLength(string str)
3203 { 3514 {
3204 m_host.AddScriptLPS(1); 3515 m_host.AddScriptLPS(1);
@@ -3222,14 +3533,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3222 3533
3223 TaskInventoryItem item; 3534 TaskInventoryItem item;
3224 3535
3225 lock (m_host.TaskInventory) 3536 m_host.TaskInventory.LockItemsForRead(true);
3537 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 { 3538 {
3227 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3539 m_host.TaskInventory.LockItemsForRead(false);
3228 return; 3540 return;
3229 else
3230 item = m_host.TaskInventory[InventorySelf()];
3231 } 3541 }
3232 3542 else
3543 {
3544 item = m_host.TaskInventory[InventorySelf()];
3545 }
3546 m_host.TaskInventory.LockItemsForRead(false);
3233 if (item.PermsGranter == UUID.Zero) 3547 if (item.PermsGranter == UUID.Zero)
3234 return; 3548 return;
3235 3549
@@ -3259,13 +3573,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3259 3573
3260 TaskInventoryItem item; 3574 TaskInventoryItem item;
3261 3575
3262 lock (m_host.TaskInventory) 3576 m_host.TaskInventory.LockItemsForRead(true);
3577 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3263 { 3578 {
3264 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3579 m_host.TaskInventory.LockItemsForRead(false);
3265 return; 3580 return;
3266 else
3267 item = m_host.TaskInventory[InventorySelf()];
3268 } 3581 }
3582 else
3583 {
3584 item = m_host.TaskInventory[InventorySelf()];
3585 }
3586 m_host.TaskInventory.LockItemsForRead(false);
3587
3269 3588
3270 if (item.PermsGranter == UUID.Zero) 3589 if (item.PermsGranter == UUID.Zero)
3271 return; 3590 return;
@@ -3336,10 +3655,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 3655
3337 TaskInventoryItem item; 3656 TaskInventoryItem item;
3338 3657
3339 lock (m_host.TaskInventory) 3658
3659 m_host.TaskInventory.LockItemsForRead(true);
3660 if (!m_host.TaskInventory.ContainsKey(invItemID))
3661 {
3662 m_host.TaskInventory.LockItemsForRead(false);
3663 return;
3664 }
3665 else
3340 { 3666 {
3341 item = m_host.TaskInventory[invItemID]; 3667 item = m_host.TaskInventory[invItemID];
3342 } 3668 }
3669 m_host.TaskInventory.LockItemsForRead(false);
3343 3670
3344 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3671 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3345 { 3672 {
@@ -3367,15 +3694,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3367 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3694 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3368 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3695 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3369 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3696 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3697 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3370 ScriptBaseClass.PERMISSION_ATTACH; 3698 ScriptBaseClass.PERMISSION_ATTACH;
3371 3699
3372 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3700 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3373 { 3701 {
3374 lock (m_host.TaskInventory) 3702 m_host.TaskInventory.LockItemsForWrite(true);
3375 { 3703 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3376 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3704 m_host.TaskInventory[invItemID].PermsMask = perm;
3377 m_host.TaskInventory[invItemID].PermsMask = perm; 3705 m_host.TaskInventory.LockItemsForWrite(false);
3378 }
3379 3706
3380 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3707 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3381 "run_time_permissions", new Object[] { 3708 "run_time_permissions", new Object[] {
@@ -3395,11 +3722,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3395 3722
3396 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3723 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3397 { 3724 {
3398 lock (m_host.TaskInventory) 3725 m_host.TaskInventory.LockItemsForWrite(true);
3399 { 3726 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3400 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3727 m_host.TaskInventory[invItemID].PermsMask = perm;
3401 m_host.TaskInventory[invItemID].PermsMask = perm; 3728 m_host.TaskInventory.LockItemsForWrite(false);
3402 }
3403 3729
3404 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3730 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3405 "run_time_permissions", new Object[] { 3731 "run_time_permissions", new Object[] {
@@ -3420,11 +3746,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 3746
3421 if (!m_waitingForScriptAnswer) 3747 if (!m_waitingForScriptAnswer)
3422 { 3748 {
3423 lock (m_host.TaskInventory) 3749 m_host.TaskInventory.LockItemsForWrite(true);
3424 { 3750 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3425 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3751 m_host.TaskInventory[invItemID].PermsMask = 0;
3426 m_host.TaskInventory[invItemID].PermsMask = 0; 3752 m_host.TaskInventory.LockItemsForWrite(false);
3427 }
3428 3753
3429 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3754 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3430 m_waitingForScriptAnswer=true; 3755 m_waitingForScriptAnswer=true;
@@ -3459,10 +3784,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3459 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3784 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3460 llReleaseControls(); 3785 llReleaseControls();
3461 3786
3462 lock (m_host.TaskInventory) 3787
3463 { 3788 m_host.TaskInventory.LockItemsForWrite(true);
3464 m_host.TaskInventory[invItemID].PermsMask = answer; 3789 m_host.TaskInventory[invItemID].PermsMask = answer;
3465 } 3790 m_host.TaskInventory.LockItemsForWrite(false);
3791
3466 3792
3467 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3793 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3468 "run_time_permissions", new Object[] { 3794 "run_time_permissions", new Object[] {
@@ -3474,16 +3800,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3474 { 3800 {
3475 m_host.AddScriptLPS(1); 3801 m_host.AddScriptLPS(1);
3476 3802
3477 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForRead(true);
3804
3805 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3478 { 3806 {
3479 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3807 if (item.Type == 10 && item.ItemID == m_itemID)
3480 { 3808 {
3481 if (item.Type == 10 && item.ItemID == m_itemID) 3809 m_host.TaskInventory.LockItemsForRead(false);
3482 { 3810 return item.PermsGranter.ToString();
3483 return item.PermsGranter.ToString();
3484 }
3485 } 3811 }
3486 } 3812 }
3813 m_host.TaskInventory.LockItemsForRead(false);
3487 3814
3488 return UUID.Zero.ToString(); 3815 return UUID.Zero.ToString();
3489 } 3816 }
@@ -3492,19 +3819,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 { 3819 {
3493 m_host.AddScriptLPS(1); 3820 m_host.AddScriptLPS(1);
3494 3821
3495 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForRead(true);
3823
3824 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3496 { 3825 {
3497 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3826 if (item.Type == 10 && item.ItemID == m_itemID)
3498 { 3827 {
3499 if (item.Type == 10 && item.ItemID == m_itemID) 3828 int perms = item.PermsMask;
3500 { 3829 if (m_automaticLinkPermission)
3501 int perms = item.PermsMask; 3830 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3502 if (m_automaticLinkPermission) 3831 m_host.TaskInventory.LockItemsForRead(false);
3503 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3832 return perms;
3504 return perms;
3505 }
3506 } 3833 }
3507 } 3834 }
3835 m_host.TaskInventory.LockItemsForRead(false);
3508 3836
3509 return 0; 3837 return 0;
3510 } 3838 }
@@ -3526,9 +3854,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3854 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3527 { 3855 {
3528 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3856 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3529 3857 if (parts.Count > 0)
3530 foreach (SceneObjectPart part in parts) 3858 {
3531 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3859 try
3860 {
3861 parts[0].ParentGroup.areUpdatesSuspended = true;
3862 foreach (SceneObjectPart part in parts)
3863 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3864 }
3865 finally
3866 {
3867 parts[0].ParentGroup.areUpdatesSuspended = false;
3868 }
3869 }
3532 } 3870 }
3533 3871
3534 public void llCreateLink(string target, int parent) 3872 public void llCreateLink(string target, int parent)
@@ -3541,11 +3879,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3541 return; 3879 return;
3542 3880
3543 TaskInventoryItem item; 3881 TaskInventoryItem item;
3544 lock (m_host.TaskInventory) 3882 m_host.TaskInventory.LockItemsForRead(true);
3545 { 3883 item = m_host.TaskInventory[invItemID];
3546 item = m_host.TaskInventory[invItemID]; 3884 m_host.TaskInventory.LockItemsForRead(false);
3547 } 3885
3548
3549 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3886 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3550 && !m_automaticLinkPermission) 3887 && !m_automaticLinkPermission)
3551 { 3888 {
@@ -3562,11 +3899,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3562 3899
3563 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3900 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0)
3564 return; // Fail silently if attached 3901 return; // Fail silently if attached
3902
3903 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3904 return;
3905
3565 SceneObjectGroup parentPrim = null, childPrim = null; 3906 SceneObjectGroup parentPrim = null, childPrim = null;
3566 3907
3567 if (targetPart != null) 3908 if (targetPart != null)
3568 { 3909 {
3569 if (parent != 0) { 3910 if (parent != 0)
3911 {
3570 parentPrim = m_host.ParentGroup; 3912 parentPrim = m_host.ParentGroup;
3571 childPrim = targetPart.ParentGroup; 3913 childPrim = targetPart.ParentGroup;
3572 } 3914 }
@@ -3598,16 +3940,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3598 m_host.AddScriptLPS(1); 3940 m_host.AddScriptLPS(1);
3599 UUID invItemID = InventorySelf(); 3941 UUID invItemID = InventorySelf();
3600 3942
3601 lock (m_host.TaskInventory) 3943 m_host.TaskInventory.LockItemsForRead(true);
3602 {
3603 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3944 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3604 && !m_automaticLinkPermission) 3945 && !m_automaticLinkPermission)
3605 { 3946 {
3606 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3947 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3948 m_host.TaskInventory.LockItemsForRead(false);
3607 return; 3949 return;
3608 } 3950 }
3609 } 3951 m_host.TaskInventory.LockItemsForRead(false);
3610 3952
3611 if (linknum < ScriptBaseClass.LINK_THIS) 3953 if (linknum < ScriptBaseClass.LINK_THIS)
3612 return; 3954 return;
3613 3955
@@ -3646,10 +3988,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 // Restructuring Multiple Prims. 3988 // Restructuring Multiple Prims.
3647 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3989 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3648 parts.Remove(parentPrim.RootPart); 3990 parts.Remove(parentPrim.RootPart);
3649 foreach (SceneObjectPart part in parts) 3991 if (parts.Count > 0)
3650 { 3992 {
3651 parentPrim.DelinkFromGroup(part.LocalId, true); 3993 try
3994 {
3995 parts[0].ParentGroup.areUpdatesSuspended = true;
3996 foreach (SceneObjectPart part in parts)
3997 {
3998 parentPrim.DelinkFromGroup(part.LocalId, true);
3999 }
4000 }
4001 finally
4002 {
4003 parts[0].ParentGroup.areUpdatesSuspended = false;
4004 }
3652 } 4005 }
4006
3653 parentPrim.HasGroupChanged = true; 4007 parentPrim.HasGroupChanged = true;
3654 parentPrim.ScheduleGroupForFullUpdate(); 4008 parentPrim.ScheduleGroupForFullUpdate();
3655 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4009 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3658,11 +4012,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3658 { 4012 {
3659 SceneObjectPart newRoot = parts[0]; 4013 SceneObjectPart newRoot = parts[0];
3660 parts.Remove(newRoot); 4014 parts.Remove(newRoot);
3661 foreach (SceneObjectPart part in parts) 4015
4016 try
3662 { 4017 {
3663 part.UpdateFlag = 0; 4018 parts[0].ParentGroup.areUpdatesSuspended = true;
3664 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4019 foreach (SceneObjectPart part in parts)
4020 {
4021 part.UpdateFlag = 0;
4022 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4023 }
3665 } 4024 }
4025 finally
4026 {
4027 parts[0].ParentGroup.areUpdatesSuspended = false;
4028 }
4029
4030
3666 newRoot.ParentGroup.HasGroupChanged = true; 4031 newRoot.ParentGroup.HasGroupChanged = true;
3667 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4032 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3668 } 4033 }
@@ -3682,6 +4047,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 public void llBreakAllLinks() 4047 public void llBreakAllLinks()
3683 { 4048 {
3684 m_host.AddScriptLPS(1); 4049 m_host.AddScriptLPS(1);
4050
4051 UUID invItemID = InventorySelf();
4052
4053 TaskInventoryItem item;
4054 m_host.TaskInventory.LockItemsForRead(true);
4055 item = m_host.TaskInventory[invItemID];
4056 m_host.TaskInventory.LockItemsForRead(false);
4057
4058 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4059 && !m_automaticLinkPermission)
4060 {
4061 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4062 return;
4063 }
4064
3685 SceneObjectGroup parentPrim = m_host.ParentGroup; 4065 SceneObjectGroup parentPrim = m_host.ParentGroup;
3686 if (parentPrim.RootPart.AttachmentPoint != 0) 4066 if (parentPrim.RootPart.AttachmentPoint != 0)
3687 return; // Fail silently if attached 4067 return; // Fail silently if attached
@@ -3708,6 +4088,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3708 } 4088 }
3709 else 4089 else
3710 { 4090 {
4091 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4092 {
4093 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4094
4095 if (linknum < 0)
4096 return UUID.Zero.ToString();
4097
4098 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4099 if (avatars.Count > linknum)
4100 {
4101 return avatars[linknum].UUID.ToString();
4102 }
4103 }
3711 return UUID.Zero.ToString(); 4104 return UUID.Zero.ToString();
3712 } 4105 }
3713 } 4106 }
@@ -3784,17 +4177,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3784 m_host.AddScriptLPS(1); 4177 m_host.AddScriptLPS(1);
3785 int count = 0; 4178 int count = 0;
3786 4179
3787 lock (m_host.TaskInventory) 4180 m_host.TaskInventory.LockItemsForRead(true);
4181 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3788 { 4182 {
3789 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4183 if (inv.Value.Type == type || type == -1)
3790 { 4184 {
3791 if (inv.Value.Type == type || type == -1) 4185 count = count + 1;
3792 {
3793 count = count + 1;
3794 }
3795 } 4186 }
3796 } 4187 }
3797 4188
4189 m_host.TaskInventory.LockItemsForRead(false);
3798 return count; 4190 return count;
3799 } 4191 }
3800 4192
@@ -3803,16 +4195,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3803 m_host.AddScriptLPS(1); 4195 m_host.AddScriptLPS(1);
3804 ArrayList keys = new ArrayList(); 4196 ArrayList keys = new ArrayList();
3805 4197
3806 lock (m_host.TaskInventory) 4198 m_host.TaskInventory.LockItemsForRead(true);
4199 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3807 { 4200 {
3808 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4201 if (inv.Value.Type == type || type == -1)
3809 { 4202 {
3810 if (inv.Value.Type == type || type == -1) 4203 keys.Add(inv.Value.Name);
3811 {
3812 keys.Add(inv.Value.Name);
3813 }
3814 } 4204 }
3815 } 4205 }
4206 m_host.TaskInventory.LockItemsForRead(false);
3816 4207
3817 if (keys.Count == 0) 4208 if (keys.Count == 0)
3818 { 4209 {
@@ -3849,30 +4240,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3849 } 4240 }
3850 4241
3851 // move the first object found with this inventory name 4242 // move the first object found with this inventory name
3852 lock (m_host.TaskInventory) 4243 m_host.TaskInventory.LockItemsForRead(true);
4244 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3853 { 4245 {
3854 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4246 if (inv.Value.Name == inventory)
3855 { 4247 {
3856 if (inv.Value.Name == inventory) 4248 found = true;
3857 { 4249 objId = inv.Key;
3858 found = true; 4250 assetType = inv.Value.Type;
3859 objId = inv.Key; 4251 objName = inv.Value.Name;
3860 assetType = inv.Value.Type; 4252 break;
3861 objName = inv.Value.Name;
3862 break;
3863 }
3864 } 4253 }
3865 } 4254 }
4255 m_host.TaskInventory.LockItemsForRead(false);
3866 4256
3867 if (!found) 4257 if (!found)
3868 { 4258 {
3869 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4259 llSay(0, String.Format("Could not find object '{0}'", inventory));
3870 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4260 return;
4261// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3871 } 4262 }
3872 4263
3873 // check if destination is an avatar 4264 // check if destination is an object
3874 if (World.GetScenePresence(destId) != null) 4265 if (World.GetSceneObjectPart(destId) != null)
4266 {
4267 // destination is an object
4268 World.MoveTaskInventoryItem(destId, m_host, objId);
4269 }
4270 else
3875 { 4271 {
4272 ScenePresence presence = World.GetScenePresence(destId);
4273
4274 if (presence == null)
4275 {
4276 UserAccount account =
4277 World.UserAccountService.GetUserAccount(
4278 World.RegionInfo.ScopeID,
4279 destId);
4280
4281 if (account == null)
4282 {
4283 llSay(0, "Can't find destination "+destId.ToString());
4284 return;
4285 }
4286 }
4287
3876 // destination is an avatar 4288 // destination is an avatar
3877 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4289 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3878 4290
@@ -3896,31 +4308,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 4308
3897 if (m_TransferModule != null) 4309 if (m_TransferModule != null)
3898 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4310 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4311
4312 //This delay should only occur when giving inventory to avatars.
4313 ScriptSleep(3000);
3899 } 4314 }
3900 else
3901 {
3902 // destination is an object
3903 World.MoveTaskInventoryItem(destId, m_host, objId);
3904 }
3905 ScriptSleep(3000);
3906 } 4315 }
3907 4316
4317 [DebuggerNonUserCode]
3908 public void llRemoveInventory(string name) 4318 public void llRemoveInventory(string name)
3909 { 4319 {
3910 m_host.AddScriptLPS(1); 4320 m_host.AddScriptLPS(1);
3911 4321
3912 lock (m_host.TaskInventory) 4322 List<TaskInventoryItem> inv;
4323 try
3913 { 4324 {
3914 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4325 m_host.TaskInventory.LockItemsForRead(true);
4326 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4327 }
4328 finally
4329 {
4330 m_host.TaskInventory.LockItemsForRead(false);
4331 }
4332 foreach (TaskInventoryItem item in inv)
4333 {
4334 if (item.Name == name)
3915 { 4335 {
3916 if (item.Name == name) 4336 if (item.ItemID == m_itemID)
3917 { 4337 throw new ScriptDeleteException();
3918 if (item.ItemID == m_itemID) 4338 else
3919 throw new ScriptDeleteException(); 4339 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3920 else 4340 return;
3921 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3922 return;
3923 }
3924 } 4341 }
3925 } 4342 }
3926 } 4343 }
@@ -3955,112 +4372,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 { 4372 {
3956 m_host.AddScriptLPS(1); 4373 m_host.AddScriptLPS(1);
3957 4374
3958 UUID uuid = (UUID)id; 4375 UUID uuid;
3959 PresenceInfo pinfo = null; 4376 if (UUID.TryParse(id, out uuid))
3960 UserAccount account;
3961
3962 UserInfoCacheEntry ce;
3963 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3964 { 4377 {
3965 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4378 PresenceInfo pinfo = null;
3966 if (account == null) 4379 UserAccount account;
4380
4381 UserInfoCacheEntry ce;
4382 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3967 { 4383 {
3968 m_userInfoCache[uuid] = null; // Cache negative 4384 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3969 return UUID.Zero.ToString(); 4385 if (account == null)
3970 } 4386 {
4387 m_userInfoCache[uuid] = null; // Cache negative
4388 return UUID.Zero.ToString();
4389 }
3971 4390
3972 4391
3973 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4392 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3974 if (pinfos != null && pinfos.Length > 0) 4393 if (pinfos != null && pinfos.Length > 0)
3975 {
3976 foreach (PresenceInfo p in pinfos)
3977 { 4394 {
3978 if (p.RegionID != UUID.Zero) 4395 foreach (PresenceInfo p in pinfos)
3979 { 4396 {
3980 pinfo = p; 4397 if (p.RegionID != UUID.Zero)
4398 {
4399 pinfo = p;
4400 }
3981 } 4401 }
3982 } 4402 }
3983 }
3984 4403
3985 ce = new UserInfoCacheEntry(); 4404 ce = new UserInfoCacheEntry();
3986 ce.time = Util.EnvironmentTickCount(); 4405 ce.time = Util.EnvironmentTickCount();
3987 ce.account = account; 4406 ce.account = account;
3988 ce.pinfo = pinfo; 4407 ce.pinfo = pinfo;
3989 } 4408 m_userInfoCache[uuid] = ce;
3990 else 4409 }
3991 { 4410 else
3992 if (ce == null) 4411 {
3993 return UUID.Zero.ToString(); 4412 if (ce == null)
4413 return UUID.Zero.ToString();
3994 4414
3995 account = ce.account; 4415 account = ce.account;
3996 pinfo = ce.pinfo; 4416 pinfo = ce.pinfo;
3997 } 4417 }
3998 4418
3999 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4419 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4000 {
4001 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4002 if (pinfos != null && pinfos.Length > 0)
4003 { 4420 {
4004 foreach (PresenceInfo p in pinfos) 4421 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4422 if (pinfos != null && pinfos.Length > 0)
4005 { 4423 {
4006 if (p.RegionID != UUID.Zero) 4424 foreach (PresenceInfo p in pinfos)
4007 { 4425 {
4008 pinfo = p; 4426 if (p.RegionID != UUID.Zero)
4427 {
4428 pinfo = p;
4429 }
4009 } 4430 }
4010 } 4431 }
4011 } 4432 else
4012 else 4433 pinfo = null;
4013 pinfo = null;
4014 4434
4015 ce.time = Util.EnvironmentTickCount(); 4435 ce.time = Util.EnvironmentTickCount();
4016 ce.pinfo = pinfo; 4436 ce.pinfo = pinfo;
4017 } 4437 }
4018 4438
4019 string reply = String.Empty; 4439 string reply = String.Empty;
4020 4440
4021 switch (data) 4441 switch (data)
4022 { 4442 {
4023 case 1: // DATA_ONLINE (0|1) 4443 case 1: // DATA_ONLINE (0|1)
4024 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4444 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4025 reply = "1"; 4445 reply = "1";
4026 else 4446 else
4027 reply = "0"; 4447 reply = "0";
4028 break; 4448 break;
4029 case 2: // DATA_NAME (First Last) 4449 case 2: // DATA_NAME (First Last)
4030 reply = account.FirstName + " " + account.LastName; 4450 reply = account.FirstName + " " + account.LastName;
4031 break; 4451 break;
4032 case 3: // DATA_BORN (YYYY-MM-DD) 4452 case 3: // DATA_BORN (YYYY-MM-DD)
4033 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4453 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4034 born = born.AddSeconds(account.Created); 4454 born = born.AddSeconds(account.Created);
4035 reply = born.ToString("yyyy-MM-dd"); 4455 reply = born.ToString("yyyy-MM-dd");
4036 break; 4456 break;
4037 case 4: // DATA_RATING (0,0,0,0,0,0) 4457 case 4: // DATA_RATING (0,0,0,0,0,0)
4038 reply = "0,0,0,0,0,0"; 4458 reply = "0,0,0,0,0,0";
4039 break; 4459 break;
4040 case 8: // DATA_PAYINFO (0|1|2|3) 4460 case 8: // DATA_PAYINFO (0|1|2|3)
4041 reply = "0"; 4461 reply = "0";
4042 break; 4462 break;
4043 default: 4463 default:
4044 return UUID.Zero.ToString(); // Raise no event 4464 return UUID.Zero.ToString(); // Raise no event
4045 } 4465 }
4046 4466
4047 UUID rq = UUID.Random(); 4467 UUID rq = UUID.Random();
4048 4468
4049 UUID tid = AsyncCommands. 4469 UUID tid = AsyncCommands.
4050 DataserverPlugin.RegisterRequest(m_localID, 4470 DataserverPlugin.RegisterRequest(m_localID,
4051 m_itemID, rq.ToString()); 4471 m_itemID, rq.ToString());
4052 4472
4053 AsyncCommands. 4473 AsyncCommands.
4054 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4474 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4055 4475
4056 ScriptSleep(100); 4476 ScriptSleep(100);
4057 return tid.ToString(); 4477 return tid.ToString();
4478 }
4479 else
4480 {
4481 ShoutError("Invalid UUID passed to llRequestAgentData.");
4482 }
4483 return "";
4058 } 4484 }
4059 4485
4060 public LSL_String llRequestInventoryData(string name) 4486 public LSL_String llRequestInventoryData(string name)
4061 { 4487 {
4062 m_host.AddScriptLPS(1); 4488 m_host.AddScriptLPS(1);
4063 4489
4490 //Clone is thread safe
4064 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4491 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4065 4492
4066 foreach (TaskInventoryItem item in itemDictionary.Values) 4493 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4114,6 +4541,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4114 ScenePresence presence = World.GetScenePresence(agentId); 4541 ScenePresence presence = World.GetScenePresence(agentId);
4115 if (presence != null) 4542 if (presence != null)
4116 { 4543 {
4544 // agent must not be a god
4545 if (presence.UserLevel >= 200) return;
4546
4117 // agent must be over the owners land 4547 // agent must be over the owners land
4118 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4548 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4119 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4549 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4136,7 +4566,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4136 UUID av = new UUID(); 4566 UUID av = new UUID();
4137 if (!UUID.TryParse(agent,out av)) 4567 if (!UUID.TryParse(agent,out av))
4138 { 4568 {
4139 LSLError("First parameter to llDialog needs to be a key"); 4569 //LSLError("First parameter to llDialog needs to be a key");
4140 return; 4570 return;
4141 } 4571 }
4142 4572
@@ -4173,17 +4603,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 UUID soundId = UUID.Zero; 4603 UUID soundId = UUID.Zero;
4174 if (!UUID.TryParse(impact_sound, out soundId)) 4604 if (!UUID.TryParse(impact_sound, out soundId))
4175 { 4605 {
4176 lock (m_host.TaskInventory) 4606 m_host.TaskInventory.LockItemsForRead(true);
4607 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4177 { 4608 {
4178 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4609 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4179 { 4610 {
4180 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4611 soundId = item.AssetID;
4181 { 4612 break;
4182 soundId = item.AssetID;
4183 break;
4184 }
4185 } 4613 }
4186 } 4614 }
4615 m_host.TaskInventory.LockItemsForRead(false);
4187 } 4616 }
4188 m_host.CollisionSound = soundId; 4617 m_host.CollisionSound = soundId;
4189 m_host.CollisionSoundVolume = (float)impact_volume; 4618 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4229,6 +4658,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 UUID partItemID; 4658 UUID partItemID;
4230 foreach (SceneObjectPart part in parts) 4659 foreach (SceneObjectPart part in parts)
4231 { 4660 {
4661 //Clone is thread safe
4232 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4662 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4233 4663
4234 foreach (TaskInventoryItem item in itemsDictionary.Values) 4664 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4443,17 +4873,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4443 4873
4444 m_host.AddScriptLPS(1); 4874 m_host.AddScriptLPS(1);
4445 4875
4446 lock (m_host.TaskInventory) 4876 m_host.TaskInventory.LockItemsForRead(true);
4877 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4447 { 4878 {
4448 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4879 if (item.Type == 10 && item.ItemID == m_itemID)
4449 { 4880 {
4450 if (item.Type == 10 && item.ItemID == m_itemID) 4881 result = item.Name!=null?item.Name:String.Empty;
4451 { 4882 break;
4452 result = item.Name != null ? item.Name : String.Empty;
4453 break;
4454 }
4455 } 4883 }
4456 } 4884 }
4885 m_host.TaskInventory.LockItemsForRead(false);
4457 4886
4458 return result; 4887 return result;
4459 } 4888 }
@@ -4622,23 +5051,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4622 { 5051 {
4623 m_host.AddScriptLPS(1); 5052 m_host.AddScriptLPS(1);
4624 5053
4625 lock (m_host.TaskInventory) 5054 m_host.TaskInventory.LockItemsForRead(true);
5055 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4626 { 5056 {
4627 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5057 if (inv.Value.Name == name)
4628 { 5058 {
4629 if (inv.Value.Name == name) 5059 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4630 { 5060 {
4631 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5061 m_host.TaskInventory.LockItemsForRead(false);
4632 { 5062 return inv.Value.AssetID.ToString();
4633 return inv.Value.AssetID.ToString(); 5063 }
4634 } 5064 else
4635 else 5065 {
4636 { 5066 m_host.TaskInventory.LockItemsForRead(false);
4637 return UUID.Zero.ToString(); 5067 return UUID.Zero.ToString();
4638 }
4639 } 5068 }
4640 } 5069 }
4641 } 5070 }
5071 m_host.TaskInventory.LockItemsForRead(false);
4642 5072
4643 return UUID.Zero.ToString(); 5073 return UUID.Zero.ToString();
4644 } 5074 }
@@ -4791,14 +5221,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4791 { 5221 {
4792 m_host.AddScriptLPS(1); 5222 m_host.AddScriptLPS(1);
4793 5223
4794 if (src == null) 5224 return src.Length;
4795 {
4796 return 0;
4797 }
4798 else
4799 {
4800 return src.Length;
4801 }
4802 } 5225 }
4803 5226
4804 public LSL_Integer llList2Integer(LSL_List src, int index) 5227 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4844,7 +5267,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4844 else if (src.Data[index] is LSL_Float) 5267 else if (src.Data[index] is LSL_Float)
4845 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5268 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4846 else if (src.Data[index] is LSL_String) 5269 else if (src.Data[index] is LSL_String)
4847 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5270 {
5271 string str = ((LSL_String) src.Data[index]).m_string;
5272 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5273 if (m != Match.Empty)
5274 {
5275 str = m.Value;
5276 double d = 0.0;
5277 if (!Double.TryParse(str, out d))
5278 return 0.0;
5279
5280 return d;
5281 }
5282 return 0.0;
5283 }
4848 return Convert.ToDouble(src.Data[index]); 5284 return Convert.ToDouble(src.Data[index]);
4849 } 5285 }
4850 catch (FormatException) 5286 catch (FormatException)
@@ -5117,7 +5553,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5117 } 5553 }
5118 } 5554 }
5119 } 5555 }
5120 else { 5556 else
5557 {
5121 object[] array = new object[src.Length]; 5558 object[] array = new object[src.Length];
5122 Array.Copy(src.Data, 0, array, 0, src.Length); 5559 Array.Copy(src.Data, 0, array, 0, src.Length);
5123 result = new LSL_List(array); 5560 result = new LSL_List(array);
@@ -5529,7 +5966,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5529 public void llSetSoundQueueing(int queue) 5966 public void llSetSoundQueueing(int queue)
5530 { 5967 {
5531 m_host.AddScriptLPS(1); 5968 m_host.AddScriptLPS(1);
5532 NotImplemented("llSetSoundQueueing");
5533 } 5969 }
5534 5970
5535 public void llSetSoundRadius(double radius) 5971 public void llSetSoundRadius(double radius)
@@ -5574,10 +6010,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5574 m_host.AddScriptLPS(1); 6010 m_host.AddScriptLPS(1);
5575 6011
5576 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6012 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5577 6013 if (parts.Count > 0)
5578 foreach (var part in parts)
5579 { 6014 {
5580 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6015 try
6016 {
6017 parts[0].ParentGroup.areUpdatesSuspended = true;
6018 foreach (var part in parts)
6019 {
6020 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6021 }
6022 }
6023 finally
6024 {
6025 parts[0].ParentGroup.areUpdatesSuspended = false;
6026 }
5581 } 6027 }
5582 } 6028 }
5583 6029
@@ -5631,6 +6077,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5631 ScriptSleep(5000); 6077 ScriptSleep(5000);
5632 } 6078 }
5633 6079
6080 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6081 {
6082 return ParseString2List(str, separators, in_spacers, false);
6083 }
6084
5634 public LSL_Integer llOverMyLand(string id) 6085 public LSL_Integer llOverMyLand(string id)
5635 { 6086 {
5636 m_host.AddScriptLPS(1); 6087 m_host.AddScriptLPS(1);
@@ -5831,7 +6282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5831 return m_host.ParentGroup.RootPart.AttachmentPoint; 6282 return m_host.ParentGroup.RootPart.AttachmentPoint;
5832 } 6283 }
5833 6284
5834 public LSL_Integer llGetFreeMemory() 6285 public virtual LSL_Integer llGetFreeMemory()
5835 { 6286 {
5836 m_host.AddScriptLPS(1); 6287 m_host.AddScriptLPS(1);
5837 // Make scripts designed for LSO happy 6288 // Make scripts designed for LSO happy
@@ -5948,7 +6399,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5948 SetParticleSystem(m_host, rules); 6399 SetParticleSystem(m_host, rules);
5949 } 6400 }
5950 6401
5951 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6402 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6403 {
5952 6404
5953 6405
5954 if (rules.Length == 0) 6406 if (rules.Length == 0)
@@ -6142,14 +6594,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6142 6594
6143 protected UUID GetTaskInventoryItem(string name) 6595 protected UUID GetTaskInventoryItem(string name)
6144 { 6596 {
6145 lock (m_host.TaskInventory) 6597 m_host.TaskInventory.LockItemsForRead(true);
6598 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6146 { 6599 {
6147 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6600 if (inv.Value.Name == name)
6148 { 6601 {
6149 if (inv.Value.Name == name) 6602 m_host.TaskInventory.LockItemsForRead(false);
6150 return inv.Key; 6603 return inv.Key;
6151 } 6604 }
6152 } 6605 }
6606 m_host.TaskInventory.LockItemsForRead(false);
6153 6607
6154 return UUID.Zero; 6608 return UUID.Zero;
6155 } 6609 }
@@ -6399,13 +6853,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6399 UUID av = new UUID(); 6853 UUID av = new UUID();
6400 if (!UUID.TryParse(avatar,out av)) 6854 if (!UUID.TryParse(avatar,out av))
6401 { 6855 {
6402 LSLError("First parameter to llDialog needs to be a key"); 6856 //LSLError("First parameter to llDialog needs to be a key");
6403 return; 6857 return;
6404 } 6858 }
6405 if (buttons.Length < 1) 6859 if (buttons.Length < 1)
6406 { 6860 {
6407 LSLError("No less than 1 button can be shown"); 6861 buttons.Add("OK");
6408 return;
6409 } 6862 }
6410 if (buttons.Length > 12) 6863 if (buttons.Length > 12)
6411 { 6864 {
@@ -6422,7 +6875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6422 } 6875 }
6423 if (buttons.Data[i].ToString().Length > 24) 6876 if (buttons.Data[i].ToString().Length > 24)
6424 { 6877 {
6425 LSLError("button label cannot be longer than 24 characters"); 6878 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6426 return; 6879 return;
6427 } 6880 }
6428 buts[i] = buttons.Data[i].ToString(); 6881 buts[i] = buttons.Data[i].ToString();
@@ -6486,22 +6939,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6486 } 6939 }
6487 6940
6488 // copy the first script found with this inventory name 6941 // copy the first script found with this inventory name
6489 lock (m_host.TaskInventory) 6942 TaskInventoryItem scriptItem = null;
6943 m_host.TaskInventory.LockItemsForRead(true);
6944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6490 { 6945 {
6491 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6946 if (inv.Value.Name == name)
6492 { 6947 {
6493 if (inv.Value.Name == name) 6948 // make sure the object is a script
6949 if (10 == inv.Value.Type)
6494 { 6950 {
6495 // make sure the object is a script 6951 found = true;
6496 if (10 == inv.Value.Type) 6952 srcId = inv.Key;
6497 { 6953 scriptItem = inv.Value;
6498 found = true; 6954 break;
6499 srcId = inv.Key;
6500 break;
6501 }
6502 } 6955 }
6503 } 6956 }
6504 } 6957 }
6958 m_host.TaskInventory.LockItemsForRead(false);
6505 6959
6506 if (!found) 6960 if (!found)
6507 { 6961 {
@@ -6509,8 +6963,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6509 return; 6963 return;
6510 } 6964 }
6511 6965
6512 // the rest of the permission checks are done in RezScript, so check the pin there as well 6966 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6513 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6967 if (dest != null)
6968 {
6969 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6970 {
6971 // the rest of the permission checks are done in RezScript, so check the pin there as well
6972 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6973
6974 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6975 m_host.Inventory.RemoveInventoryItem(srcId);
6976 }
6977 }
6514 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6978 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6515 ScriptSleep(3000); 6979 ScriptSleep(3000);
6516 } 6980 }
@@ -6573,18 +7037,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6573 public LSL_String llMD5String(string src, int nonce) 7037 public LSL_String llMD5String(string src, int nonce)
6574 { 7038 {
6575 m_host.AddScriptLPS(1); 7039 m_host.AddScriptLPS(1);
6576 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7040 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6577 } 7041 }
6578 7042
6579 public LSL_String llSHA1String(string src) 7043 public LSL_String llSHA1String(string src)
6580 { 7044 {
6581 m_host.AddScriptLPS(1); 7045 m_host.AddScriptLPS(1);
6582 return Util.SHA1Hash(src).ToLower(); 7046 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6583 } 7047 }
6584 7048
6585 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7049 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6586 { 7050 {
6587 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7051 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7053 return shapeBlock;
6588 7054
6589 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7055 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6590 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7056 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6660,6 +7126,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6660 7126
6661 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7127 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6662 { 7128 {
7129 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7130 return;
7131
6663 ObjectShapePacket.ObjectDataBlock shapeBlock; 7132 ObjectShapePacket.ObjectDataBlock shapeBlock;
6664 7133
6665 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7134 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6709,6 +7178,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6709 7178
6710 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7179 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6711 { 7180 {
7181 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7182 return;
7183
6712 ObjectShapePacket.ObjectDataBlock shapeBlock; 7184 ObjectShapePacket.ObjectDataBlock shapeBlock;
6713 7185
6714 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7186 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6751,6 +7223,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6751 7223
6752 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 fudge) 7224 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 fudge)
6753 { 7225 {
7226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7227 return;
7228
6754 ObjectShapePacket.ObjectDataBlock shapeBlock; 7229 ObjectShapePacket.ObjectDataBlock shapeBlock;
6755 7230
6756 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7231 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6877,6 +7352,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 7352
6878 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7353 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6879 { 7354 {
7355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7356 return;
7357
6880 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7358 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6881 UUID sculptId; 7359 UUID sculptId;
6882 7360
@@ -6892,13 +7370,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6892 shapeBlock.PathScaleX = 100; 7370 shapeBlock.PathScaleX = 100;
6893 shapeBlock.PathScaleY = 150; 7371 shapeBlock.PathScaleY = 150;
6894 7372
6895 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7373 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6896 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7374 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6897 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7375 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6898 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7376 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6899 { 7377 {
6900 // default 7378 // default
6901 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7379 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6902 } 7380 }
6903 7381
6904 // retain pathcurve 7382 // retain pathcurve
@@ -6917,32 +7395,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6917 ScriptSleep(200); 7395 ScriptSleep(200);
6918 } 7396 }
6919 7397
6920 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7398 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6921 { 7399 {
6922 m_host.AddScriptLPS(1); 7400 m_host.AddScriptLPS(1);
6923 7401
6924 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7402 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7403 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7404 if (parts.Count>0)
7405 {
7406 try
7407 {
7408 parts[0].ParentGroup.areUpdatesSuspended = true;
7409 foreach (SceneObjectPart part in parts)
7410 SetPrimParams(part, rules);
7411 }
7412 finally
7413 {
7414 parts[0].ParentGroup.areUpdatesSuspended = false;
7415 }
7416 }
7417 if (avatars.Count > 0)
7418 {
7419 foreach (ScenePresence avatar in avatars)
7420 SetPrimParams(avatar, rules);
7421 }
7422 }
6925 7423
6926 foreach (SceneObjectPart part in parts) 7424 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6927 SetPrimParams(part, rules); 7425 {
6928 7426 llSetLinkPrimitiveParamsFast(linknumber, rules);
6929 ScriptSleep(200); 7427 ScriptSleep(200);
6930 } 7428 }
6931 7429
6932 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7430 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6933 { 7431 {
6934 m_host.AddScriptLPS(1); 7432 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7433 //We only support PRIM_POSITION and PRIM_ROTATION
6935 7434
6936 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7435 int idx = 0;
6937 7436
6938 foreach (SceneObjectPart part in parts) 7437 while (idx < rules.Length)
6939 SetPrimParams(part, rules); 7438 {
7439 int code = rules.GetLSLIntegerItem(idx++);
7440
7441 int remain = rules.Length - idx;
7442
7443
7444
7445 switch (code)
7446 {
7447 case (int)ScriptBaseClass.PRIM_POSITION:
7448 if (remain < 1)
7449 return;
7450 LSL_Vector v;
7451 v = rules.GetVector3Item(idx++);
7452 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7453 av.SendAvatarDataToAllAgents();
7454
7455 break;
7456
7457 case (int)ScriptBaseClass.PRIM_ROTATION:
7458 if (remain < 1)
7459 return;
7460 LSL_Rotation r;
7461 r = rules.GetQuaternionItem(idx++);
7462 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7463 av.SendAvatarDataToAllAgents();
7464 break;
7465 }
7466 }
6940 } 7467 }
6941 7468
6942 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7469 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6943 { 7470 {
7471 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7472 return;
7473
6944 int idx = 0; 7474 int idx = 0;
6945 7475
7476 bool positionChanged = false;
7477 LSL_Vector currentPosition = GetPartLocalPos(part);
7478
6946 while (idx < rules.Length) 7479 while (idx < rules.Length)
6947 { 7480 {
6948 int code = rules.GetLSLIntegerItem(idx++); 7481 int code = rules.GetLSLIntegerItem(idx++);
@@ -6951,7 +7484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 7484
6952 int face; 7485 int face;
6953 LSL_Vector v; 7486 LSL_Vector v;
6954 7487
6955 switch (code) 7488 switch (code)
6956 { 7489 {
6957 case (int)ScriptBaseClass.PRIM_POSITION: 7490 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6959,7 +7492,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6959 return; 7492 return;
6960 7493
6961 v=rules.GetVector3Item(idx++); 7494 v=rules.GetVector3Item(idx++);
6962 SetPos(part, v); 7495 positionChanged = true;
7496 currentPosition = GetSetPosTarget(part, v, currentPosition);
6963 7497
6964 break; 7498 break;
6965 case (int)ScriptBaseClass.PRIM_SIZE: 7499 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7327,6 +7861,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7327 break; 7861 break;
7328 } 7862 }
7329 } 7863 }
7864
7865 if (positionChanged)
7866 {
7867 if (part.ParentGroup.RootPart == part)
7868 {
7869 SceneObjectGroup parent = part.ParentGroup;
7870 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7871 }
7872 else
7873 {
7874 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7875 SceneObjectGroup parent = part.ParentGroup;
7876 parent.HasGroupChanged = true;
7877 parent.ScheduleGroupForTerseUpdate();
7878 }
7879 }
7330 } 7880 }
7331 7881
7332 public LSL_String llStringToBase64(string str) 7882 public LSL_String llStringToBase64(string str)
@@ -7475,13 +8025,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7475 public LSL_Integer llGetNumberOfPrims() 8025 public LSL_Integer llGetNumberOfPrims()
7476 { 8026 {
7477 m_host.AddScriptLPS(1); 8027 m_host.AddScriptLPS(1);
7478 int avatarCount = 0; 8028 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7479 World.ForEachScenePresence(delegate(ScenePresence presence) 8029
7480 {
7481 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7482 avatarCount++;
7483 });
7484
7485 return m_host.ParentGroup.PrimCount + avatarCount; 8030 return m_host.ParentGroup.PrimCount + avatarCount;
7486 } 8031 }
7487 8032
@@ -7497,55 +8042,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7497 m_host.AddScriptLPS(1); 8042 m_host.AddScriptLPS(1);
7498 UUID objID = UUID.Zero; 8043 UUID objID = UUID.Zero;
7499 LSL_List result = new LSL_List(); 8044 LSL_List result = new LSL_List();
8045
8046 // If the ID is not valid, return null result
7500 if (!UUID.TryParse(obj, out objID)) 8047 if (!UUID.TryParse(obj, out objID))
7501 { 8048 {
7502 result.Add(new LSL_Vector()); 8049 result.Add(new LSL_Vector());
7503 result.Add(new LSL_Vector()); 8050 result.Add(new LSL_Vector());
7504 return result; 8051 return result;
7505 } 8052 }
8053
8054 // Check if this is an attached prim. If so, replace
8055 // the UUID with the avatar UUID and report it's bounding box
8056 SceneObjectPart part = World.GetSceneObjectPart(objID);
8057 if (part != null && part.ParentGroup.IsAttachment)
8058 objID = part.ParentGroup.RootPart.AttachedAvatar;
8059
8060 // Find out if this is an avatar ID. If so, return it's box
7506 ScenePresence presence = World.GetScenePresence(objID); 8061 ScenePresence presence = World.GetScenePresence(objID);
7507 if (presence != null) 8062 if (presence != null)
7508 { 8063 {
7509 if (presence.ParentID == 0) // not sat on an object 8064 // As per LSL Wiki, there is no difference between sitting
8065 // and standing avatar since server 1.36
8066 LSL_Vector lower;
8067 LSL_Vector upper;
8068 if (presence.Animator.Animations.DefaultAnimation.AnimID
8069 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7510 { 8070 {
7511 LSL_Vector lower; 8071 // This is for ground sitting avatars
7512 LSL_Vector upper; 8072 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7513 if (presence.Animator.Animations.DefaultAnimation.AnimID 8073 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7514 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8074 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7515 {
7516 // This is for ground sitting avatars
7517 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7518 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7519 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7520 }
7521 else
7522 {
7523 // This is for standing/flying avatars
7524 float height = presence.Appearance.AvatarHeight / 2.0f;
7525 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7526 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7527 }
7528 result.Add(lower);
7529 result.Add(upper);
7530 return result;
7531 } 8075 }
7532 else 8076 else
7533 { 8077 {
7534 // sitting on an object so we need the bounding box of that 8078 // This is for standing/flying avatars
7535 // which should include the avatar so set the UUID to the 8079 float height = presence.Appearance.AvatarHeight / 2.0f;
7536 // UUID of the object the avatar is sat on and allow it to fall through 8080 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7537 // to processing an object 8081 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7538 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7539 objID = p.UUID;
7540 } 8082 }
8083
8084 // Adjust to the documented error offsets (see LSL Wiki)
8085 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8086 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8087
8088 if (lower.x > upper.x)
8089 lower.x = upper.x;
8090 if (lower.y > upper.y)
8091 lower.y = upper.y;
8092 if (lower.z > upper.z)
8093 lower.z = upper.z;
8094
8095 result.Add(lower);
8096 result.Add(upper);
8097 return result;
7541 } 8098 }
7542 SceneObjectPart part = World.GetSceneObjectPart(objID); 8099
8100 part = World.GetSceneObjectPart(objID);
7543 // Currently only works for single prims without a sitting avatar 8101 // Currently only works for single prims without a sitting avatar
7544 if (part != null) 8102 if (part != null)
7545 { 8103 {
7546 Vector3 halfSize = part.Scale / 2.0f; 8104 float minX;
7547 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8105 float maxX;
7548 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8106 float minY;
8107 float maxY;
8108 float minZ;
8109 float maxZ;
8110
8111 // This BBox is in sim coordinates, with the offset being
8112 // a contained point.
8113 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8114 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8115
8116 minX -= offsets[0].X;
8117 maxX -= offsets[0].X;
8118 minY -= offsets[0].Y;
8119 maxY -= offsets[0].Y;
8120 minZ -= offsets[0].Z;
8121 maxZ -= offsets[0].Z;
8122
8123 LSL_Vector lower;
8124 LSL_Vector upper;
8125
8126 // Adjust to the documented error offsets (see LSL Wiki)
8127 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8128 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8129
8130 if (lower.x > upper.x)
8131 lower.x = upper.x;
8132 if (lower.y > upper.y)
8133 lower.y = upper.y;
8134 if (lower.z > upper.z)
8135 lower.z = upper.z;
8136
7549 result.Add(lower); 8137 result.Add(lower);
7550 result.Add(upper); 8138 result.Add(upper);
7551 return result; 8139 return result;
@@ -7625,13 +8213,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7625 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8213 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7626 part.AbsolutePosition.Y, 8214 part.AbsolutePosition.Y,
7627 part.AbsolutePosition.Z); 8215 part.AbsolutePosition.Z);
7628 // For some reason, the part.AbsolutePosition.* values do not change if the
7629 // linkset is rotated; they always reflect the child prim's world position
7630 // as though the linkset is unrotated. This is incompatible behavior with SL's
7631 // implementation, so will break scripts imported from there (not to mention it
7632 // makes it more difficult to determine a child prim's actual inworld position).
7633 if (part.ParentID != 0)
7634 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7635 res.Add(v); 8216 res.Add(v);
7636 break; 8217 break;
7637 8218
@@ -7792,56 +8373,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7792 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8373 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7793 if (remain < 1) 8374 if (remain < 1)
7794 return res; 8375 return res;
7795 8376 face = (int)rules.GetLSLIntegerItem(idx++);
7796 face=(int)rules.GetLSLIntegerItem(idx++);
7797 8377
7798 tex = part.Shape.Textures; 8378 tex = part.Shape.Textures;
8379 int shiny;
7799 if (face == ScriptBaseClass.ALL_SIDES) 8380 if (face == ScriptBaseClass.ALL_SIDES)
7800 { 8381 {
7801 for (face = 0; face < GetNumberOfSides(part); face++) 8382 for (face = 0; face < GetNumberOfSides(part); face++)
7802 { 8383 {
7803 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8384 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7804 // Convert Shininess to PRIM_SHINY_* 8385 if (shinyness == Shininess.High)
7805 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8386 {
7806 // PRIM_BUMP_* 8387 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7807 res.Add(new LSL_Integer((int)texface.Bump)); 8388 }
8389 else if (shinyness == Shininess.Medium)
8390 {
8391 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8392 }
8393 else if (shinyness == Shininess.Low)
8394 {
8395 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8396 }
8397 else
8398 {
8399 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8400 }
8401 res.Add(new LSL_Integer(shiny));
8402 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7808 } 8403 }
7809 } 8404 }
7810 else 8405 else
7811 { 8406 {
7812 if (face >= 0 && face < GetNumberOfSides(part)) 8407 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8408 if (shinyness == Shininess.High)
7813 { 8409 {
7814 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8410 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7815 // Convert Shininess to PRIM_SHINY_* 8411 }
7816 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8412 else if (shinyness == Shininess.Medium)
7817 // PRIM_BUMP_* 8413 {
7818 res.Add(new LSL_Integer((int)texface.Bump)); 8414 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8415 }
8416 else if (shinyness == Shininess.Low)
8417 {
8418 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8419 }
8420 else
8421 {
8422 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7819 } 8423 }
8424 res.Add(new LSL_Integer(shiny));
8425 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7820 } 8426 }
7821 break; 8427 break;
7822 8428
7823 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8429 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7824 if (remain < 1) 8430 if (remain < 1)
7825 return res; 8431 return res;
7826 8432 face = (int)rules.GetLSLIntegerItem(idx++);
7827 face=(int)rules.GetLSLIntegerItem(idx++);
7828 8433
7829 tex = part.Shape.Textures; 8434 tex = part.Shape.Textures;
8435 int fullbright;
7830 if (face == ScriptBaseClass.ALL_SIDES) 8436 if (face == ScriptBaseClass.ALL_SIDES)
7831 { 8437 {
7832 for (face = 0; face < GetNumberOfSides(part); face++) 8438 for (face = 0; face < GetNumberOfSides(part); face++)
7833 { 8439 {
7834 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8440 if (tex.GetFace((uint)face).Fullbright == true)
7835 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8441 {
8442 fullbright = ScriptBaseClass.TRUE;
8443 }
8444 else
8445 {
8446 fullbright = ScriptBaseClass.FALSE;
8447 }
8448 res.Add(new LSL_Integer(fullbright));
7836 } 8449 }
7837 } 8450 }
7838 else 8451 else
7839 { 8452 {
7840 if (face >= 0 && face < GetNumberOfSides(part)) 8453 if (tex.GetFace((uint)face).Fullbright == true)
7841 { 8454 {
7842 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8455 fullbright = ScriptBaseClass.TRUE;
7843 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8456 }
8457 else
8458 {
8459 fullbright = ScriptBaseClass.FALSE;
7844 } 8460 }
8461 res.Add(new LSL_Integer(fullbright));
7845 } 8462 }
7846 break; 8463 break;
7847 8464
@@ -7863,27 +8480,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7863 break; 8480 break;
7864 8481
7865 case (int)ScriptBaseClass.PRIM_TEXGEN: 8482 case (int)ScriptBaseClass.PRIM_TEXGEN:
8483 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7866 if (remain < 1) 8484 if (remain < 1)
7867 return res; 8485 return res;
7868 8486 face = (int)rules.GetLSLIntegerItem(idx++);
7869 face=(int)rules.GetLSLIntegerItem(idx++);
7870 8487
7871 tex = part.Shape.Textures; 8488 tex = part.Shape.Textures;
7872 if (face == ScriptBaseClass.ALL_SIDES) 8489 if (face == ScriptBaseClass.ALL_SIDES)
7873 { 8490 {
7874 for (face = 0; face < GetNumberOfSides(part); face++) 8491 for (face = 0; face < GetNumberOfSides(part); face++)
7875 { 8492 {
7876 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8493 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7877 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8494 {
7878 res.Add(new LSL_Integer((uint)texgen >> 1)); 8495 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8496 }
8497 else
8498 {
8499 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8500 }
7879 } 8501 }
7880 } 8502 }
7881 else 8503 else
7882 { 8504 {
7883 if (face >= 0 && face < GetNumberOfSides(part)) 8505 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8506 {
8507 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8508 }
8509 else
7884 { 8510 {
7885 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8511 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7886 res.Add(new LSL_Integer((uint)texgen >> 1));
7887 } 8512 }
7888 } 8513 }
7889 break; 8514 break;
@@ -7906,28 +8531,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7906 case (int)ScriptBaseClass.PRIM_GLOW: 8531 case (int)ScriptBaseClass.PRIM_GLOW:
7907 if (remain < 1) 8532 if (remain < 1)
7908 return res; 8533 return res;
7909 8534 face = (int)rules.GetLSLIntegerItem(idx++);
7910 face=(int)rules.GetLSLIntegerItem(idx++);
7911 8535
7912 tex = part.Shape.Textures; 8536 tex = part.Shape.Textures;
8537 float primglow;
7913 if (face == ScriptBaseClass.ALL_SIDES) 8538 if (face == ScriptBaseClass.ALL_SIDES)
7914 { 8539 {
7915 for (face = 0; face < GetNumberOfSides(part); face++) 8540 for (face = 0; face < GetNumberOfSides(part); face++)
7916 { 8541 {
7917 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8542 primglow = tex.GetFace((uint)face).Glow;
7918 res.Add(new LSL_Float(texface.Glow)); 8543 res.Add(new LSL_Float(primglow));
7919 } 8544 }
7920 } 8545 }
7921 else 8546 else
7922 { 8547 {
7923 if (face >= 0 && face < GetNumberOfSides(part)) 8548 primglow = tex.GetFace((uint)face).Glow;
7924 { 8549 res.Add(new LSL_Float(primglow));
7925 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7926 res.Add(new LSL_Float(texface.Glow));
7927 }
7928 } 8550 }
7929 break; 8551 break;
7930
7931 case (int)ScriptBaseClass.PRIM_TEXT: 8552 case (int)ScriptBaseClass.PRIM_TEXT:
7932 Color4 textColor = part.GetTextColor(); 8553 Color4 textColor = part.GetTextColor();
7933 res.Add(part.Text); 8554 res.Add(part.Text);
@@ -8476,8 +9097,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8476 // The function returns an ordered list 9097 // The function returns an ordered list
8477 // representing the tokens found in the supplied 9098 // representing the tokens found in the supplied
8478 // sources string. If two successive tokenizers 9099 // sources string. If two successive tokenizers
8479 // are encountered, then a NULL entry is added 9100 // are encountered, then a null-string entry is
8480 // to the list. 9101 // added to the list.
8481 // 9102 //
8482 // It is a precondition that the source and 9103 // It is a precondition that the source and
8483 // toekizer lisst are non-null. If they are null, 9104 // toekizer lisst are non-null. If they are null,
@@ -8485,7 +9106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8485 // while their lengths are being determined. 9106 // while their lengths are being determined.
8486 // 9107 //
8487 // A small amount of working memoryis required 9108 // A small amount of working memoryis required
8488 // of approximately 8*#tokenizers. 9109 // of approximately 8*#tokenizers + 8*srcstrlen.
8489 // 9110 //
8490 // There are many ways in which this function 9111 // There are many ways in which this function
8491 // can be implemented, this implementation is 9112 // can be implemented, this implementation is
@@ -8501,155 +9122,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8501 // and eliminates redundant tokenizers as soon 9122 // and eliminates redundant tokenizers as soon
8502 // as is possible. 9123 // as is possible.
8503 // 9124 //
8504 // The implementation tries to avoid any copying 9125 // The implementation tries to minimize temporary
8505 // of arrays or other objects. 9126 // garbage generation.
8506 // </remarks> 9127 // </remarks>
8507 9128
8508 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9129 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8509 { 9130 {
8510 int beginning = 0; 9131 return ParseString2List(src, separators, spacers, true);
8511 int srclen = src.Length; 9132 }
8512 int seplen = separators.Length;
8513 object[] separray = separators.Data;
8514 int spclen = spacers.Length;
8515 object[] spcarray = spacers.Data;
8516 int mlen = seplen+spclen;
8517
8518 int[] offset = new int[mlen+1];
8519 bool[] active = new bool[mlen];
8520
8521 int best;
8522 int j;
8523
8524 // Initial capacity reduces resize cost
8525 9133
8526 LSL_List tokens = new LSL_List(); 9134 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9135 {
9136 int srclen = src.Length;
9137 int seplen = separators.Length;
9138 object[] separray = separators.Data;
9139 int spclen = spacers.Length;
9140 object[] spcarray = spacers.Data;
9141 int dellen = 0;
9142 string[] delarray = new string[seplen+spclen];
8527 9143
8528 // All entries are initially valid 9144 int outlen = 0;
9145 string[] outarray = new string[srclen*2+1];
8529 9146
8530 for (int i = 0; i < mlen; i++) 9147 int i, j;
8531 active[i] = true; 9148 string d;
8532 9149
8533 offset[mlen] = srclen; 9150 m_host.AddScriptLPS(1);
8534 9151
8535 while (beginning < srclen) 9152 /*
9153 * Convert separator and spacer lists to C# strings.
9154 * Also filter out null strings so we don't hang.
9155 */
9156 for (i = 0; i < seplen; i ++)
8536 { 9157 {
9158 d = separray[i].ToString();
9159 if (d.Length > 0)
9160 {
9161 delarray[dellen++] = d;
9162 }
9163 }
9164 seplen = dellen;
8537 9165
8538 best = mlen; // as bad as it gets 9166 for (i = 0; i < spclen; i ++)
9167 {
9168 d = spcarray[i].ToString();
9169 if (d.Length > 0)
9170 {
9171 delarray[dellen++] = d;
9172 }
9173 }
8539 9174
8540 // Scan for separators 9175 /*
9176 * Scan through source string from beginning to end.
9177 */
9178 for (i = 0;;)
9179 {
8541 9180
8542 for (j = 0; j < seplen; j++) 9181 /*
9182 * Find earliest delimeter in src starting at i (if any).
9183 */
9184 int earliestDel = -1;
9185 int earliestSrc = srclen;
9186 string earliestStr = null;
9187 for (j = 0; j < dellen; j ++)
8543 { 9188 {
8544 if (separray[j].ToString() == String.Empty) 9189 d = delarray[j];
8545 active[j] = false; 9190 if (d != null)
8546
8547 if (active[j])
8548 { 9191 {
8549 // scan all of the markers 9192 int index = src.IndexOf(d, i);
8550 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9193 if (index < 0)
8551 { 9194 {
8552 // not present at all 9195 delarray[j] = null; // delim nowhere in src, don't check it anymore
8553 active[j] = false;
8554 } 9196 }
8555 else 9197 else if (index < earliestSrc)
8556 { 9198 {
8557 // present and correct 9199 earliestSrc = index; // where delimeter starts in source string
8558 if (offset[j] < offset[best]) 9200 earliestDel = j; // where delimeter is in delarray[]
8559 { 9201 earliestStr = d; // the delimeter string from delarray[]
8560 // closest so far 9202 if (index == i) break; // can't do any better than found at beg of string
8561 best = j;
8562 if (offset[best] == beginning)
8563 break;
8564 }
8565 } 9203 }
8566 } 9204 }
8567 } 9205 }
8568 9206
8569 // Scan for spacers 9207 /*
8570 9208 * Output source string starting at i through start of earliest delimeter.
8571 if (offset[best] != beginning) 9209 */
9210 if (keepNulls || (earliestSrc > i))
8572 { 9211 {
8573 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9212 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8574 {
8575 if (spcarray[j-seplen].ToString() == String.Empty)
8576 active[j] = false;
8577
8578 if (active[j])
8579 {
8580 // scan all of the markers
8581 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8582 {
8583 // not present at all
8584 active[j] = false;
8585 }
8586 else
8587 {
8588 // present and correct
8589 if (offset[j] < offset[best])
8590 {
8591 // closest so far
8592 best = j;
8593 }
8594 }
8595 }
8596 }
8597 } 9213 }
8598 9214
8599 // This is the normal exit from the scanning loop 9215 /*
9216 * If no delimeter found at or after i, we're done scanning.
9217 */
9218 if (earliestDel < 0) break;
8600 9219
8601 if (best == mlen) 9220 /*
9221 * If delimeter was a spacer, output the spacer.
9222 */
9223 if (earliestDel >= seplen)
8602 { 9224 {
8603 // no markers were found on this pass 9225 outarray[outlen++] = earliestStr;
8604 // so we're pretty much done
8605 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8606 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8607 break;
8608 } 9226 }
8609 9227
8610 // Otherwise we just add the newly delimited token 9228 /*
8611 // and recalculate where the search should continue. 9229 * Look at rest of src string following delimeter.
8612 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9230 */
8613 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9231 i = earliestSrc + earliestStr.Length;
8614
8615 if (best < seplen)
8616 {
8617 beginning = offset[best] + (separray[best].ToString()).Length;
8618 }
8619 else
8620 {
8621 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8622 string str = spcarray[best - seplen].ToString();
8623 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8624 tokens.Add(new LSL_String(str));
8625 }
8626 } 9232 }
8627 9233
8628 // This an awkward an not very intuitive boundary case. If the 9234 /*
8629 // last substring is a tokenizer, then there is an implied trailing 9235 * Make up an exact-sized output array suitable for an LSL_List object.
8630 // null list entry. Hopefully the single comparison will not be too 9236 */
8631 // arduous. Alternatively the 'break' could be replced with a return 9237 object[] outlist = new object[outlen];
8632 // but that's shabby programming. 9238 for (i = 0; i < outlen; i ++)
8633
8634 if ((beginning == srclen) && (keepNulls))
8635 { 9239 {
8636 if (srclen != 0) 9240 outlist[i] = new LSL_String(outarray[i]);
8637 tokens.Add(new LSL_String(""));
8638 } 9241 }
8639 9242 return new LSL_List(outlist);
8640 return tokens;
8641 }
8642
8643 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8644 {
8645 m_host.AddScriptLPS(1);
8646 return this.ParseString(src, separators, spacers, false);
8647 }
8648
8649 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8650 {
8651 m_host.AddScriptLPS(1);
8652 return this.ParseString(src, separators, spacers, true);
8653 } 9243 }
8654 9244
8655 public LSL_Integer llGetObjectPermMask(int mask) 9245 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8726,28 +9316,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8726 { 9316 {
8727 m_host.AddScriptLPS(1); 9317 m_host.AddScriptLPS(1);
8728 9318
8729 lock (m_host.TaskInventory) 9319 m_host.TaskInventory.LockItemsForRead(true);
9320 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8730 { 9321 {
8731 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9322 if (inv.Value.Name == item)
8732 { 9323 {
8733 if (inv.Value.Name == item) 9324 m_host.TaskInventory.LockItemsForRead(false);
9325 switch (mask)
8734 { 9326 {
8735 switch (mask) 9327 case 0:
8736 { 9328 return (int)inv.Value.BasePermissions;
8737 case 0: 9329 case 1:
8738 return (int)inv.Value.BasePermissions; 9330 return (int)inv.Value.CurrentPermissions;
8739 case 1: 9331 case 2:
8740 return (int)inv.Value.CurrentPermissions; 9332 return (int)inv.Value.GroupPermissions;
8741 case 2: 9333 case 3:
8742 return (int)inv.Value.GroupPermissions; 9334 return (int)inv.Value.EveryonePermissions;
8743 case 3: 9335 case 4:
8744 return (int)inv.Value.EveryonePermissions; 9336 return (int)inv.Value.NextPermissions;
8745 case 4:
8746 return (int)inv.Value.NextPermissions;
8747 }
8748 } 9337 }
8749 } 9338 }
8750 } 9339 }
9340 m_host.TaskInventory.LockItemsForRead(false);
8751 9341
8752 return -1; 9342 return -1;
8753 } 9343 }
@@ -8794,16 +9384,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8794 { 9384 {
8795 m_host.AddScriptLPS(1); 9385 m_host.AddScriptLPS(1);
8796 9386
8797 lock (m_host.TaskInventory) 9387 m_host.TaskInventory.LockItemsForRead(true);
9388 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8798 { 9389 {
8799 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9390 if (inv.Value.Name == item)
8800 { 9391 {
8801 if (inv.Value.Name == item) 9392 m_host.TaskInventory.LockItemsForRead(false);
8802 { 9393 return inv.Value.CreatorID.ToString();
8803 return inv.Value.CreatorID.ToString();
8804 }
8805 } 9394 }
8806 } 9395 }
9396 m_host.TaskInventory.LockItemsForRead(false);
8807 9397
8808 llSay(0, "No item name '" + item + "'"); 9398 llSay(0, "No item name '" + item + "'");
8809 9399
@@ -8951,7 +9541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8951 } 9541 }
8952 9542
8953 /// <summary> 9543 /// <summary>
8954 /// illListReplaceList removes the sub-list defined by the inclusive indices 9544 /// llListReplaceList removes the sub-list defined by the inclusive indices
8955 /// start and end and inserts the src list in its place. The inclusive 9545 /// start and end and inserts the src list in its place. The inclusive
8956 /// nature of the indices means that at least one element must be deleted 9546 /// nature of the indices means that at least one element must be deleted
8957 /// if the indices are within the bounds of the existing list. I.e. 2,2 9547 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9008,16 +9598,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9008 // based upon end. Note that if end exceeds the upper 9598 // based upon end. Note that if end exceeds the upper
9009 // bound in this case, the entire destination list 9599 // bound in this case, the entire destination list
9010 // is removed. 9600 // is removed.
9011 else 9601 else if (start == 0)
9012 { 9602 {
9013 if (end + 1 < dest.Length) 9603 if (end + 1 < dest.Length)
9014 {
9015 return src + dest.GetSublist(end + 1, -1); 9604 return src + dest.GetSublist(end + 1, -1);
9016 }
9017 else 9605 else
9018 {
9019 return src; 9606 return src;
9020 } 9607 }
9608 else // Start < 0
9609 {
9610 if (end + 1 < dest.Length)
9611 return dest.GetSublist(end + 1, -1);
9612 else
9613 return new LSL_List();
9021 } 9614 }
9022 } 9615 }
9023 // Finally, if start > end, we strip away a prefix and 9616 // Finally, if start > end, we strip away a prefix and
@@ -9068,17 +9661,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9068 int width = 0; 9661 int width = 0;
9069 int height = 0; 9662 int height = 0;
9070 9663
9071 ParcelMediaCommandEnum? commandToSend = null; 9664 uint commandToSend = 0;
9072 float time = 0.0f; // default is from start 9665 float time = 0.0f; // default is from start
9073 9666
9074 ScenePresence presence = null; 9667 ScenePresence presence = null;
9075 9668
9076 for (int i = 0; i < commandList.Data.Length; i++) 9669 for (int i = 0; i < commandList.Data.Length; i++)
9077 { 9670 {
9078 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9671 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9079 switch (command) 9672 switch (command)
9080 { 9673 {
9081 case ParcelMediaCommandEnum.Agent: 9674 case (uint)ParcelMediaCommandEnum.Agent:
9082 // we send only to one agent 9675 // we send only to one agent
9083 if ((i + 1) < commandList.Length) 9676 if ((i + 1) < commandList.Length)
9084 { 9677 {
@@ -9095,25 +9688,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9095 } 9688 }
9096 break; 9689 break;
9097 9690
9098 case ParcelMediaCommandEnum.Loop: 9691 case (uint)ParcelMediaCommandEnum.Loop:
9099 loop = 1; 9692 loop = 1;
9100 commandToSend = command; 9693 commandToSend = command;
9101 update = true; //need to send the media update packet to set looping 9694 update = true; //need to send the media update packet to set looping
9102 break; 9695 break;
9103 9696
9104 case ParcelMediaCommandEnum.Play: 9697 case (uint)ParcelMediaCommandEnum.Play:
9105 loop = 0; 9698 loop = 0;
9106 commandToSend = command; 9699 commandToSend = command;
9107 update = true; //need to send the media update packet to make sure it doesn't loop 9700 update = true; //need to send the media update packet to make sure it doesn't loop
9108 break; 9701 break;
9109 9702
9110 case ParcelMediaCommandEnum.Pause: 9703 case (uint)ParcelMediaCommandEnum.Pause:
9111 case ParcelMediaCommandEnum.Stop: 9704 case (uint)ParcelMediaCommandEnum.Stop:
9112 case ParcelMediaCommandEnum.Unload: 9705 case (uint)ParcelMediaCommandEnum.Unload:
9113 commandToSend = command; 9706 commandToSend = command;
9114 break; 9707 break;
9115 9708
9116 case ParcelMediaCommandEnum.Url: 9709 case (uint)ParcelMediaCommandEnum.Url:
9117 if ((i + 1) < commandList.Length) 9710 if ((i + 1) < commandList.Length)
9118 { 9711 {
9119 if (commandList.Data[i + 1] is LSL_String) 9712 if (commandList.Data[i + 1] is LSL_String)
@@ -9126,7 +9719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9126 } 9719 }
9127 break; 9720 break;
9128 9721
9129 case ParcelMediaCommandEnum.Texture: 9722 case (uint)ParcelMediaCommandEnum.Texture:
9130 if ((i + 1) < commandList.Length) 9723 if ((i + 1) < commandList.Length)
9131 { 9724 {
9132 if (commandList.Data[i + 1] is LSL_String) 9725 if (commandList.Data[i + 1] is LSL_String)
@@ -9139,7 +9732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9139 } 9732 }
9140 break; 9733 break;
9141 9734
9142 case ParcelMediaCommandEnum.Time: 9735 case (uint)ParcelMediaCommandEnum.Time:
9143 if ((i + 1) < commandList.Length) 9736 if ((i + 1) < commandList.Length)
9144 { 9737 {
9145 if (commandList.Data[i + 1] is LSL_Float) 9738 if (commandList.Data[i + 1] is LSL_Float)
@@ -9151,7 +9744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9151 } 9744 }
9152 break; 9745 break;
9153 9746
9154 case ParcelMediaCommandEnum.AutoAlign: 9747 case (uint)ParcelMediaCommandEnum.AutoAlign:
9155 if ((i + 1) < commandList.Length) 9748 if ((i + 1) < commandList.Length)
9156 { 9749 {
9157 if (commandList.Data[i + 1] is LSL_Integer) 9750 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9165,7 +9758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9165 } 9758 }
9166 break; 9759 break;
9167 9760
9168 case ParcelMediaCommandEnum.Type: 9761 case (uint)ParcelMediaCommandEnum.Type:
9169 if ((i + 1) < commandList.Length) 9762 if ((i + 1) < commandList.Length)
9170 { 9763 {
9171 if (commandList.Data[i + 1] is LSL_String) 9764 if (commandList.Data[i + 1] is LSL_String)
@@ -9178,7 +9771,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9178 } 9771 }
9179 break; 9772 break;
9180 9773
9181 case ParcelMediaCommandEnum.Desc: 9774 case (uint)ParcelMediaCommandEnum.Desc:
9182 if ((i + 1) < commandList.Length) 9775 if ((i + 1) < commandList.Length)
9183 { 9776 {
9184 if (commandList.Data[i + 1] is LSL_String) 9777 if (commandList.Data[i + 1] is LSL_String)
@@ -9191,7 +9784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9191 } 9784 }
9192 break; 9785 break;
9193 9786
9194 case ParcelMediaCommandEnum.Size: 9787 case (uint)ParcelMediaCommandEnum.Size:
9195 if ((i + 2) < commandList.Length) 9788 if ((i + 2) < commandList.Length)
9196 { 9789 {
9197 if (commandList.Data[i + 1] is LSL_Integer) 9790 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9261,7 +9854,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 } 9854 }
9262 } 9855 }
9263 9856
9264 if (commandToSend != null) 9857 if (commandToSend != 0)
9265 { 9858 {
9266 // the commandList contained a start/stop/... command, too 9859 // the commandList contained a start/stop/... command, too
9267 if (presence == null) 9860 if (presence == null)
@@ -9298,7 +9891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9298 9891
9299 if (aList.Data[i] != null) 9892 if (aList.Data[i] != null)
9300 { 9893 {
9301 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9894 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9302 { 9895 {
9303 case ParcelMediaCommandEnum.Url: 9896 case ParcelMediaCommandEnum.Url:
9304 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9897 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9341,16 +9934,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9341 { 9934 {
9342 m_host.AddScriptLPS(1); 9935 m_host.AddScriptLPS(1);
9343 9936
9344 lock (m_host.TaskInventory) 9937 m_host.TaskInventory.LockItemsForRead(true);
9938 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9345 { 9939 {
9346 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9940 if (inv.Value.Name == name)
9347 { 9941 {
9348 if (inv.Value.Name == name) 9942 m_host.TaskInventory.LockItemsForRead(false);
9349 { 9943 return inv.Value.Type;
9350 return inv.Value.Type;
9351 }
9352 } 9944 }
9353 } 9945 }
9946 m_host.TaskInventory.LockItemsForRead(false);
9354 9947
9355 return -1; 9948 return -1;
9356 } 9949 }
@@ -9361,15 +9954,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9361 9954
9362 if (quick_pay_buttons.Data.Length < 4) 9955 if (quick_pay_buttons.Data.Length < 4)
9363 { 9956 {
9364 LSLError("List must have at least 4 elements"); 9957 int x;
9365 return; 9958 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9959 {
9960 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9961 }
9366 } 9962 }
9367 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9963 int[] nPrice = new int[5];
9368 9964 nPrice[0] = price;
9369 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9965 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9370 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9966 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9371 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9967 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9372 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9968 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9969 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9373 m_host.ParentGroup.HasGroupChanged = true; 9970 m_host.ParentGroup.HasGroupChanged = true;
9374 } 9971 }
9375 9972
@@ -9381,17 +9978,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9381 if (invItemID == UUID.Zero) 9978 if (invItemID == UUID.Zero)
9382 return new LSL_Vector(); 9979 return new LSL_Vector();
9383 9980
9384 lock (m_host.TaskInventory) 9981 m_host.TaskInventory.LockItemsForRead(true);
9982 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9385 { 9983 {
9386 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9984 m_host.TaskInventory.LockItemsForRead(false);
9387 return new LSL_Vector(); 9985 return new LSL_Vector();
9986 }
9388 9987
9389 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9988 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9390 { 9989 {
9391 ShoutError("No permissions to track the camera"); 9990 ShoutError("No permissions to track the camera");
9392 return new LSL_Vector(); 9991 m_host.TaskInventory.LockItemsForRead(false);
9393 } 9992 return new LSL_Vector();
9394 } 9993 }
9994 m_host.TaskInventory.LockItemsForRead(false);
9395 9995
9396 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9996 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9397 if (presence != null) 9997 if (presence != null)
@@ -9409,17 +10009,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9409 if (invItemID == UUID.Zero) 10009 if (invItemID == UUID.Zero)
9410 return new LSL_Rotation(); 10010 return new LSL_Rotation();
9411 10011
9412 lock (m_host.TaskInventory) 10012 m_host.TaskInventory.LockItemsForRead(true);
10013 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9413 { 10014 {
9414 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10015 m_host.TaskInventory.LockItemsForRead(false);
9415 return new LSL_Rotation(); 10016 return new LSL_Rotation();
9416 10017 }
9417 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10018 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9418 { 10019 {
9419 ShoutError("No permissions to track the camera"); 10020 ShoutError("No permissions to track the camera");
9420 return new LSL_Rotation(); 10021 m_host.TaskInventory.LockItemsForRead(false);
9421 } 10022 return new LSL_Rotation();
9422 } 10023 }
10024 m_host.TaskInventory.LockItemsForRead(false);
9423 10025
9424 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10026 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9425 if (presence != null) 10027 if (presence != null)
@@ -9481,8 +10083,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9481 { 10083 {
9482 m_host.AddScriptLPS(1); 10084 m_host.AddScriptLPS(1);
9483 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10085 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9484 if (detectedParams == null) return; // only works on the first detected avatar 10086 if (detectedParams == null)
9485 10087 {
10088 if (m_host.IsAttachment == true)
10089 {
10090 detectedParams = new DetectParams();
10091 detectedParams.Key = m_host.OwnerID;
10092 }
10093 else
10094 {
10095 return;
10096 }
10097 }
10098
9486 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10099 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9487 if (avatar != null) 10100 if (avatar != null)
9488 { 10101 {
@@ -9490,6 +10103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9490 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10103 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9491 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10104 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9492 } 10105 }
10106
9493 ScriptSleep(1000); 10107 ScriptSleep(1000);
9494 } 10108 }
9495 10109
@@ -9582,14 +10196,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 if (objectID == UUID.Zero) return; 10196 if (objectID == UUID.Zero) return;
9583 10197
9584 UUID agentID; 10198 UUID agentID;
9585 lock (m_host.TaskInventory) 10199 m_host.TaskInventory.LockItemsForRead(true);
9586 { 10200 // we need the permission first, to know which avatar we want to set the camera for
9587 // we need the permission first, to know which avatar we want to set the camera for 10201 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9588 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9589 10202
9590 if (agentID == UUID.Zero) return; 10203 if (agentID == UUID.Zero)
9591 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10204 {
10205 m_host.TaskInventory.LockItemsForRead(false);
10206 return;
10207 }
10208 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10209 {
10210 m_host.TaskInventory.LockItemsForRead(false);
10211 return;
9592 } 10212 }
10213 m_host.TaskInventory.LockItemsForRead(false);
9593 10214
9594 ScenePresence presence = World.GetScenePresence(agentID); 10215 ScenePresence presence = World.GetScenePresence(agentID);
9595 10216
@@ -9598,12 +10219,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9598 10219
9599 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10220 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9600 object[] data = rules.Data; 10221 object[] data = rules.Data;
9601 for (int i = 0; i < data.Length; ++i) { 10222 for (int i = 0; i < data.Length; ++i)
10223 {
9602 int type = Convert.ToInt32(data[i++].ToString()); 10224 int type = Convert.ToInt32(data[i++].ToString());
9603 if (i >= data.Length) break; // odd number of entries => ignore the last 10225 if (i >= data.Length) break; // odd number of entries => ignore the last
9604 10226
9605 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10227 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9606 switch (type) { 10228 switch (type)
10229 {
9607 case ScriptBaseClass.CAMERA_FOCUS: 10230 case ScriptBaseClass.CAMERA_FOCUS:
9608 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10231 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9609 case ScriptBaseClass.CAMERA_POSITION: 10232 case ScriptBaseClass.CAMERA_POSITION:
@@ -9639,12 +10262,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9639 10262
9640 // we need the permission first, to know which avatar we want to clear the camera for 10263 // we need the permission first, to know which avatar we want to clear the camera for
9641 UUID agentID; 10264 UUID agentID;
9642 lock (m_host.TaskInventory) 10265 m_host.TaskInventory.LockItemsForRead(true);
10266 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10267 if (agentID == UUID.Zero)
10268 {
10269 m_host.TaskInventory.LockItemsForRead(false);
10270 return;
10271 }
10272 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9643 { 10273 {
9644 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10274 m_host.TaskInventory.LockItemsForRead(false);
9645 if (agentID == UUID.Zero) return; 10275 return;
9646 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9647 } 10276 }
10277 m_host.TaskInventory.LockItemsForRead(false);
9648 10278
9649 ScenePresence presence = World.GetScenePresence(agentID); 10279 ScenePresence presence = World.GetScenePresence(agentID);
9650 10280
@@ -9711,19 +10341,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9711 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10341 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9712 { 10342 {
9713 m_host.AddScriptLPS(1); 10343 m_host.AddScriptLPS(1);
9714 string ret = String.Empty; 10344
9715 string src1 = llBase64ToString(str1); 10345 if (str1 == String.Empty)
9716 string src2 = llBase64ToString(str2); 10346 return String.Empty;
9717 int c = 0; 10347 if (str2 == String.Empty)
9718 for (int i = 0; i < src1.Length; i++) 10348 return str1;
10349
10350 int len = str2.Length;
10351 if ((len % 4) != 0) // LL is EVIL!!!!
10352 {
10353 while (str2.EndsWith("="))
10354 str2 = str2.Substring(0, str2.Length - 1);
10355
10356 len = str2.Length;
10357 int mod = len % 4;
10358
10359 if (mod == 1)
10360 str2 = str2.Substring(0, str2.Length - 1);
10361 else if (mod == 2)
10362 str2 += "==";
10363 else if (mod == 3)
10364 str2 += "=";
10365 }
10366
10367 byte[] data1;
10368 byte[] data2;
10369 try
10370 {
10371 data1 = Convert.FromBase64String(str1);
10372 data2 = Convert.FromBase64String(str2);
10373 }
10374 catch (Exception)
9719 { 10375 {
9720 ret += (char) (src1[i] ^ src2[c]); 10376 return new LSL_String(String.Empty);
10377 }
9721 10378
9722 c++; 10379 byte[] d2 = new Byte[data1.Length];
9723 if (c >= src2.Length) 10380 int pos = 0;
9724 c = 0; 10381
10382 if (data1.Length <= data2.Length)
10383 {
10384 Array.Copy(data2, 0, d2, 0, data1.Length);
9725 } 10385 }
9726 return llStringToBase64(ret); 10386 else
10387 {
10388 while (pos < data1.Length)
10389 {
10390 len = data1.Length - pos;
10391 if (len > data2.Length)
10392 len = data2.Length;
10393
10394 Array.Copy(data2, 0, d2, pos, len);
10395 pos += len;
10396 }
10397 }
10398
10399 for (pos = 0 ; pos < data1.Length ; pos++ )
10400 data1[pos] ^= d2[pos];
10401
10402 return Convert.ToBase64String(data1);
9727 } 10403 }
9728 10404
9729 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10405 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9782,12 +10458,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 Regex r = new Regex(authregex); 10458 Regex r = new Regex(authregex);
9783 int[] gnums = r.GetGroupNumbers(); 10459 int[] gnums = r.GetGroupNumbers();
9784 Match m = r.Match(url); 10460 Match m = r.Match(url);
9785 if (m.Success) { 10461 if (m.Success)
9786 for (int i = 1; i < gnums.Length; i++) { 10462 {
10463 for (int i = 1; i < gnums.Length; i++)
10464 {
9787 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10465 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9788 //CaptureCollection cc = g.Captures; 10466 //CaptureCollection cc = g.Captures;
9789 } 10467 }
9790 if (m.Groups.Count == 5) { 10468 if (m.Groups.Count == 5)
10469 {
9791 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10470 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9792 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10471 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9793 } 10472 }
@@ -9899,7 +10578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9899 { 10578 {
9900 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10579 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9901 { 10580 {
9902 ret.Add(detectedParams.Key.ToString()); 10581 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9903 ret.Add(detectedParams.Value); 10582 ret.Add(detectedParams.Value);
9904 } 10583 }
9905 } 10584 }
@@ -10068,15 +10747,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10068 10747
10069 internal UUID ScriptByName(string name) 10748 internal UUID ScriptByName(string name)
10070 { 10749 {
10071 lock (m_host.TaskInventory) 10750 m_host.TaskInventory.LockItemsForRead(true);
10751
10752 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10072 { 10753 {
10073 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10754 if (item.Type == 10 && item.Name == name)
10074 { 10755 {
10075 if (item.Type == 10 && item.Name == name) 10756 m_host.TaskInventory.LockItemsForRead(false);
10076 return item.ItemID; 10757 return item.ItemID;
10077 } 10758 }
10078 } 10759 }
10079 10760
10761 m_host.TaskInventory.LockItemsForRead(false);
10762
10080 return UUID.Zero; 10763 return UUID.Zero;
10081 } 10764 }
10082 10765
@@ -10117,6 +10800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10117 { 10800 {
10118 m_host.AddScriptLPS(1); 10801 m_host.AddScriptLPS(1);
10119 10802
10803 //Clone is thread safe
10120 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10804 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10121 10805
10122 UUID assetID = UUID.Zero; 10806 UUID assetID = UUID.Zero;
@@ -10179,6 +10863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10179 { 10863 {
10180 m_host.AddScriptLPS(1); 10864 m_host.AddScriptLPS(1);
10181 10865
10866 //Clone is thread safe
10182 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10867 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10183 10868
10184 UUID assetID = UUID.Zero; 10869 UUID assetID = UUID.Zero;
@@ -10259,15 +10944,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10259 return GetLinkPrimitiveParams(obj, rules); 10944 return GetLinkPrimitiveParams(obj, rules);
10260 } 10945 }
10261 10946
10262 public void print(string str) 10947 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10263 { 10948 {
10264 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10949 List<SceneObjectPart> parts = GetLinkParts(link);
10265 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10950 if (parts.Count < 1)
10266 if (ossl != null) 10951 return 0;
10267 { 10952
10268 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10953 return GetNumberOfSides(parts[0]);
10269 m_log.Info("LSL print():" + str);
10270 }
10271 } 10954 }
10272 10955
10273 private string Name2Username(string name) 10956 private string Name2Username(string name)
@@ -10312,6 +10995,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10312 10995
10313 return rq.ToString(); 10996 return rq.ToString();
10314 } 10997 }
10998
10999 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11000 {
11001 m_SayShoutCount = 0;
11002 }
10315 } 11003 }
10316 11004
10317 public class NotecardCache 11005 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 64931d0..39e1a27 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -831,18 +840,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
831 if (target != null) 840 if (target != null)
832 { 841 {
833 UUID animID=UUID.Zero; 842 UUID animID=UUID.Zero;
834 lock (m_host.TaskInventory) 843 m_host.TaskInventory.LockItemsForRead(true);
844 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
835 { 845 {
836 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 846 if (inv.Value.Name == animation)
837 { 847 {
838 if (inv.Value.Name == animation) 848 if (inv.Value.Type == (int)AssetType.Animation)
839 { 849 animID = inv.Value.AssetID;
840 if (inv.Value.Type == (int)AssetType.Animation) 850 continue;
841 animID = inv.Value.AssetID;
842 continue;
843 }
844 } 851 }
845 } 852 }
853 m_host.TaskInventory.LockItemsForRead(false);
846 if (animID == UUID.Zero) 854 if (animID == UUID.Zero)
847 target.Animator.AddAnimation(animation, m_host.UUID); 855 target.Animator.AddAnimation(animation, m_host.UUID);
848 else 856 else
@@ -864,18 +872,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
864 if (target != null) 872 if (target != null)
865 { 873 {
866 UUID animID=UUID.Zero; 874 UUID animID=UUID.Zero;
867 lock (m_host.TaskInventory) 875 m_host.TaskInventory.LockItemsForRead(true);
876 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
868 { 877 {
869 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 878 if (inv.Value.Name == animation)
870 { 879 {
871 if (inv.Value.Name == animation) 880 if (inv.Value.Type == (int)AssetType.Animation)
872 { 881 animID = inv.Value.AssetID;
873 if (inv.Value.Type == (int)AssetType.Animation) 882 continue;
874 animID = inv.Value.AssetID;
875 continue;
876 }
877 } 883 }
878 } 884 }
885 m_host.TaskInventory.LockItemsForRead(false);
879 886
880 if (animID == UUID.Zero) 887 if (animID == UUID.Zero)
881 target.Animator.RemoveAnimation(animation); 888 target.Animator.RemoveAnimation(animation);
@@ -1768,6 +1775,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1768 1775
1769 if (!UUID.TryParse(name, out assetID)) 1776 if (!UUID.TryParse(name, out assetID))
1770 { 1777 {
1778 m_host.TaskInventory.LockItemsForRead(true);
1771 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1779 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1772 { 1780 {
1773 if (item.Type == 7 && item.Name == name) 1781 if (item.Type == 7 && item.Name == name)
@@ -1775,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1775 assetID = item.AssetID; 1783 assetID = item.AssetID;
1776 } 1784 }
1777 } 1785 }
1786 m_host.TaskInventory.LockItemsForRead(false);
1778 } 1787 }
1779 1788
1780 if (assetID == UUID.Zero) 1789 if (assetID == UUID.Zero)
@@ -1821,6 +1830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 1830
1822 if (!UUID.TryParse(name, out assetID)) 1831 if (!UUID.TryParse(name, out assetID))
1823 { 1832 {
1833 m_host.TaskInventory.LockItemsForRead(true);
1824 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1834 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1825 { 1835 {
1826 if (item.Type == 7 && item.Name == name) 1836 if (item.Type == 7 && item.Name == name)
@@ -1828,6 +1838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 assetID = item.AssetID; 1838 assetID = item.AssetID;
1829 } 1839 }
1830 } 1840 }
1841 m_host.TaskInventory.LockItemsForRead(false);
1831 } 1842 }
1832 1843
1833 if (assetID == UUID.Zero) 1844 if (assetID == UUID.Zero)
@@ -1878,6 +1889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1878 1889
1879 if (!UUID.TryParse(name, out assetID)) 1890 if (!UUID.TryParse(name, out assetID))
1880 { 1891 {
1892 m_host.TaskInventory.LockItemsForRead(true);
1881 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1893 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1882 { 1894 {
1883 if (item.Type == 7 && item.Name == name) 1895 if (item.Type == 7 && item.Name == name)
@@ -1885,6 +1897,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 assetID = item.AssetID; 1897 assetID = item.AssetID;
1886 } 1898 }
1887 } 1899 }
1900 m_host.TaskInventory.LockItemsForRead(false);
1888 } 1901 }
1889 1902
1890 if (assetID == UUID.Zero) 1903 if (assetID == UUID.Zero)
@@ -2364,9 +2377,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2364 { 2377 {
2365 if (avatar.IsChildAgent == false) 2378 if (avatar.IsChildAgent == false)
2366 { 2379 {
2367 result.Add(avatar.UUID); 2380 result.Add(new LSL_Key(avatar.UUID.ToString()));
2368 result.Add(avatar.AbsolutePosition); 2381 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2369 result.Add(avatar.Name); 2382 result.Add(new LSL_String(avatar.Name));
2370 } 2383 }
2371 } 2384 }
2372 }); 2385 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 47c7915..3afedc7 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,7 +302,8 @@ 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.RootPart.IsAttachment) 307 if (SensePoint.ParentGroup.RootPart.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
@@ -310,6 +311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
310 // in mouselook. 311 // in mouselook.
311 312
312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 313 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
314 fromRegionPos = avatar.AbsolutePosition;
313 q = avatar.Rotation; 315 q = avatar.Rotation;
314 } 316 }
315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 317 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -423,6 +425,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
423 SceneObjectPart SensePoint = ts.host; 425 SceneObjectPart SensePoint = ts.host;
424 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 426 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
425 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment)
429 {
430 // In attachments, the sensor cone always orients with the
431 // avatar rotation. This may include a nonzero elevation if
432 // in mouselook.
433
434 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
435 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation;
437 }
426 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
427 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
428 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
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 }