aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-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
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
15 files changed, 1792 insertions, 792 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 0240227..48a7953 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 }
@@ -4606,23 +5035,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4606 { 5035 {
4607 m_host.AddScriptLPS(1); 5036 m_host.AddScriptLPS(1);
4608 5037
4609 lock (m_host.TaskInventory) 5038 m_host.TaskInventory.LockItemsForRead(true);
5039 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4610 { 5040 {
4611 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5041 if (inv.Value.Name == name)
4612 { 5042 {
4613 if (inv.Value.Name == name) 5043 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4614 { 5044 {
4615 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5045 m_host.TaskInventory.LockItemsForRead(false);
4616 { 5046 return inv.Value.AssetID.ToString();
4617 return inv.Value.AssetID.ToString(); 5047 }
4618 } 5048 else
4619 else 5049 {
4620 { 5050 m_host.TaskInventory.LockItemsForRead(false);
4621 return UUID.Zero.ToString(); 5051 return UUID.Zero.ToString();
4622 }
4623 } 5052 }
4624 } 5053 }
4625 } 5054 }
5055 m_host.TaskInventory.LockItemsForRead(false);
4626 5056
4627 return UUID.Zero.ToString(); 5057 return UUID.Zero.ToString();
4628 } 5058 }
@@ -4775,14 +5205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4775 { 5205 {
4776 m_host.AddScriptLPS(1); 5206 m_host.AddScriptLPS(1);
4777 5207
4778 if (src == null) 5208 return src.Length;
4779 {
4780 return 0;
4781 }
4782 else
4783 {
4784 return src.Length;
4785 }
4786 } 5209 }
4787 5210
4788 public LSL_Integer llList2Integer(LSL_List src, int index) 5211 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4828,7 +5251,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4828 else if (src.Data[index] is LSL_Float) 5251 else if (src.Data[index] is LSL_Float)
4829 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5252 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4830 else if (src.Data[index] is LSL_String) 5253 else if (src.Data[index] is LSL_String)
4831 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5254 {
5255 string str = ((LSL_String) src.Data[index]).m_string;
5256 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5257 if (m != Match.Empty)
5258 {
5259 str = m.Value;
5260 double d = 0.0;
5261 if (!Double.TryParse(str, out d))
5262 return 0.0;
5263
5264 return d;
5265 }
5266 return 0.0;
5267 }
4832 return Convert.ToDouble(src.Data[index]); 5268 return Convert.ToDouble(src.Data[index]);
4833 } 5269 }
4834 catch (FormatException) 5270 catch (FormatException)
@@ -5101,7 +5537,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5101 } 5537 }
5102 } 5538 }
5103 } 5539 }
5104 else { 5540 else
5541 {
5105 object[] array = new object[src.Length]; 5542 object[] array = new object[src.Length];
5106 Array.Copy(src.Data, 0, array, 0, src.Length); 5543 Array.Copy(src.Data, 0, array, 0, src.Length);
5107 result = new LSL_List(array); 5544 result = new LSL_List(array);
@@ -5513,7 +5950,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5513 public void llSetSoundQueueing(int queue) 5950 public void llSetSoundQueueing(int queue)
5514 { 5951 {
5515 m_host.AddScriptLPS(1); 5952 m_host.AddScriptLPS(1);
5516 NotImplemented("llSetSoundQueueing");
5517 } 5953 }
5518 5954
5519 public void llSetSoundRadius(double radius) 5955 public void llSetSoundRadius(double radius)
@@ -5558,10 +5994,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5558 m_host.AddScriptLPS(1); 5994 m_host.AddScriptLPS(1);
5559 5995
5560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5996 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5561 5997 if (parts.Count > 0)
5562 foreach (var part in parts)
5563 { 5998 {
5564 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5999 try
6000 {
6001 parts[0].ParentGroup.areUpdatesSuspended = true;
6002 foreach (var part in parts)
6003 {
6004 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6005 }
6006 }
6007 finally
6008 {
6009 parts[0].ParentGroup.areUpdatesSuspended = false;
6010 }
5565 } 6011 }
5566 } 6012 }
5567 6013
@@ -5615,6 +6061,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5615 ScriptSleep(5000); 6061 ScriptSleep(5000);
5616 } 6062 }
5617 6063
6064 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6065 {
6066 return ParseString2List(str, separators, in_spacers, false);
6067 }
6068
5618 public LSL_Integer llOverMyLand(string id) 6069 public LSL_Integer llOverMyLand(string id)
5619 { 6070 {
5620 m_host.AddScriptLPS(1); 6071 m_host.AddScriptLPS(1);
@@ -5815,7 +6266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5815 return m_host.ParentGroup.RootPart.AttachmentPoint; 6266 return m_host.ParentGroup.RootPart.AttachmentPoint;
5816 } 6267 }
5817 6268
5818 public LSL_Integer llGetFreeMemory() 6269 public virtual LSL_Integer llGetFreeMemory()
5819 { 6270 {
5820 m_host.AddScriptLPS(1); 6271 m_host.AddScriptLPS(1);
5821 // Make scripts designed for LSO happy 6272 // Make scripts designed for LSO happy
@@ -5932,7 +6383,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5932 SetParticleSystem(m_host, rules); 6383 SetParticleSystem(m_host, rules);
5933 } 6384 }
5934 6385
5935 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6386 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6387 {
5936 6388
5937 6389
5938 if (rules.Length == 0) 6390 if (rules.Length == 0)
@@ -6126,14 +6578,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6126 6578
6127 protected UUID GetTaskInventoryItem(string name) 6579 protected UUID GetTaskInventoryItem(string name)
6128 { 6580 {
6129 lock (m_host.TaskInventory) 6581 m_host.TaskInventory.LockItemsForRead(true);
6582 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6130 { 6583 {
6131 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6584 if (inv.Value.Name == name)
6132 { 6585 {
6133 if (inv.Value.Name == name) 6586 m_host.TaskInventory.LockItemsForRead(false);
6134 return inv.Key; 6587 return inv.Key;
6135 } 6588 }
6136 } 6589 }
6590 m_host.TaskInventory.LockItemsForRead(false);
6137 6591
6138 return UUID.Zero; 6592 return UUID.Zero;
6139 } 6593 }
@@ -6383,13 +6837,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6383 UUID av = new UUID(); 6837 UUID av = new UUID();
6384 if (!UUID.TryParse(avatar,out av)) 6838 if (!UUID.TryParse(avatar,out av))
6385 { 6839 {
6386 LSLError("First parameter to llDialog needs to be a key"); 6840 //LSLError("First parameter to llDialog needs to be a key");
6387 return; 6841 return;
6388 } 6842 }
6389 if (buttons.Length < 1) 6843 if (buttons.Length < 1)
6390 { 6844 {
6391 LSLError("No less than 1 button can be shown"); 6845 buttons.Add("OK");
6392 return;
6393 } 6846 }
6394 if (buttons.Length > 12) 6847 if (buttons.Length > 12)
6395 { 6848 {
@@ -6406,7 +6859,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6406 } 6859 }
6407 if (buttons.Data[i].ToString().Length > 24) 6860 if (buttons.Data[i].ToString().Length > 24)
6408 { 6861 {
6409 LSLError("button label cannot be longer than 24 characters"); 6862 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6410 return; 6863 return;
6411 } 6864 }
6412 buts[i] = buttons.Data[i].ToString(); 6865 buts[i] = buttons.Data[i].ToString();
@@ -6470,22 +6923,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6470 } 6923 }
6471 6924
6472 // copy the first script found with this inventory name 6925 // copy the first script found with this inventory name
6473 lock (m_host.TaskInventory) 6926 TaskInventoryItem scriptItem = null;
6927 m_host.TaskInventory.LockItemsForRead(true);
6928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6474 { 6929 {
6475 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6930 if (inv.Value.Name == name)
6476 { 6931 {
6477 if (inv.Value.Name == name) 6932 // make sure the object is a script
6933 if (10 == inv.Value.Type)
6478 { 6934 {
6479 // make sure the object is a script 6935 found = true;
6480 if (10 == inv.Value.Type) 6936 srcId = inv.Key;
6481 { 6937 scriptItem = inv.Value;
6482 found = true; 6938 break;
6483 srcId = inv.Key;
6484 break;
6485 }
6486 } 6939 }
6487 } 6940 }
6488 } 6941 }
6942 m_host.TaskInventory.LockItemsForRead(false);
6489 6943
6490 if (!found) 6944 if (!found)
6491 { 6945 {
@@ -6493,8 +6947,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6493 return; 6947 return;
6494 } 6948 }
6495 6949
6496 // the rest of the permission checks are done in RezScript, so check the pin there as well 6950 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6497 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6951 if (dest != null)
6952 {
6953 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6954 {
6955 // the rest of the permission checks are done in RezScript, so check the pin there as well
6956 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6957
6958 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6959 m_host.Inventory.RemoveInventoryItem(srcId);
6960 }
6961 }
6498 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6962 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6499 ScriptSleep(3000); 6963 ScriptSleep(3000);
6500 } 6964 }
@@ -6557,18 +7021,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6557 public LSL_String llMD5String(string src, int nonce) 7021 public LSL_String llMD5String(string src, int nonce)
6558 { 7022 {
6559 m_host.AddScriptLPS(1); 7023 m_host.AddScriptLPS(1);
6560 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7024 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6561 } 7025 }
6562 7026
6563 public LSL_String llSHA1String(string src) 7027 public LSL_String llSHA1String(string src)
6564 { 7028 {
6565 m_host.AddScriptLPS(1); 7029 m_host.AddScriptLPS(1);
6566 return Util.SHA1Hash(src).ToLower(); 7030 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6567 } 7031 }
6568 7032
6569 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7033 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6570 { 7034 {
6571 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7035 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7037 return shapeBlock;
6572 7038
6573 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7039 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6574 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7040 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6644,6 +7110,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6644 7110
6645 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7111 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6646 { 7112 {
7113 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7114 return;
7115
6647 ObjectShapePacket.ObjectDataBlock shapeBlock; 7116 ObjectShapePacket.ObjectDataBlock shapeBlock;
6648 7117
6649 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7118 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6693,6 +7162,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6693 7162
6694 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7163 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6695 { 7164 {
7165 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7166 return;
7167
6696 ObjectShapePacket.ObjectDataBlock shapeBlock; 7168 ObjectShapePacket.ObjectDataBlock shapeBlock;
6697 7169
6698 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7170 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6735,6 +7207,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6735 7207
6736 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) 7208 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)
6737 { 7209 {
7210 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7211 return;
7212
6738 ObjectShapePacket.ObjectDataBlock shapeBlock; 7213 ObjectShapePacket.ObjectDataBlock shapeBlock;
6739 7214
6740 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7215 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6861,6 +7336,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 7336
6862 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7337 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6863 { 7338 {
7339 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7340 return;
7341
6864 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7342 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6865 UUID sculptId; 7343 UUID sculptId;
6866 7344
@@ -6876,13 +7354,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6876 shapeBlock.PathScaleX = 100; 7354 shapeBlock.PathScaleX = 100;
6877 shapeBlock.PathScaleY = 150; 7355 shapeBlock.PathScaleY = 150;
6878 7356
6879 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7357 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6880 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7358 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6881 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7359 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6882 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7360 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6883 { 7361 {
6884 // default 7362 // default
6885 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7363 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6886 } 7364 }
6887 7365
6888 // retain pathcurve 7366 // retain pathcurve
@@ -6901,32 +7379,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6901 ScriptSleep(200); 7379 ScriptSleep(200);
6902 } 7380 }
6903 7381
6904 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7382 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6905 { 7383 {
6906 m_host.AddScriptLPS(1); 7384 m_host.AddScriptLPS(1);
6907 7385
6908 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7386 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7387 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7388 if (parts.Count>0)
7389 {
7390 try
7391 {
7392 parts[0].ParentGroup.areUpdatesSuspended = true;
7393 foreach (SceneObjectPart part in parts)
7394 SetPrimParams(part, rules);
7395 }
7396 finally
7397 {
7398 parts[0].ParentGroup.areUpdatesSuspended = false;
7399 }
7400 }
7401 if (avatars.Count > 0)
7402 {
7403 foreach (ScenePresence avatar in avatars)
7404 SetPrimParams(avatar, rules);
7405 }
7406 }
6909 7407
6910 foreach (SceneObjectPart part in parts) 7408 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6911 SetPrimParams(part, rules); 7409 {
6912 7410 llSetLinkPrimitiveParamsFast(linknumber, rules);
6913 ScriptSleep(200); 7411 ScriptSleep(200);
6914 } 7412 }
6915 7413
6916 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7414 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6917 { 7415 {
6918 m_host.AddScriptLPS(1); 7416 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7417 //We only support PRIM_POSITION and PRIM_ROTATION
6919 7418
6920 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7419 int idx = 0;
6921 7420
6922 foreach (SceneObjectPart part in parts) 7421 while (idx < rules.Length)
6923 SetPrimParams(part, rules); 7422 {
7423 int code = rules.GetLSLIntegerItem(idx++);
7424
7425 int remain = rules.Length - idx;
7426
7427
7428
7429 switch (code)
7430 {
7431 case (int)ScriptBaseClass.PRIM_POSITION:
7432 if (remain < 1)
7433 return;
7434 LSL_Vector v;
7435 v = rules.GetVector3Item(idx++);
7436 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7437 av.SendAvatarDataToAllAgents();
7438
7439 break;
7440
7441 case (int)ScriptBaseClass.PRIM_ROTATION:
7442 if (remain < 1)
7443 return;
7444 LSL_Rotation r;
7445 r = rules.GetQuaternionItem(idx++);
7446 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7447 av.SendAvatarDataToAllAgents();
7448 break;
7449 }
7450 }
6924 } 7451 }
6925 7452
6926 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7453 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6927 { 7454 {
7455 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7456 return;
7457
6928 int idx = 0; 7458 int idx = 0;
6929 7459
7460 bool positionChanged = false;
7461 LSL_Vector currentPosition = GetPartLocalPos(part);
7462
6930 while (idx < rules.Length) 7463 while (idx < rules.Length)
6931 { 7464 {
6932 int code = rules.GetLSLIntegerItem(idx++); 7465 int code = rules.GetLSLIntegerItem(idx++);
@@ -6935,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6935 7468
6936 int face; 7469 int face;
6937 LSL_Vector v; 7470 LSL_Vector v;
6938 7471
6939 switch (code) 7472 switch (code)
6940 { 7473 {
6941 case (int)ScriptBaseClass.PRIM_POSITION: 7474 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6943,7 +7476,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 return; 7476 return;
6944 7477
6945 v=rules.GetVector3Item(idx++); 7478 v=rules.GetVector3Item(idx++);
6946 SetPos(part, v); 7479 positionChanged = true;
7480 currentPosition = GetSetPosTarget(part, v, currentPosition);
6947 7481
6948 break; 7482 break;
6949 case (int)ScriptBaseClass.PRIM_SIZE: 7483 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7311,6 +7845,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7311 break; 7845 break;
7312 } 7846 }
7313 } 7847 }
7848
7849 if (positionChanged)
7850 {
7851 if (part.ParentGroup.RootPart == part)
7852 {
7853 SceneObjectGroup parent = part.ParentGroup;
7854 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7855 }
7856 else
7857 {
7858 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7859 SceneObjectGroup parent = part.ParentGroup;
7860 parent.HasGroupChanged = true;
7861 parent.ScheduleGroupForTerseUpdate();
7862 }
7863 }
7314 } 7864 }
7315 7865
7316 public LSL_String llStringToBase64(string str) 7866 public LSL_String llStringToBase64(string str)
@@ -7459,13 +8009,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7459 public LSL_Integer llGetNumberOfPrims() 8009 public LSL_Integer llGetNumberOfPrims()
7460 { 8010 {
7461 m_host.AddScriptLPS(1); 8011 m_host.AddScriptLPS(1);
7462 int avatarCount = 0; 8012 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7463 World.ForEachScenePresence(delegate(ScenePresence presence) 8013
7464 {
7465 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7466 avatarCount++;
7467 });
7468
7469 return m_host.ParentGroup.PrimCount + avatarCount; 8014 return m_host.ParentGroup.PrimCount + avatarCount;
7470 } 8015 }
7471 8016
@@ -7481,55 +8026,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7481 m_host.AddScriptLPS(1); 8026 m_host.AddScriptLPS(1);
7482 UUID objID = UUID.Zero; 8027 UUID objID = UUID.Zero;
7483 LSL_List result = new LSL_List(); 8028 LSL_List result = new LSL_List();
8029
8030 // If the ID is not valid, return null result
7484 if (!UUID.TryParse(obj, out objID)) 8031 if (!UUID.TryParse(obj, out objID))
7485 { 8032 {
7486 result.Add(new LSL_Vector()); 8033 result.Add(new LSL_Vector());
7487 result.Add(new LSL_Vector()); 8034 result.Add(new LSL_Vector());
7488 return result; 8035 return result;
7489 } 8036 }
8037
8038 // Check if this is an attached prim. If so, replace
8039 // the UUID with the avatar UUID and report it's bounding box
8040 SceneObjectPart part = World.GetSceneObjectPart(objID);
8041 if (part != null && part.ParentGroup.IsAttachment)
8042 objID = part.ParentGroup.RootPart.AttachedAvatar;
8043
8044 // Find out if this is an avatar ID. If so, return it's box
7490 ScenePresence presence = World.GetScenePresence(objID); 8045 ScenePresence presence = World.GetScenePresence(objID);
7491 if (presence != null) 8046 if (presence != null)
7492 { 8047 {
7493 if (presence.ParentID == 0) // not sat on an object 8048 // As per LSL Wiki, there is no difference between sitting
8049 // and standing avatar since server 1.36
8050 LSL_Vector lower;
8051 LSL_Vector upper;
8052 if (presence.Animator.Animations.DefaultAnimation.AnimID
8053 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7494 { 8054 {
7495 LSL_Vector lower; 8055 // This is for ground sitting avatars
7496 LSL_Vector upper; 8056 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7497 if (presence.Animator.Animations.DefaultAnimation.AnimID 8057 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7498 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8058 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7499 {
7500 // This is for ground sitting avatars
7501 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7502 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7503 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7504 }
7505 else
7506 {
7507 // This is for standing/flying avatars
7508 float height = presence.Appearance.AvatarHeight / 2.0f;
7509 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7510 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7511 }
7512 result.Add(lower);
7513 result.Add(upper);
7514 return result;
7515 } 8059 }
7516 else 8060 else
7517 { 8061 {
7518 // sitting on an object so we need the bounding box of that 8062 // This is for standing/flying avatars
7519 // which should include the avatar so set the UUID to the 8063 float height = presence.Appearance.AvatarHeight / 2.0f;
7520 // UUID of the object the avatar is sat on and allow it to fall through 8064 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7521 // to processing an object 8065 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7522 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7523 objID = p.UUID;
7524 } 8066 }
8067
8068 // Adjust to the documented error offsets (see LSL Wiki)
8069 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8070 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8071
8072 if (lower.x > upper.x)
8073 lower.x = upper.x;
8074 if (lower.y > upper.y)
8075 lower.y = upper.y;
8076 if (lower.z > upper.z)
8077 lower.z = upper.z;
8078
8079 result.Add(lower);
8080 result.Add(upper);
8081 return result;
7525 } 8082 }
7526 SceneObjectPart part = World.GetSceneObjectPart(objID); 8083
8084 part = World.GetSceneObjectPart(objID);
7527 // Currently only works for single prims without a sitting avatar 8085 // Currently only works for single prims without a sitting avatar
7528 if (part != null) 8086 if (part != null)
7529 { 8087 {
7530 Vector3 halfSize = part.Scale / 2.0f; 8088 float minX;
7531 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8089 float maxX;
7532 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8090 float minY;
8091 float maxY;
8092 float minZ;
8093 float maxZ;
8094
8095 // This BBox is in sim coordinates, with the offset being
8096 // a contained point.
8097 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8098 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8099
8100 minX -= offsets[0].X;
8101 maxX -= offsets[0].X;
8102 minY -= offsets[0].Y;
8103 maxY -= offsets[0].Y;
8104 minZ -= offsets[0].Z;
8105 maxZ -= offsets[0].Z;
8106
8107 LSL_Vector lower;
8108 LSL_Vector upper;
8109
8110 // Adjust to the documented error offsets (see LSL Wiki)
8111 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8112 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8113
8114 if (lower.x > upper.x)
8115 lower.x = upper.x;
8116 if (lower.y > upper.y)
8117 lower.y = upper.y;
8118 if (lower.z > upper.z)
8119 lower.z = upper.z;
8120
7533 result.Add(lower); 8121 result.Add(lower);
7534 result.Add(upper); 8122 result.Add(upper);
7535 return result; 8123 return result;
@@ -7609,13 +8197,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7609 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8197 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7610 part.AbsolutePosition.Y, 8198 part.AbsolutePosition.Y,
7611 part.AbsolutePosition.Z); 8199 part.AbsolutePosition.Z);
7612 // For some reason, the part.AbsolutePosition.* values do not change if the
7613 // linkset is rotated; they always reflect the child prim's world position
7614 // as though the linkset is unrotated. This is incompatible behavior with SL's
7615 // implementation, so will break scripts imported from there (not to mention it
7616 // makes it more difficult to determine a child prim's actual inworld position).
7617 if (part.ParentID != 0)
7618 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7619 res.Add(v); 8200 res.Add(v);
7620 break; 8201 break;
7621 8202
@@ -7776,56 +8357,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8357 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7777 if (remain < 1) 8358 if (remain < 1)
7778 return res; 8359 return res;
7779 8360 face = (int)rules.GetLSLIntegerItem(idx++);
7780 face=(int)rules.GetLSLIntegerItem(idx++);
7781 8361
7782 tex = part.Shape.Textures; 8362 tex = part.Shape.Textures;
8363 int shiny;
7783 if (face == ScriptBaseClass.ALL_SIDES) 8364 if (face == ScriptBaseClass.ALL_SIDES)
7784 { 8365 {
7785 for (face = 0; face < GetNumberOfSides(part); face++) 8366 for (face = 0; face < GetNumberOfSides(part); face++)
7786 { 8367 {
7787 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8368 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7788 // Convert Shininess to PRIM_SHINY_* 8369 if (shinyness == Shininess.High)
7789 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8370 {
7790 // PRIM_BUMP_* 8371 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7791 res.Add(new LSL_Integer((int)texface.Bump)); 8372 }
8373 else if (shinyness == Shininess.Medium)
8374 {
8375 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8376 }
8377 else if (shinyness == Shininess.Low)
8378 {
8379 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8380 }
8381 else
8382 {
8383 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8384 }
8385 res.Add(new LSL_Integer(shiny));
8386 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7792 } 8387 }
7793 } 8388 }
7794 else 8389 else
7795 { 8390 {
7796 if (face >= 0 && face < GetNumberOfSides(part)) 8391 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8392 if (shinyness == Shininess.High)
7797 { 8393 {
7798 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8394 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7799 // Convert Shininess to PRIM_SHINY_* 8395 }
7800 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8396 else if (shinyness == Shininess.Medium)
7801 // PRIM_BUMP_* 8397 {
7802 res.Add(new LSL_Integer((int)texface.Bump)); 8398 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8399 }
8400 else if (shinyness == Shininess.Low)
8401 {
8402 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8403 }
8404 else
8405 {
8406 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7803 } 8407 }
8408 res.Add(new LSL_Integer(shiny));
8409 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7804 } 8410 }
7805 break; 8411 break;
7806 8412
7807 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8413 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7808 if (remain < 1) 8414 if (remain < 1)
7809 return res; 8415 return res;
7810 8416 face = (int)rules.GetLSLIntegerItem(idx++);
7811 face=(int)rules.GetLSLIntegerItem(idx++);
7812 8417
7813 tex = part.Shape.Textures; 8418 tex = part.Shape.Textures;
8419 int fullbright;
7814 if (face == ScriptBaseClass.ALL_SIDES) 8420 if (face == ScriptBaseClass.ALL_SIDES)
7815 { 8421 {
7816 for (face = 0; face < GetNumberOfSides(part); face++) 8422 for (face = 0; face < GetNumberOfSides(part); face++)
7817 { 8423 {
7818 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8424 if (tex.GetFace((uint)face).Fullbright == true)
7819 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8425 {
8426 fullbright = ScriptBaseClass.TRUE;
8427 }
8428 else
8429 {
8430 fullbright = ScriptBaseClass.FALSE;
8431 }
8432 res.Add(new LSL_Integer(fullbright));
7820 } 8433 }
7821 } 8434 }
7822 else 8435 else
7823 { 8436 {
7824 if (face >= 0 && face < GetNumberOfSides(part)) 8437 if (tex.GetFace((uint)face).Fullbright == true)
7825 { 8438 {
7826 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8439 fullbright = ScriptBaseClass.TRUE;
7827 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8440 }
8441 else
8442 {
8443 fullbright = ScriptBaseClass.FALSE;
7828 } 8444 }
8445 res.Add(new LSL_Integer(fullbright));
7829 } 8446 }
7830 break; 8447 break;
7831 8448
@@ -7847,27 +8464,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7847 break; 8464 break;
7848 8465
7849 case (int)ScriptBaseClass.PRIM_TEXGEN: 8466 case (int)ScriptBaseClass.PRIM_TEXGEN:
8467 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7850 if (remain < 1) 8468 if (remain < 1)
7851 return res; 8469 return res;
7852 8470 face = (int)rules.GetLSLIntegerItem(idx++);
7853 face=(int)rules.GetLSLIntegerItem(idx++);
7854 8471
7855 tex = part.Shape.Textures; 8472 tex = part.Shape.Textures;
7856 if (face == ScriptBaseClass.ALL_SIDES) 8473 if (face == ScriptBaseClass.ALL_SIDES)
7857 { 8474 {
7858 for (face = 0; face < GetNumberOfSides(part); face++) 8475 for (face = 0; face < GetNumberOfSides(part); face++)
7859 { 8476 {
7860 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8477 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7861 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8478 {
7862 res.Add(new LSL_Integer((uint)texgen >> 1)); 8479 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8480 }
8481 else
8482 {
8483 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8484 }
7863 } 8485 }
7864 } 8486 }
7865 else 8487 else
7866 { 8488 {
7867 if (face >= 0 && face < GetNumberOfSides(part)) 8489 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8490 {
8491 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8492 }
8493 else
7868 { 8494 {
7869 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8495 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7870 res.Add(new LSL_Integer((uint)texgen >> 1));
7871 } 8496 }
7872 } 8497 }
7873 break; 8498 break;
@@ -7890,28 +8515,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7890 case (int)ScriptBaseClass.PRIM_GLOW: 8515 case (int)ScriptBaseClass.PRIM_GLOW:
7891 if (remain < 1) 8516 if (remain < 1)
7892 return res; 8517 return res;
7893 8518 face = (int)rules.GetLSLIntegerItem(idx++);
7894 face=(int)rules.GetLSLIntegerItem(idx++);
7895 8519
7896 tex = part.Shape.Textures; 8520 tex = part.Shape.Textures;
8521 float primglow;
7897 if (face == ScriptBaseClass.ALL_SIDES) 8522 if (face == ScriptBaseClass.ALL_SIDES)
7898 { 8523 {
7899 for (face = 0; face < GetNumberOfSides(part); face++) 8524 for (face = 0; face < GetNumberOfSides(part); face++)
7900 { 8525 {
7901 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8526 primglow = tex.GetFace((uint)face).Glow;
7902 res.Add(new LSL_Float(texface.Glow)); 8527 res.Add(new LSL_Float(primglow));
7903 } 8528 }
7904 } 8529 }
7905 else 8530 else
7906 { 8531 {
7907 if (face >= 0 && face < GetNumberOfSides(part)) 8532 primglow = tex.GetFace((uint)face).Glow;
7908 { 8533 res.Add(new LSL_Float(primglow));
7909 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7910 res.Add(new LSL_Float(texface.Glow));
7911 }
7912 } 8534 }
7913 break; 8535 break;
7914
7915 case (int)ScriptBaseClass.PRIM_TEXT: 8536 case (int)ScriptBaseClass.PRIM_TEXT:
7916 Color4 textColor = part.GetTextColor(); 8537 Color4 textColor = part.GetTextColor();
7917 res.Add(part.Text); 8538 res.Add(part.Text);
@@ -8460,8 +9081,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8460 // The function returns an ordered list 9081 // The function returns an ordered list
8461 // representing the tokens found in the supplied 9082 // representing the tokens found in the supplied
8462 // sources string. If two successive tokenizers 9083 // sources string. If two successive tokenizers
8463 // are encountered, then a NULL entry is added 9084 // are encountered, then a null-string entry is
8464 // to the list. 9085 // added to the list.
8465 // 9086 //
8466 // It is a precondition that the source and 9087 // It is a precondition that the source and
8467 // toekizer lisst are non-null. If they are null, 9088 // toekizer lisst are non-null. If they are null,
@@ -8469,7 +9090,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8469 // while their lengths are being determined. 9090 // while their lengths are being determined.
8470 // 9091 //
8471 // A small amount of working memoryis required 9092 // A small amount of working memoryis required
8472 // of approximately 8*#tokenizers. 9093 // of approximately 8*#tokenizers + 8*srcstrlen.
8473 // 9094 //
8474 // There are many ways in which this function 9095 // There are many ways in which this function
8475 // can be implemented, this implementation is 9096 // can be implemented, this implementation is
@@ -8485,155 +9106,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8485 // and eliminates redundant tokenizers as soon 9106 // and eliminates redundant tokenizers as soon
8486 // as is possible. 9107 // as is possible.
8487 // 9108 //
8488 // The implementation tries to avoid any copying 9109 // The implementation tries to minimize temporary
8489 // of arrays or other objects. 9110 // garbage generation.
8490 // </remarks> 9111 // </remarks>
8491 9112
8492 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9113 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8493 { 9114 {
8494 int beginning = 0; 9115 return ParseString2List(src, separators, spacers, true);
8495 int srclen = src.Length; 9116 }
8496 int seplen = separators.Length;
8497 object[] separray = separators.Data;
8498 int spclen = spacers.Length;
8499 object[] spcarray = spacers.Data;
8500 int mlen = seplen+spclen;
8501
8502 int[] offset = new int[mlen+1];
8503 bool[] active = new bool[mlen];
8504
8505 int best;
8506 int j;
8507
8508 // Initial capacity reduces resize cost
8509 9117
8510 LSL_List tokens = new LSL_List(); 9118 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9119 {
9120 int srclen = src.Length;
9121 int seplen = separators.Length;
9122 object[] separray = separators.Data;
9123 int spclen = spacers.Length;
9124 object[] spcarray = spacers.Data;
9125 int dellen = 0;
9126 string[] delarray = new string[seplen+spclen];
8511 9127
8512 // All entries are initially valid 9128 int outlen = 0;
9129 string[] outarray = new string[srclen*2+1];
8513 9130
8514 for (int i = 0; i < mlen; i++) 9131 int i, j;
8515 active[i] = true; 9132 string d;
8516 9133
8517 offset[mlen] = srclen; 9134 m_host.AddScriptLPS(1);
8518 9135
8519 while (beginning < srclen) 9136 /*
9137 * Convert separator and spacer lists to C# strings.
9138 * Also filter out null strings so we don't hang.
9139 */
9140 for (i = 0; i < seplen; i ++)
8520 { 9141 {
9142 d = separray[i].ToString();
9143 if (d.Length > 0)
9144 {
9145 delarray[dellen++] = d;
9146 }
9147 }
9148 seplen = dellen;
8521 9149
8522 best = mlen; // as bad as it gets 9150 for (i = 0; i < spclen; i ++)
9151 {
9152 d = spcarray[i].ToString();
9153 if (d.Length > 0)
9154 {
9155 delarray[dellen++] = d;
9156 }
9157 }
8523 9158
8524 // Scan for separators 9159 /*
9160 * Scan through source string from beginning to end.
9161 */
9162 for (i = 0;;)
9163 {
8525 9164
8526 for (j = 0; j < seplen; j++) 9165 /*
9166 * Find earliest delimeter in src starting at i (if any).
9167 */
9168 int earliestDel = -1;
9169 int earliestSrc = srclen;
9170 string earliestStr = null;
9171 for (j = 0; j < dellen; j ++)
8527 { 9172 {
8528 if (separray[j].ToString() == String.Empty) 9173 d = delarray[j];
8529 active[j] = false; 9174 if (d != null)
8530
8531 if (active[j])
8532 { 9175 {
8533 // scan all of the markers 9176 int index = src.IndexOf(d, i);
8534 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9177 if (index < 0)
8535 { 9178 {
8536 // not present at all 9179 delarray[j] = null; // delim nowhere in src, don't check it anymore
8537 active[j] = false;
8538 } 9180 }
8539 else 9181 else if (index < earliestSrc)
8540 { 9182 {
8541 // present and correct 9183 earliestSrc = index; // where delimeter starts in source string
8542 if (offset[j] < offset[best]) 9184 earliestDel = j; // where delimeter is in delarray[]
8543 { 9185 earliestStr = d; // the delimeter string from delarray[]
8544 // closest so far 9186 if (index == i) break; // can't do any better than found at beg of string
8545 best = j;
8546 if (offset[best] == beginning)
8547 break;
8548 }
8549 } 9187 }
8550 } 9188 }
8551 } 9189 }
8552 9190
8553 // Scan for spacers 9191 /*
8554 9192 * Output source string starting at i through start of earliest delimeter.
8555 if (offset[best] != beginning) 9193 */
9194 if (keepNulls || (earliestSrc > i))
8556 { 9195 {
8557 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9196 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8558 {
8559 if (spcarray[j-seplen].ToString() == String.Empty)
8560 active[j] = false;
8561
8562 if (active[j])
8563 {
8564 // scan all of the markers
8565 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8566 {
8567 // not present at all
8568 active[j] = false;
8569 }
8570 else
8571 {
8572 // present and correct
8573 if (offset[j] < offset[best])
8574 {
8575 // closest so far
8576 best = j;
8577 }
8578 }
8579 }
8580 }
8581 } 9197 }
8582 9198
8583 // This is the normal exit from the scanning loop 9199 /*
9200 * If no delimeter found at or after i, we're done scanning.
9201 */
9202 if (earliestDel < 0) break;
8584 9203
8585 if (best == mlen) 9204 /*
9205 * If delimeter was a spacer, output the spacer.
9206 */
9207 if (earliestDel >= seplen)
8586 { 9208 {
8587 // no markers were found on this pass 9209 outarray[outlen++] = earliestStr;
8588 // so we're pretty much done
8589 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8590 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8591 break;
8592 } 9210 }
8593 9211
8594 // Otherwise we just add the newly delimited token 9212 /*
8595 // and recalculate where the search should continue. 9213 * Look at rest of src string following delimeter.
8596 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9214 */
8597 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9215 i = earliestSrc + earliestStr.Length;
8598
8599 if (best < seplen)
8600 {
8601 beginning = offset[best] + (separray[best].ToString()).Length;
8602 }
8603 else
8604 {
8605 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8606 string str = spcarray[best - seplen].ToString();
8607 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8608 tokens.Add(new LSL_String(str));
8609 }
8610 } 9216 }
8611 9217
8612 // This an awkward an not very intuitive boundary case. If the 9218 /*
8613 // last substring is a tokenizer, then there is an implied trailing 9219 * Make up an exact-sized output array suitable for an LSL_List object.
8614 // null list entry. Hopefully the single comparison will not be too 9220 */
8615 // arduous. Alternatively the 'break' could be replced with a return 9221 object[] outlist = new object[outlen];
8616 // but that's shabby programming. 9222 for (i = 0; i < outlen; i ++)
8617
8618 if ((beginning == srclen) && (keepNulls))
8619 { 9223 {
8620 if (srclen != 0) 9224 outlist[i] = new LSL_String(outarray[i]);
8621 tokens.Add(new LSL_String(""));
8622 } 9225 }
8623 9226 return new LSL_List(outlist);
8624 return tokens;
8625 }
8626
8627 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8628 {
8629 m_host.AddScriptLPS(1);
8630 return this.ParseString(src, separators, spacers, false);
8631 }
8632
8633 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8634 {
8635 m_host.AddScriptLPS(1);
8636 return this.ParseString(src, separators, spacers, true);
8637 } 9227 }
8638 9228
8639 public LSL_Integer llGetObjectPermMask(int mask) 9229 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8710,28 +9300,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8710 { 9300 {
8711 m_host.AddScriptLPS(1); 9301 m_host.AddScriptLPS(1);
8712 9302
8713 lock (m_host.TaskInventory) 9303 m_host.TaskInventory.LockItemsForRead(true);
9304 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8714 { 9305 {
8715 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9306 if (inv.Value.Name == item)
8716 { 9307 {
8717 if (inv.Value.Name == item) 9308 m_host.TaskInventory.LockItemsForRead(false);
9309 switch (mask)
8718 { 9310 {
8719 switch (mask) 9311 case 0:
8720 { 9312 return (int)inv.Value.BasePermissions;
8721 case 0: 9313 case 1:
8722 return (int)inv.Value.BasePermissions; 9314 return (int)inv.Value.CurrentPermissions;
8723 case 1: 9315 case 2:
8724 return (int)inv.Value.CurrentPermissions; 9316 return (int)inv.Value.GroupPermissions;
8725 case 2: 9317 case 3:
8726 return (int)inv.Value.GroupPermissions; 9318 return (int)inv.Value.EveryonePermissions;
8727 case 3: 9319 case 4:
8728 return (int)inv.Value.EveryonePermissions; 9320 return (int)inv.Value.NextPermissions;
8729 case 4:
8730 return (int)inv.Value.NextPermissions;
8731 }
8732 } 9321 }
8733 } 9322 }
8734 } 9323 }
9324 m_host.TaskInventory.LockItemsForRead(false);
8735 9325
8736 return -1; 9326 return -1;
8737 } 9327 }
@@ -8778,16 +9368,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8778 { 9368 {
8779 m_host.AddScriptLPS(1); 9369 m_host.AddScriptLPS(1);
8780 9370
8781 lock (m_host.TaskInventory) 9371 m_host.TaskInventory.LockItemsForRead(true);
9372 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8782 { 9373 {
8783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9374 if (inv.Value.Name == item)
8784 { 9375 {
8785 if (inv.Value.Name == item) 9376 m_host.TaskInventory.LockItemsForRead(false);
8786 { 9377 return inv.Value.CreatorID.ToString();
8787 return inv.Value.CreatorID.ToString();
8788 }
8789 } 9378 }
8790 } 9379 }
9380 m_host.TaskInventory.LockItemsForRead(false);
8791 9381
8792 llSay(0, "No item name '" + item + "'"); 9382 llSay(0, "No item name '" + item + "'");
8793 9383
@@ -8935,7 +9525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8935 } 9525 }
8936 9526
8937 /// <summary> 9527 /// <summary>
8938 /// illListReplaceList removes the sub-list defined by the inclusive indices 9528 /// llListReplaceList removes the sub-list defined by the inclusive indices
8939 /// start and end and inserts the src list in its place. The inclusive 9529 /// start and end and inserts the src list in its place. The inclusive
8940 /// nature of the indices means that at least one element must be deleted 9530 /// nature of the indices means that at least one element must be deleted
8941 /// if the indices are within the bounds of the existing list. I.e. 2,2 9531 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8992,16 +9582,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8992 // based upon end. Note that if end exceeds the upper 9582 // based upon end. Note that if end exceeds the upper
8993 // bound in this case, the entire destination list 9583 // bound in this case, the entire destination list
8994 // is removed. 9584 // is removed.
8995 else 9585 else if (start == 0)
8996 { 9586 {
8997 if (end + 1 < dest.Length) 9587 if (end + 1 < dest.Length)
8998 {
8999 return src + dest.GetSublist(end + 1, -1); 9588 return src + dest.GetSublist(end + 1, -1);
9000 }
9001 else 9589 else
9002 {
9003 return src; 9590 return src;
9004 } 9591 }
9592 else // Start < 0
9593 {
9594 if (end + 1 < dest.Length)
9595 return dest.GetSublist(end + 1, -1);
9596 else
9597 return new LSL_List();
9005 } 9598 }
9006 } 9599 }
9007 // Finally, if start > end, we strip away a prefix and 9600 // Finally, if start > end, we strip away a prefix and
@@ -9052,17 +9645,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 int width = 0; 9645 int width = 0;
9053 int height = 0; 9646 int height = 0;
9054 9647
9055 ParcelMediaCommandEnum? commandToSend = null; 9648 uint commandToSend = 0;
9056 float time = 0.0f; // default is from start 9649 float time = 0.0f; // default is from start
9057 9650
9058 ScenePresence presence = null; 9651 ScenePresence presence = null;
9059 9652
9060 for (int i = 0; i < commandList.Data.Length; i++) 9653 for (int i = 0; i < commandList.Data.Length; i++)
9061 { 9654 {
9062 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9655 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9063 switch (command) 9656 switch (command)
9064 { 9657 {
9065 case ParcelMediaCommandEnum.Agent: 9658 case (uint)ParcelMediaCommandEnum.Agent:
9066 // we send only to one agent 9659 // we send only to one agent
9067 if ((i + 1) < commandList.Length) 9660 if ((i + 1) < commandList.Length)
9068 { 9661 {
@@ -9079,25 +9672,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9079 } 9672 }
9080 break; 9673 break;
9081 9674
9082 case ParcelMediaCommandEnum.Loop: 9675 case (uint)ParcelMediaCommandEnum.Loop:
9083 loop = 1; 9676 loop = 1;
9084 commandToSend = command; 9677 commandToSend = command;
9085 update = true; //need to send the media update packet to set looping 9678 update = true; //need to send the media update packet to set looping
9086 break; 9679 break;
9087 9680
9088 case ParcelMediaCommandEnum.Play: 9681 case (uint)ParcelMediaCommandEnum.Play:
9089 loop = 0; 9682 loop = 0;
9090 commandToSend = command; 9683 commandToSend = command;
9091 update = true; //need to send the media update packet to make sure it doesn't loop 9684 update = true; //need to send the media update packet to make sure it doesn't loop
9092 break; 9685 break;
9093 9686
9094 case ParcelMediaCommandEnum.Pause: 9687 case (uint)ParcelMediaCommandEnum.Pause:
9095 case ParcelMediaCommandEnum.Stop: 9688 case (uint)ParcelMediaCommandEnum.Stop:
9096 case ParcelMediaCommandEnum.Unload: 9689 case (uint)ParcelMediaCommandEnum.Unload:
9097 commandToSend = command; 9690 commandToSend = command;
9098 break; 9691 break;
9099 9692
9100 case ParcelMediaCommandEnum.Url: 9693 case (uint)ParcelMediaCommandEnum.Url:
9101 if ((i + 1) < commandList.Length) 9694 if ((i + 1) < commandList.Length)
9102 { 9695 {
9103 if (commandList.Data[i + 1] is LSL_String) 9696 if (commandList.Data[i + 1] is LSL_String)
@@ -9110,7 +9703,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9110 } 9703 }
9111 break; 9704 break;
9112 9705
9113 case ParcelMediaCommandEnum.Texture: 9706 case (uint)ParcelMediaCommandEnum.Texture:
9114 if ((i + 1) < commandList.Length) 9707 if ((i + 1) < commandList.Length)
9115 { 9708 {
9116 if (commandList.Data[i + 1] is LSL_String) 9709 if (commandList.Data[i + 1] is LSL_String)
@@ -9123,7 +9716,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9123 } 9716 }
9124 break; 9717 break;
9125 9718
9126 case ParcelMediaCommandEnum.Time: 9719 case (uint)ParcelMediaCommandEnum.Time:
9127 if ((i + 1) < commandList.Length) 9720 if ((i + 1) < commandList.Length)
9128 { 9721 {
9129 if (commandList.Data[i + 1] is LSL_Float) 9722 if (commandList.Data[i + 1] is LSL_Float)
@@ -9135,7 +9728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9135 } 9728 }
9136 break; 9729 break;
9137 9730
9138 case ParcelMediaCommandEnum.AutoAlign: 9731 case (uint)ParcelMediaCommandEnum.AutoAlign:
9139 if ((i + 1) < commandList.Length) 9732 if ((i + 1) < commandList.Length)
9140 { 9733 {
9141 if (commandList.Data[i + 1] is LSL_Integer) 9734 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9149,7 +9742,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9149 } 9742 }
9150 break; 9743 break;
9151 9744
9152 case ParcelMediaCommandEnum.Type: 9745 case (uint)ParcelMediaCommandEnum.Type:
9153 if ((i + 1) < commandList.Length) 9746 if ((i + 1) < commandList.Length)
9154 { 9747 {
9155 if (commandList.Data[i + 1] is LSL_String) 9748 if (commandList.Data[i + 1] is LSL_String)
@@ -9162,7 +9755,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9162 } 9755 }
9163 break; 9756 break;
9164 9757
9165 case ParcelMediaCommandEnum.Desc: 9758 case (uint)ParcelMediaCommandEnum.Desc:
9166 if ((i + 1) < commandList.Length) 9759 if ((i + 1) < commandList.Length)
9167 { 9760 {
9168 if (commandList.Data[i + 1] is LSL_String) 9761 if (commandList.Data[i + 1] is LSL_String)
@@ -9175,7 +9768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9175 } 9768 }
9176 break; 9769 break;
9177 9770
9178 case ParcelMediaCommandEnum.Size: 9771 case (uint)ParcelMediaCommandEnum.Size:
9179 if ((i + 2) < commandList.Length) 9772 if ((i + 2) < commandList.Length)
9180 { 9773 {
9181 if (commandList.Data[i + 1] is LSL_Integer) 9774 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9245,7 +9838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9245 } 9838 }
9246 } 9839 }
9247 9840
9248 if (commandToSend != null) 9841 if (commandToSend != 0)
9249 { 9842 {
9250 // the commandList contained a start/stop/... command, too 9843 // the commandList contained a start/stop/... command, too
9251 if (presence == null) 9844 if (presence == null)
@@ -9282,7 +9875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9282 9875
9283 if (aList.Data[i] != null) 9876 if (aList.Data[i] != null)
9284 { 9877 {
9285 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9878 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9286 { 9879 {
9287 case ParcelMediaCommandEnum.Url: 9880 case ParcelMediaCommandEnum.Url:
9288 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9881 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9325,16 +9918,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9325 { 9918 {
9326 m_host.AddScriptLPS(1); 9919 m_host.AddScriptLPS(1);
9327 9920
9328 lock (m_host.TaskInventory) 9921 m_host.TaskInventory.LockItemsForRead(true);
9922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9329 { 9923 {
9330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9924 if (inv.Value.Name == name)
9331 { 9925 {
9332 if (inv.Value.Name == name) 9926 m_host.TaskInventory.LockItemsForRead(false);
9333 { 9927 return inv.Value.Type;
9334 return inv.Value.Type;
9335 }
9336 } 9928 }
9337 } 9929 }
9930 m_host.TaskInventory.LockItemsForRead(false);
9338 9931
9339 return -1; 9932 return -1;
9340 } 9933 }
@@ -9345,15 +9938,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9345 9938
9346 if (quick_pay_buttons.Data.Length < 4) 9939 if (quick_pay_buttons.Data.Length < 4)
9347 { 9940 {
9348 LSLError("List must have at least 4 elements"); 9941 int x;
9349 return; 9942 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9943 {
9944 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9945 }
9350 } 9946 }
9351 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9947 int[] nPrice = new int[5];
9352 9948 nPrice[0] = price;
9353 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9949 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9354 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9950 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9355 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9951 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9356 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9952 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9953 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9357 m_host.ParentGroup.HasGroupChanged = true; 9954 m_host.ParentGroup.HasGroupChanged = true;
9358 } 9955 }
9359 9956
@@ -9365,17 +9962,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9365 if (invItemID == UUID.Zero) 9962 if (invItemID == UUID.Zero)
9366 return new LSL_Vector(); 9963 return new LSL_Vector();
9367 9964
9368 lock (m_host.TaskInventory) 9965 m_host.TaskInventory.LockItemsForRead(true);
9966 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9369 { 9967 {
9370 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9968 m_host.TaskInventory.LockItemsForRead(false);
9371 return new LSL_Vector(); 9969 return new LSL_Vector();
9970 }
9372 9971
9373 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9972 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9374 { 9973 {
9375 ShoutError("No permissions to track the camera"); 9974 ShoutError("No permissions to track the camera");
9376 return new LSL_Vector(); 9975 m_host.TaskInventory.LockItemsForRead(false);
9377 } 9976 return new LSL_Vector();
9378 } 9977 }
9978 m_host.TaskInventory.LockItemsForRead(false);
9379 9979
9380 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9980 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9381 if (presence != null) 9981 if (presence != null)
@@ -9393,17 +9993,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9393 if (invItemID == UUID.Zero) 9993 if (invItemID == UUID.Zero)
9394 return new LSL_Rotation(); 9994 return new LSL_Rotation();
9395 9995
9396 lock (m_host.TaskInventory) 9996 m_host.TaskInventory.LockItemsForRead(true);
9997 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9397 { 9998 {
9398 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9999 m_host.TaskInventory.LockItemsForRead(false);
9399 return new LSL_Rotation(); 10000 return new LSL_Rotation();
9400 10001 }
9401 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10002 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9402 { 10003 {
9403 ShoutError("No permissions to track the camera"); 10004 ShoutError("No permissions to track the camera");
9404 return new LSL_Rotation(); 10005 m_host.TaskInventory.LockItemsForRead(false);
9405 } 10006 return new LSL_Rotation();
9406 } 10007 }
10008 m_host.TaskInventory.LockItemsForRead(false);
9407 10009
9408 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10010 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9409 if (presence != null) 10011 if (presence != null)
@@ -9465,8 +10067,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 { 10067 {
9466 m_host.AddScriptLPS(1); 10068 m_host.AddScriptLPS(1);
9467 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10069 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9468 if (detectedParams == null) return; // only works on the first detected avatar 10070 if (detectedParams == null)
9469 10071 {
10072 if (m_host.IsAttachment == true)
10073 {
10074 detectedParams = new DetectParams();
10075 detectedParams.Key = m_host.OwnerID;
10076 }
10077 else
10078 {
10079 return;
10080 }
10081 }
10082
9470 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10083 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9471 if (avatar != null) 10084 if (avatar != null)
9472 { 10085 {
@@ -9474,6 +10087,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9474 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10087 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9475 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10088 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9476 } 10089 }
10090
9477 ScriptSleep(1000); 10091 ScriptSleep(1000);
9478 } 10092 }
9479 10093
@@ -9566,14 +10180,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 if (objectID == UUID.Zero) return; 10180 if (objectID == UUID.Zero) return;
9567 10181
9568 UUID agentID; 10182 UUID agentID;
9569 lock (m_host.TaskInventory) 10183 m_host.TaskInventory.LockItemsForRead(true);
9570 { 10184 // we need the permission first, to know which avatar we want to set the camera for
9571 // we need the permission first, to know which avatar we want to set the camera for 10185 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9572 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9573 10186
9574 if (agentID == UUID.Zero) return; 10187 if (agentID == UUID.Zero)
9575 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10188 {
10189 m_host.TaskInventory.LockItemsForRead(false);
10190 return;
10191 }
10192 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10193 {
10194 m_host.TaskInventory.LockItemsForRead(false);
10195 return;
9576 } 10196 }
10197 m_host.TaskInventory.LockItemsForRead(false);
9577 10198
9578 ScenePresence presence = World.GetScenePresence(agentID); 10199 ScenePresence presence = World.GetScenePresence(agentID);
9579 10200
@@ -9582,12 +10203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 10203
9583 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10204 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9584 object[] data = rules.Data; 10205 object[] data = rules.Data;
9585 for (int i = 0; i < data.Length; ++i) { 10206 for (int i = 0; i < data.Length; ++i)
10207 {
9586 int type = Convert.ToInt32(data[i++].ToString()); 10208 int type = Convert.ToInt32(data[i++].ToString());
9587 if (i >= data.Length) break; // odd number of entries => ignore the last 10209 if (i >= data.Length) break; // odd number of entries => ignore the last
9588 10210
9589 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10211 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9590 switch (type) { 10212 switch (type)
10213 {
9591 case ScriptBaseClass.CAMERA_FOCUS: 10214 case ScriptBaseClass.CAMERA_FOCUS:
9592 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10215 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9593 case ScriptBaseClass.CAMERA_POSITION: 10216 case ScriptBaseClass.CAMERA_POSITION:
@@ -9623,12 +10246,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 10246
9624 // we need the permission first, to know which avatar we want to clear the camera for 10247 // we need the permission first, to know which avatar we want to clear the camera for
9625 UUID agentID; 10248 UUID agentID;
9626 lock (m_host.TaskInventory) 10249 m_host.TaskInventory.LockItemsForRead(true);
10250 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10251 if (agentID == UUID.Zero)
10252 {
10253 m_host.TaskInventory.LockItemsForRead(false);
10254 return;
10255 }
10256 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9627 { 10257 {
9628 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10258 m_host.TaskInventory.LockItemsForRead(false);
9629 if (agentID == UUID.Zero) return; 10259 return;
9630 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9631 } 10260 }
10261 m_host.TaskInventory.LockItemsForRead(false);
9632 10262
9633 ScenePresence presence = World.GetScenePresence(agentID); 10263 ScenePresence presence = World.GetScenePresence(agentID);
9634 10264
@@ -9695,19 +10325,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10325 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9696 { 10326 {
9697 m_host.AddScriptLPS(1); 10327 m_host.AddScriptLPS(1);
9698 string ret = String.Empty; 10328
9699 string src1 = llBase64ToString(str1); 10329 if (str1 == String.Empty)
9700 string src2 = llBase64ToString(str2); 10330 return String.Empty;
9701 int c = 0; 10331 if (str2 == String.Empty)
9702 for (int i = 0; i < src1.Length; i++) 10332 return str1;
10333
10334 int len = str2.Length;
10335 if ((len % 4) != 0) // LL is EVIL!!!!
10336 {
10337 while (str2.EndsWith("="))
10338 str2 = str2.Substring(0, str2.Length - 1);
10339
10340 len = str2.Length;
10341 int mod = len % 4;
10342
10343 if (mod == 1)
10344 str2 = str2.Substring(0, str2.Length - 1);
10345 else if (mod == 2)
10346 str2 += "==";
10347 else if (mod == 3)
10348 str2 += "=";
10349 }
10350
10351 byte[] data1;
10352 byte[] data2;
10353 try
10354 {
10355 data1 = Convert.FromBase64String(str1);
10356 data2 = Convert.FromBase64String(str2);
10357 }
10358 catch (Exception)
9703 { 10359 {
9704 ret += (char) (src1[i] ^ src2[c]); 10360 return new LSL_String(String.Empty);
10361 }
9705 10362
9706 c++; 10363 byte[] d2 = new Byte[data1.Length];
9707 if (c >= src2.Length) 10364 int pos = 0;
9708 c = 0; 10365
10366 if (data1.Length <= data2.Length)
10367 {
10368 Array.Copy(data2, 0, d2, 0, data1.Length);
9709 } 10369 }
9710 return llStringToBase64(ret); 10370 else
10371 {
10372 while (pos < data1.Length)
10373 {
10374 len = data1.Length - pos;
10375 if (len > data2.Length)
10376 len = data2.Length;
10377
10378 Array.Copy(data2, 0, d2, pos, len);
10379 pos += len;
10380 }
10381 }
10382
10383 for (pos = 0 ; pos < data1.Length ; pos++ )
10384 data1[pos] ^= d2[pos];
10385
10386 return Convert.ToBase64String(data1);
9711 } 10387 }
9712 10388
9713 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10389 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9766,12 +10442,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9766 Regex r = new Regex(authregex); 10442 Regex r = new Regex(authregex);
9767 int[] gnums = r.GetGroupNumbers(); 10443 int[] gnums = r.GetGroupNumbers();
9768 Match m = r.Match(url); 10444 Match m = r.Match(url);
9769 if (m.Success) { 10445 if (m.Success)
9770 for (int i = 1; i < gnums.Length; i++) { 10446 {
10447 for (int i = 1; i < gnums.Length; i++)
10448 {
9771 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10449 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9772 //CaptureCollection cc = g.Captures; 10450 //CaptureCollection cc = g.Captures;
9773 } 10451 }
9774 if (m.Groups.Count == 5) { 10452 if (m.Groups.Count == 5)
10453 {
9775 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10454 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9776 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10455 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9777 } 10456 }
@@ -9883,7 +10562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 { 10562 {
9884 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10563 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9885 { 10564 {
9886 ret.Add(detectedParams.Key.ToString()); 10565 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9887 ret.Add(detectedParams.Value); 10566 ret.Add(detectedParams.Value);
9888 } 10567 }
9889 } 10568 }
@@ -10052,15 +10731,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10052 10731
10053 internal UUID ScriptByName(string name) 10732 internal UUID ScriptByName(string name)
10054 { 10733 {
10055 lock (m_host.TaskInventory) 10734 m_host.TaskInventory.LockItemsForRead(true);
10735
10736 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10056 { 10737 {
10057 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10738 if (item.Type == 10 && item.Name == name)
10058 { 10739 {
10059 if (item.Type == 10 && item.Name == name) 10740 m_host.TaskInventory.LockItemsForRead(false);
10060 return item.ItemID; 10741 return item.ItemID;
10061 } 10742 }
10062 } 10743 }
10063 10744
10745 m_host.TaskInventory.LockItemsForRead(false);
10746
10064 return UUID.Zero; 10747 return UUID.Zero;
10065 } 10748 }
10066 10749
@@ -10101,6 +10784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10101 { 10784 {
10102 m_host.AddScriptLPS(1); 10785 m_host.AddScriptLPS(1);
10103 10786
10787 //Clone is thread safe
10104 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10788 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10105 10789
10106 UUID assetID = UUID.Zero; 10790 UUID assetID = UUID.Zero;
@@ -10163,6 +10847,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10163 { 10847 {
10164 m_host.AddScriptLPS(1); 10848 m_host.AddScriptLPS(1);
10165 10849
10850 //Clone is thread safe
10166 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10851 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10167 10852
10168 UUID assetID = UUID.Zero; 10853 UUID assetID = UUID.Zero;
@@ -10243,15 +10928,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10243 return GetLinkPrimitiveParams(obj, rules); 10928 return GetLinkPrimitiveParams(obj, rules);
10244 } 10929 }
10245 10930
10246 public void print(string str) 10931 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10247 { 10932 {
10248 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10933 List<SceneObjectPart> parts = GetLinkParts(link);
10249 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10934 if (parts.Count < 1)
10250 if (ossl != null) 10935 return 0;
10251 { 10936
10252 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10937 return GetNumberOfSides(parts[0]);
10253 m_log.Info("LSL print():" + str);
10254 }
10255 } 10938 }
10256 10939
10257 private string Name2Username(string name) 10940 private string Name2Username(string name)
@@ -10296,6 +10979,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10296 10979
10297 return rq.ToString(); 10980 return rq.ToString();
10298 } 10981 }
10982
10983 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
10984 {
10985 m_SayShoutCount = 0;
10986 }
10299 } 10987 }
10300 10988
10301 public class NotecardCache 10989 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 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 654ea81..0ae2388 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -402,7 +402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
402 LSL_Vector llWind(LSL_Vector offset); 402 LSL_Vector llWind(LSL_Vector offset);
403 LSL_String llXorBase64Strings(string str1, string str2); 403 LSL_String llXorBase64Strings(string str1, string str2);
404 LSL_String llXorBase64StringsCorrect(string str1, string str2); 404 LSL_String llXorBase64StringsCorrect(string str1, string str2);
405 void print(string str); 405 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
406 406
407 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 407 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
408 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 408 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 63007c6..c08ad3b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9377cda..5f94ff5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 303d75e..63cac9a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
@@ -1868,9 +1870,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1868 return m_LSL_Functions.llClearPrimMedia(face); 1870 return m_LSL_Functions.llClearPrimMedia(face);
1869 } 1871 }
1870 1872
1871 public void print(string str) 1873 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1872 { 1874 {
1873 m_LSL_Functions.print(str); 1875 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1874 } 1876 }
1875 } 1877 }
1876} 1878}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);