aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2144
-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
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
19 files changed, 2017 insertions, 966 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 aa28fa0..0ff3005 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
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;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -288,40 +346,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 346 protected UUID InventorySelf()
289 { 347 {
290 UUID invItemID = new UUID(); 348 UUID invItemID = new UUID();
291 349 bool unlock = false;
292 lock (m_host.TaskInventory) 350 if (!m_host.TaskInventory.IsReadLockedByMe())
351 {
352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 356 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 357 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 358 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 359 invItemID = inv.Key;
297 { 360 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 361 }
302 } 362 }
303 363 if (unlock)
364 {
365 m_host.TaskInventory.LockItemsForRead(false);
366 }
304 return invItemID; 367 return invItemID;
305 } 368 }
306 369
307 protected UUID InventoryKey(string name, int type) 370 protected UUID InventoryKey(string name, int type)
308 { 371 {
309 m_host.AddScriptLPS(1); 372 m_host.AddScriptLPS(1);
310 373 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 374
375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 376 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 377 if (inv.Value.Name == name)
314 { 378 {
315 if (inv.Value.Name == name) 379 m_host.TaskInventory.LockItemsForRead(false);
380
381 if (inv.Value.Type != type)
316 { 382 {
317 if (inv.Value.Type != type) 383 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 384 }
385
386 return inv.Value.AssetID;
322 } 387 }
323 } 388 }
324 389
390 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 391 return UUID.Zero;
326 } 392 }
327 393
@@ -329,17 +395,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 395 {
330 m_host.AddScriptLPS(1); 396 m_host.AddScriptLPS(1);
331 397
332 lock (m_host.TaskInventory) 398
399 m_host.TaskInventory.LockItemsForRead(true);
400
401 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 402 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 403 if (inv.Value.Name == name)
335 { 404 {
336 if (inv.Value.Name == name) 405 m_host.TaskInventory.LockItemsForRead(false);
337 { 406 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 407 }
341 } 408 }
342 409
410 m_host.TaskInventory.LockItemsForRead(false);
411
412
343 return UUID.Zero; 413 return UUID.Zero;
344 } 414 }
345 415
@@ -481,26 +551,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 551
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 552 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 553
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 554 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
486 555
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 556 // normalize an angle between -PI and PI (-180 to +180 degrees)
557 protected double NormalizeAngle(double angle)
558 {
559 if (angle > -Math.PI && angle < Math.PI)
560 return angle;
561
562 int numPis = (int)(Math.PI / angle);
563 double remainder = angle - Math.PI * numPis;
564 if (numPis % 2 == 1)
565 return Math.PI - angle;
566 return remainder;
567 }
568
569 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 570 {
489 m_host.AddScriptLPS(1); 571 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 572 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); 573
492 double m = (t.x + t.y + t.z + t.s); 574 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 575 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 576 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 577 double sqz = q1.y*q1.y;
496 if (p > 0) 578 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)), 579 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 580 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))); 581 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 582 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)); 583 eul.x = 0;
502 else 584 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)); 585 }
586 if (test < -0.4999*unit) { // singularity at south pole
587 eul.z = -2 * Math.Atan2(q1.x,q1.s);
588 eul.y = -Math.PI/2;
589 eul.x = 0;
590 return eul;
591 }
592 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
593 eul.y = Math.Asin(2*test/unit);
594 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
595 return eul;
504 } 596 }
505 597
506 /* From wiki: 598 /* From wiki:
@@ -702,77 +794,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 794 {
703 //A and B should both be normalized 795 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 796 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 797 /* 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, 798 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 799
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 800 double dotProduct = LSL_Vector.Dot(a, b);
801 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
802 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
803 double angle = Math.Acos(dotProduct / magProduct);
804 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
805 double s = Math.Sin(angle / 2);
806
807 double x = axis.x * s;
808 double y = axis.y * s;
809 double z = axis.z * s;
810 double w = Math.Cos(angle / 2);
811
812 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
813 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
814
815 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
816 */
817
818 // This method mimics the 180 errors found in SL
819 // See www.euclideanspace.com... angleBetween
820 LSL_Vector vec_a = a;
821 LSL_Vector vec_b = b;
822
823 // Eliminate zero length
824 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
825 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
826 if (vec_a_mag < 0.00001 ||
827 vec_b_mag < 0.00001)
709 { 828 {
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 829 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 } 830 }
712 else 831
832 // Normalize
833 vec_a = llVecNorm(vec_a);
834 vec_b = llVecNorm(vec_b);
835
836 // Calculate axis and rotation angle
837 LSL_Vector axis = vec_a % vec_b;
838 LSL_Float cos_theta = vec_a * vec_b;
839
840 // Check if parallel
841 if (cos_theta > 0.99999)
713 { 842 {
714 a = LSL_Vector.Norm(a); 843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 b = LSL_Vector.Norm(b); 844 }
716 double dotProduct = LSL_Vector.Dot(a, b); 845
717 // There are two degenerate cases possible. These are for vectors 180 or 846 // Check if anti-parallel
718 // 0 degrees apart. These have to be detected and handled individually. 847 else if (cos_theta < -0.99999)
719 // 848 {
720 // Check for vectors 180 degrees apart. 849 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. 850 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
722 if (dotProduct < -0.9999999f) 851 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
723 { 852 }
724 // First assume X axis is orthogonal to the vectors. 853 else // other rotation
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 854 {
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 855 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 856 axis = llVecNorm(axis);
728 // a rotation in an undesired direction. 857 double x, y, z, s, t;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 858 s = Math.Cos(theta);
730 { 859 t = Math.Sin(theta);
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 860 x = axis.x * t;
732 } 861 y = axis.y * t;
733 // If the magnitude of the vector was near zero, then assume the X axis is not 862 z = axis.z * t;
734 // orthogonal and use the Z axis instead. 863 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 } 864 }
773 return rotBetween;
774 } 865 }
775 866
776 public void llWhisper(int channelID, string text) 867 public void llWhisper(int channelID, string text)
777 { 868 {
778 m_host.AddScriptLPS(1); 869 m_host.AddScriptLPS(1);
@@ -1096,10 +1187,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1187 return detectedParams.TouchUV;
1097 } 1188 }
1098 1189
1190 [DebuggerNonUserCode]
1099 public virtual void llDie() 1191 public virtual void llDie()
1100 { 1192 {
1101 m_host.AddScriptLPS(1); 1193 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1194 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1195 }
1104 1196
1105 public LSL_Float llGround(LSL_Vector offset) 1197 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1264
1173 public void llSetStatus(int status, int value) 1265 public void llSetStatus(int status, int value)
1174 { 1266 {
1267 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1268 return;
1175 m_host.AddScriptLPS(1); 1269 m_host.AddScriptLPS(1);
1176 1270
1177 int statusrotationaxis = 0; 1271 int statusrotationaxis = 0;
@@ -1402,6 +1496,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1496 {
1403 m_host.AddScriptLPS(1); 1497 m_host.AddScriptLPS(1);
1404 1498
1499 SetColor(m_host, color, face);
1500 }
1501
1502 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1503 {
1504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1505 return;
1506
1507 Primitive.TextureEntry tex = part.Shape.Textures;
1508 Color4 texcolor;
1509 if (face >= 0 && face < GetNumberOfSides(part))
1510 {
1511 texcolor = tex.CreateFace((uint)face).RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[face].RGBA = texcolor;
1516 part.UpdateTexture(tex);
1517 return;
1518 }
1519 else if (face == ScriptBaseClass.ALL_SIDES)
1520 {
1521 for (uint i = 0; i < GetNumberOfSides(part); i++)
1522 {
1523 if (tex.FaceTextures[i] != null)
1524 {
1525 texcolor = tex.FaceTextures[i].RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[i].RGBA = texcolor;
1530 }
1531 texcolor = tex.DefaultTexture.RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.DefaultTexture.RGBA = texcolor;
1536 }
1537 part.UpdateTexture(tex);
1538 return;
1539 }
1540
1405 if (face == ScriptBaseClass.ALL_SIDES) 1541 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1542 face = SceneObjectPart.ALL_SIDES;
1407 1543
@@ -1410,6 +1546,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1546
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1547 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1548 {
1549 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1550 return;
1551
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1553 MappingType textype;
1415 textype = MappingType.Default; 1554 textype = MappingType.Default;
@@ -1440,6 +1579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1579
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1581 {
1582 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1583 return;
1584
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1585 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1586 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1587 {
@@ -1465,6 +1607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1607
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1608 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1468 1612
1469 Shininess sval = new Shininess(); 1613 Shininess sval = new Shininess();
1470 1614
@@ -1515,6 +1659,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1659
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1660 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1661 {
1662 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return;
1664
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1665 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1666 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1667 {
@@ -1575,13 +1722,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1722 m_host.AddScriptLPS(1);
1576 1723
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1724 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1725 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1726 {
1580 SetAlpha(part, alpha, face); 1727 try
1728 {
1729 parts[0].ParentGroup.areUpdatesSuspended = true;
1730 foreach (SceneObjectPart part in parts)
1731 SetAlpha(part, alpha, face);
1732 }
1733 finally
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = false;
1736 }
1737 }
1581 } 1738 }
1582 1739
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1740 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1741 {
1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1743 return;
1744
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1745 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1746 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1747 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1787 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1788 float wind, float tension, LSL_Vector Force)
1629 { 1789 {
1630 if (part == null) 1790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1791 return;
1632 1792
1633 if (flexi) 1793 if (flexi)
@@ -1662,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1822 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1823 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1824 {
1665 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1826 return;
1667 1827
1668 if (light) 1828 if (light)
@@ -1739,15 +1899,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1899 m_host.AddScriptLPS(1);
1740 1900
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1901 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1902 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1903 {
1744 SetTexture(part, texture, face); 1904 try
1745 1905 {
1906 parts[0].ParentGroup.areUpdatesSuspended = true;
1907 foreach (SceneObjectPart part in parts)
1908 SetTexture(part, texture, face);
1909 }
1910 finally
1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = false;
1913 }
1914 }
1746 ScriptSleep(200); 1915 ScriptSleep(200);
1747 } 1916 }
1748 1917
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1918 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1919 {
1920 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1921 return;
1922
1751 UUID textureID = new UUID(); 1923 UUID textureID = new UUID();
1752 1924
1753 textureID = InventoryKey(texture, (int)AssetType.Texture); 1925 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1792,6 +1964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1964
1793 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1965 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1794 { 1966 {
1967 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1968 return;
1969
1795 Primitive.TextureEntry tex = part.Shape.Textures; 1970 Primitive.TextureEntry tex = part.Shape.Textures;
1796 if (face >= 0 && face < GetNumberOfSides(part)) 1971 if (face >= 0 && face < GetNumberOfSides(part))
1797 { 1972 {
@@ -1828,6 +2003,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 2003
1829 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2004 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1830 { 2005 {
2006 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2007 return;
2008
1831 Primitive.TextureEntry tex = part.Shape.Textures; 2009 Primitive.TextureEntry tex = part.Shape.Textures;
1832 if (face >= 0 && face < GetNumberOfSides(part)) 2010 if (face >= 0 && face < GetNumberOfSides(part))
1833 { 2011 {
@@ -1864,6 +2042,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1864 2042
1865 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2043 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1866 { 2044 {
2045 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2046 return;
2047
1867 Primitive.TextureEntry tex = part.Shape.Textures; 2048 Primitive.TextureEntry tex = part.Shape.Textures;
1868 if (face >= 0 && face < GetNumberOfSides(part)) 2049 if (face >= 0 && face < GetNumberOfSides(part))
1869 { 2050 {
@@ -1932,10 +2113,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 return end; 2113 return end;
1933 } 2114 }
1934 2115
1935 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2116 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1936 { 2117 {
2118 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2119 return fromPos;
2120
1937 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2121 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1938 LSL_Vector currentPos = GetPartLocalPos(part); 2122
1939 2123
1940 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2124 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1941 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2125 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1944,14 +2128,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 { 2128 {
1945 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2129 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
1946 targetPos.z = ground; 2130 targetPos.z = ground;
2131 }
2132 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2133
2134 return real_vec;
2135 }
2136
2137 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2138 {
2139 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2140 return;
2141
2142 LSL_Vector currentPos = GetPartLocalPos(part);
2143 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2144
2145 if (part.ParentGroup.RootPart == part)
2146 {
1947 SceneObjectGroup parent = part.ParentGroup; 2147 SceneObjectGroup parent = part.ParentGroup;
1948 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2148 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 } 2149 }
1951 else 2150 else
1952 { 2151 {
1953 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2152 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; 2153 SceneObjectGroup parent = part.ParentGroup;
1956 parent.HasGroupChanged = true; 2154 parent.HasGroupChanged = true;
1957 parent.ScheduleGroupForTerseUpdate(); 2155 parent.ScheduleGroupForTerseUpdate();
@@ -2002,9 +2200,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 m_host.AddScriptLPS(1); 2200 m_host.AddScriptLPS(1);
2003 2201
2004 // try to let this work as in SL... 2202 // try to let this work as in SL...
2005 if (m_host.ParentID == 0) 2203 if (m_host.LinkNum < 2)
2006 { 2204 {
2007 // special case: If we are root, rotate complete SOG to new rotation 2205 // Special case: If we are root, rotate complete SOG to new
2206 // rotation.
2207 // We are root if the link number is 0 (single prim) or 1
2208 // (root prim). ParentID may be nonzero in attachments and
2209 // using it would cause attachments and HUDs to rotate
2210 // to the wrong positions.
2008 SetRot(m_host, Rot2Quaternion(rot)); 2211 SetRot(m_host, Rot2Quaternion(rot));
2009 } 2212 }
2010 else 2213 else
@@ -2033,6 +2236,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2033 2236
2034 protected void SetRot(SceneObjectPart part, Quaternion rot) 2237 protected void SetRot(SceneObjectPart part, Quaternion rot)
2035 { 2238 {
2239 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2240 return;
2241
2036 part.UpdateRotation(rot); 2242 part.UpdateRotation(rot);
2037 // Update rotation does not move the object in the physics scene if it's a linkset. 2243 // Update rotation does not move the object in the physics scene if it's a linkset.
2038 2244
@@ -2652,12 +2858,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 2858
2653 m_host.AddScriptLPS(1); 2859 m_host.AddScriptLPS(1);
2654 2860
2861 m_host.TaskInventory.LockItemsForRead(true);
2655 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2862 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2656 2863 m_host.TaskInventory.LockItemsForRead(false);
2657 lock (m_host.TaskInventory)
2658 {
2659 item = m_host.TaskInventory[invItemID];
2660 }
2661 2864
2662 if (item.PermsGranter == UUID.Zero) 2865 if (item.PermsGranter == UUID.Zero)
2663 return 0; 2866 return 0;
@@ -2732,6 +2935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 if (dist > m_ScriptDistanceFactor * 10.0f) 2935 if (dist > m_ScriptDistanceFactor * 10.0f)
2733 return; 2936 return;
2734 2937
2938 //Clone is thread-safe
2735 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2939 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2736 2940
2737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2941 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2794,6 +2998,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 2998
2795 public void llLookAt(LSL_Vector target, double strength, double damping) 2999 public void llLookAt(LSL_Vector target, double strength, double damping)
2796 { 3000 {
3001 /*
2797 m_host.AddScriptLPS(1); 3002 m_host.AddScriptLPS(1);
2798 // Determine where we are looking from 3003 // Determine where we are looking from
2799 LSL_Vector from = llGetPos(); 3004 LSL_Vector from = llGetPos();
@@ -2813,10 +3018,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 // the angles of rotation in radians into rotation value 3018 // the angles of rotation in radians into rotation value
2814 3019
2815 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3020 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2816 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3021
2817 m_host.startLookAt(rotation, (float)damping, (float)strength); 3022 // This would only work if your physics system contains an APID controller:
3023 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3024 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3025
2818 // Orient the object to the angle calculated 3026 // Orient the object to the angle calculated
2819 //llSetRot(rot); 3027 llSetRot(rot);
3028 */
3029
3030 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3031 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3032 // http://bugs.meta7.com/view.php?id=28
3033 // - Tom
3034
3035 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3036 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3037 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3038 */
3039 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3040 {
3041 // Part is non-phys, convert this to a llSetRot()
3042 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3043 Vector3 dir = tgt - m_host.GroupPosition;
3044 dir.Normalize();
3045 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3046 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3047 float terot = (float)Math.Atan2(-dir.Z, txy);
3048 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3049 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3050 LSL_Types.Quaternion spin = llEuler2Rot(az);
3051 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3052 llSetRot(rot);
3053 }
3054 else
3055 {
3056 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3057 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3058 m_host.RotLookAt(q, (float)strength, (float)damping);
3059 }
3060
3061 }
3062
3063 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3064 {
3065 m_host.AddScriptLPS(1);
3066// NotImplemented("llRotLookAt");
3067 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3068
2820 } 3069 }
2821 3070
2822 public void llStopLookAt() 3071 public void llStopLookAt()
@@ -2865,13 +3114,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 { 3114 {
2866 TaskInventoryItem item; 3115 TaskInventoryItem item;
2867 3116
2868 lock (m_host.TaskInventory) 3117 m_host.TaskInventory.LockItemsForRead(true);
3118 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2869 { 3119 {
2870 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3120 m_host.TaskInventory.LockItemsForRead(false);
2871 return; 3121 return;
2872 else 3122 }
2873 item = m_host.TaskInventory[InventorySelf()]; 3123 else
3124 {
3125 item = m_host.TaskInventory[InventorySelf()];
2874 } 3126 }
3127 m_host.TaskInventory.LockItemsForRead(false);
2875 3128
2876 if (item.PermsGranter != UUID.Zero) 3129 if (item.PermsGranter != UUID.Zero)
2877 { 3130 {
@@ -2893,13 +3146,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2893 { 3146 {
2894 TaskInventoryItem item; 3147 TaskInventoryItem item;
2895 3148
3149 m_host.TaskInventory.LockItemsForRead(true);
2896 lock (m_host.TaskInventory) 3150 lock (m_host.TaskInventory)
2897 { 3151 {
3152
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3153 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3154 {
3155 m_host.TaskInventory.LockItemsForRead(false);
2899 return; 3156 return;
3157 }
2900 else 3158 else
3159 {
2901 item = m_host.TaskInventory[InventorySelf()]; 3160 item = m_host.TaskInventory[InventorySelf()];
3161 }
2902 } 3162 }
3163 m_host.TaskInventory.LockItemsForRead(false);
2903 3164
2904 m_host.AddScriptLPS(1); 3165 m_host.AddScriptLPS(1);
2905 3166
@@ -2931,18 +3192,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2931 { 3192 {
2932 m_host.AddScriptLPS(1); 3193 m_host.AddScriptLPS(1);
2933 3194
2934 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2935 return;
2936
2937 TaskInventoryItem item; 3195 TaskInventoryItem item;
2938 3196
2939 lock (m_host.TaskInventory) 3197 m_host.TaskInventory.LockItemsForRead(true);
3198
3199 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2940 { 3200 {
2941 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3201 m_host.TaskInventory.LockItemsForRead(false);
2942 return; 3202 return;
2943 else
2944 item = m_host.TaskInventory[InventorySelf()];
2945 } 3203 }
3204 else
3205 {
3206 item = m_host.TaskInventory[InventorySelf()];
3207 }
3208
3209 m_host.TaskInventory.LockItemsForRead(false);
2946 3210
2947 if (item.PermsGranter != m_host.OwnerID) 3211 if (item.PermsGranter != m_host.OwnerID)
2948 return; 3212 return;
@@ -2953,10 +3217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 3217
2954 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3218 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2955 3219
2956 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3220 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 } 3221 }
2961 } 3222 }
2962 3223
@@ -2969,13 +3230,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2969 3230
2970 TaskInventoryItem item; 3231 TaskInventoryItem item;
2971 3232
2972 lock (m_host.TaskInventory) 3233 m_host.TaskInventory.LockItemsForRead(true);
3234
3235 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2973 { 3236 {
2974 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3237 m_host.TaskInventory.LockItemsForRead(false);
2975 return; 3238 return;
2976 else 3239 }
2977 item = m_host.TaskInventory[InventorySelf()]; 3240 else
3241 {
3242 item = m_host.TaskInventory[InventorySelf()];
2978 } 3243 }
3244 m_host.TaskInventory.LockItemsForRead(false);
3245
2979 3246
2980 if (item.PermsGranter != m_host.OwnerID) 3247 if (item.PermsGranter != m_host.OwnerID)
2981 return; 3248 return;
@@ -3022,6 +3289,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3289
3023 public void llInstantMessage(string user, string message) 3290 public void llInstantMessage(string user, string message)
3024 { 3291 {
3292 UUID result;
3293 if (!UUID.TryParse(user, out result))
3294 {
3295 ShoutError("An invalid key was passed to llInstantMessage");
3296 ScriptSleep(2000);
3297 return;
3298 }
3299
3300
3025 m_host.AddScriptLPS(1); 3301 m_host.AddScriptLPS(1);
3026 3302
3027 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3303 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3036,14 +3312,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 UUID friendTransactionID = UUID.Random(); 3312 UUID friendTransactionID = UUID.Random();
3037 3313
3038 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3314 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3039 3315
3040 GridInstantMessage msg = new GridInstantMessage(); 3316 GridInstantMessage msg = new GridInstantMessage();
3041 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3317 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3042 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3318 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3043 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3319 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); 3320// 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()); 3321// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3046 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3322// DateTime dt = DateTime.UtcNow;
3323//
3324// // Ticks from UtcNow, but make it look like local. Evil, huh?
3325// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3326//
3327// try
3328// {
3329// // Convert that to the PST timezone
3330// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3331// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3332// }
3333// catch
3334// {
3335// // No logging here, as it could be VERY spammy
3336// }
3337//
3338// // And make it look local again to fool the unix time util
3339// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3340
3341 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3342
3047 //if (client != null) 3343 //if (client != null)
3048 //{ 3344 //{
3049 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3345 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3057,12 +3353,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 msg.message = message.Substring(0, 1024); 3353 msg.message = message.Substring(0, 1024);
3058 else 3354 else
3059 msg.message = message; 3355 msg.message = message;
3060 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3356 msg.dialog = (byte)19; // MessageFromObject
3061 msg.fromGroup = false;// fromGroup; 3357 msg.fromGroup = false;// fromGroup;
3062 msg.offline = (byte)0; //offline; 3358 msg.offline = (byte)0; //offline;
3063 msg.ParentEstateID = 0; //ParentEstateID; 3359 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3064 msg.Position = new Vector3(m_host.AbsolutePosition); 3360 msg.Position = new Vector3(m_host.AbsolutePosition);
3065 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3361 msg.RegionID = World.RegionInfo.RegionID.Guid;
3066 msg.binaryBucket 3362 msg.binaryBucket
3067 = Util.StringToBytes256( 3363 = Util.StringToBytes256(
3068 "{0}/{1}/{2}/{3}", 3364 "{0}/{1}/{2}/{3}",
@@ -3090,7 +3386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3386 }
3091 3387
3092 emailModule.SendEmail(m_host.UUID, address, subject, message); 3388 emailModule.SendEmail(m_host.UUID, address, subject, message);
3093 ScriptSleep(20000); 3389 ScriptSleep(15000);
3094 } 3390 }
3095 3391
3096 public void llGetNextEmail(string address, string subject) 3392 public void llGetNextEmail(string address, string subject)
@@ -3192,13 +3488,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 m_host.AddScriptLPS(1); 3488 m_host.AddScriptLPS(1);
3193 } 3489 }
3194 3490
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) 3491 public LSL_Integer llStringLength(string str)
3203 { 3492 {
3204 m_host.AddScriptLPS(1); 3493 m_host.AddScriptLPS(1);
@@ -3222,14 +3511,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3222 3511
3223 TaskInventoryItem item; 3512 TaskInventoryItem item;
3224 3513
3225 lock (m_host.TaskInventory) 3514 m_host.TaskInventory.LockItemsForRead(true);
3515 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 { 3516 {
3227 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3517 m_host.TaskInventory.LockItemsForRead(false);
3228 return; 3518 return;
3229 else
3230 item = m_host.TaskInventory[InventorySelf()];
3231 } 3519 }
3232 3520 else
3521 {
3522 item = m_host.TaskInventory[InventorySelf()];
3523 }
3524 m_host.TaskInventory.LockItemsForRead(false);
3233 if (item.PermsGranter == UUID.Zero) 3525 if (item.PermsGranter == UUID.Zero)
3234 return; 3526 return;
3235 3527
@@ -3259,13 +3551,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3259 3551
3260 TaskInventoryItem item; 3552 TaskInventoryItem item;
3261 3553
3262 lock (m_host.TaskInventory) 3554 m_host.TaskInventory.LockItemsForRead(true);
3555 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3263 { 3556 {
3264 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3557 m_host.TaskInventory.LockItemsForRead(false);
3265 return; 3558 return;
3266 else
3267 item = m_host.TaskInventory[InventorySelf()];
3268 } 3559 }
3560 else
3561 {
3562 item = m_host.TaskInventory[InventorySelf()];
3563 }
3564 m_host.TaskInventory.LockItemsForRead(false);
3565
3269 3566
3270 if (item.PermsGranter == UUID.Zero) 3567 if (item.PermsGranter == UUID.Zero)
3271 return; 3568 return;
@@ -3336,10 +3633,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 3633
3337 TaskInventoryItem item; 3634 TaskInventoryItem item;
3338 3635
3339 lock (m_host.TaskInventory) 3636
3637 m_host.TaskInventory.LockItemsForRead(true);
3638 if (!m_host.TaskInventory.ContainsKey(invItemID))
3639 {
3640 m_host.TaskInventory.LockItemsForRead(false);
3641 return;
3642 }
3643 else
3340 { 3644 {
3341 item = m_host.TaskInventory[invItemID]; 3645 item = m_host.TaskInventory[invItemID];
3342 } 3646 }
3647 m_host.TaskInventory.LockItemsForRead(false);
3343 3648
3344 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3649 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3345 { 3650 {
@@ -3367,15 +3672,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3367 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3672 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3368 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3673 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3369 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3674 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3675 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3370 ScriptBaseClass.PERMISSION_ATTACH; 3676 ScriptBaseClass.PERMISSION_ATTACH;
3371 3677
3372 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3678 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3373 { 3679 {
3374 lock (m_host.TaskInventory) 3680 m_host.TaskInventory.LockItemsForWrite(true);
3375 { 3681 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3376 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3682 m_host.TaskInventory[invItemID].PermsMask = perm;
3377 m_host.TaskInventory[invItemID].PermsMask = perm; 3683 m_host.TaskInventory.LockItemsForWrite(false);
3378 }
3379 3684
3380 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3685 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3381 "run_time_permissions", new Object[] { 3686 "run_time_permissions", new Object[] {
@@ -3395,11 +3700,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3395 3700
3396 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3701 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3397 { 3702 {
3398 lock (m_host.TaskInventory) 3703 m_host.TaskInventory.LockItemsForWrite(true);
3399 { 3704 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3400 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3705 m_host.TaskInventory[invItemID].PermsMask = perm;
3401 m_host.TaskInventory[invItemID].PermsMask = perm; 3706 m_host.TaskInventory.LockItemsForWrite(false);
3402 }
3403 3707
3404 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3708 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3405 "run_time_permissions", new Object[] { 3709 "run_time_permissions", new Object[] {
@@ -3420,11 +3724,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 3724
3421 if (!m_waitingForScriptAnswer) 3725 if (!m_waitingForScriptAnswer)
3422 { 3726 {
3423 lock (m_host.TaskInventory) 3727 m_host.TaskInventory.LockItemsForWrite(true);
3424 { 3728 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3425 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3729 m_host.TaskInventory[invItemID].PermsMask = 0;
3426 m_host.TaskInventory[invItemID].PermsMask = 0; 3730 m_host.TaskInventory.LockItemsForWrite(false);
3427 }
3428 3731
3429 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3732 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3430 m_waitingForScriptAnswer=true; 3733 m_waitingForScriptAnswer=true;
@@ -3459,10 +3762,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3459 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3762 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3460 llReleaseControls(); 3763 llReleaseControls();
3461 3764
3462 lock (m_host.TaskInventory) 3765
3463 { 3766 m_host.TaskInventory.LockItemsForWrite(true);
3464 m_host.TaskInventory[invItemID].PermsMask = answer; 3767 m_host.TaskInventory[invItemID].PermsMask = answer;
3465 } 3768 m_host.TaskInventory.LockItemsForWrite(false);
3769
3466 3770
3467 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3771 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3468 "run_time_permissions", new Object[] { 3772 "run_time_permissions", new Object[] {
@@ -3474,16 +3778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3474 { 3778 {
3475 m_host.AddScriptLPS(1); 3779 m_host.AddScriptLPS(1);
3476 3780
3477 lock (m_host.TaskInventory) 3781 m_host.TaskInventory.LockItemsForRead(true);
3782
3783 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3478 { 3784 {
3479 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3785 if (item.Type == 10 && item.ItemID == m_itemID)
3480 { 3786 {
3481 if (item.Type == 10 && item.ItemID == m_itemID) 3787 m_host.TaskInventory.LockItemsForRead(false);
3482 { 3788 return item.PermsGranter.ToString();
3483 return item.PermsGranter.ToString();
3484 }
3485 } 3789 }
3486 } 3790 }
3791 m_host.TaskInventory.LockItemsForRead(false);
3487 3792
3488 return UUID.Zero.ToString(); 3793 return UUID.Zero.ToString();
3489 } 3794 }
@@ -3492,19 +3797,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 { 3797 {
3493 m_host.AddScriptLPS(1); 3798 m_host.AddScriptLPS(1);
3494 3799
3495 lock (m_host.TaskInventory) 3800 m_host.TaskInventory.LockItemsForRead(true);
3801
3802 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3496 { 3803 {
3497 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3804 if (item.Type == 10 && item.ItemID == m_itemID)
3498 { 3805 {
3499 if (item.Type == 10 && item.ItemID == m_itemID) 3806 int perms = item.PermsMask;
3500 { 3807 if (m_automaticLinkPermission)
3501 int perms = item.PermsMask; 3808 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3502 if (m_automaticLinkPermission) 3809 m_host.TaskInventory.LockItemsForRead(false);
3503 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3810 return perms;
3504 return perms;
3505 }
3506 } 3811 }
3507 } 3812 }
3813 m_host.TaskInventory.LockItemsForRead(false);
3508 3814
3509 return 0; 3815 return 0;
3510 } 3816 }
@@ -3526,9 +3832,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3832 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3527 { 3833 {
3528 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3834 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3529 3835 if (parts.Count > 0)
3530 foreach (SceneObjectPart part in parts) 3836 {
3531 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3837 try
3838 {
3839 parts[0].ParentGroup.areUpdatesSuspended = true;
3840 foreach (SceneObjectPart part in parts)
3841 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3842 }
3843 finally
3844 {
3845 parts[0].ParentGroup.areUpdatesSuspended = false;
3846 }
3847 }
3532 } 3848 }
3533 3849
3534 public void llCreateLink(string target, int parent) 3850 public void llCreateLink(string target, int parent)
@@ -3541,11 +3857,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3541 return; 3857 return;
3542 3858
3543 TaskInventoryItem item; 3859 TaskInventoryItem item;
3544 lock (m_host.TaskInventory) 3860 m_host.TaskInventory.LockItemsForRead(true);
3545 { 3861 item = m_host.TaskInventory[invItemID];
3546 item = m_host.TaskInventory[invItemID]; 3862 m_host.TaskInventory.LockItemsForRead(false);
3547 } 3863
3548
3549 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3864 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3550 && !m_automaticLinkPermission) 3865 && !m_automaticLinkPermission)
3551 { 3866 {
@@ -3566,7 +3881,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3566 3881
3567 if (targetPart != null) 3882 if (targetPart != null)
3568 { 3883 {
3569 if (parent != 0) { 3884 if (parent != 0)
3885 {
3570 parentPrim = m_host.ParentGroup; 3886 parentPrim = m_host.ParentGroup;
3571 childPrim = targetPart.ParentGroup; 3887 childPrim = targetPart.ParentGroup;
3572 } 3888 }
@@ -3598,16 +3914,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3598 m_host.AddScriptLPS(1); 3914 m_host.AddScriptLPS(1);
3599 UUID invItemID = InventorySelf(); 3915 UUID invItemID = InventorySelf();
3600 3916
3601 lock (m_host.TaskInventory) 3917 m_host.TaskInventory.LockItemsForRead(true);
3602 {
3603 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3918 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3604 && !m_automaticLinkPermission) 3919 && !m_automaticLinkPermission)
3605 { 3920 {
3606 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3921 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3922 m_host.TaskInventory.LockItemsForRead(false);
3607 return; 3923 return;
3608 } 3924 }
3609 } 3925 m_host.TaskInventory.LockItemsForRead(false);
3610 3926
3611 if (linknum < ScriptBaseClass.LINK_THIS) 3927 if (linknum < ScriptBaseClass.LINK_THIS)
3612 return; 3928 return;
3613 3929
@@ -3646,10 +3962,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 // Restructuring Multiple Prims. 3962 // Restructuring Multiple Prims.
3647 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3963 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3648 parts.Remove(parentPrim.RootPart); 3964 parts.Remove(parentPrim.RootPart);
3649 foreach (SceneObjectPart part in parts) 3965 if (parts.Count > 0)
3650 { 3966 {
3651 parentPrim.DelinkFromGroup(part.LocalId, true); 3967 try
3968 {
3969 parts[0].ParentGroup.areUpdatesSuspended = true;
3970 foreach (SceneObjectPart part in parts)
3971 {
3972 parentPrim.DelinkFromGroup(part.LocalId, true);
3973 }
3974 }
3975 finally
3976 {
3977 parts[0].ParentGroup.areUpdatesSuspended = false;
3978 }
3652 } 3979 }
3980
3653 parentPrim.HasGroupChanged = true; 3981 parentPrim.HasGroupChanged = true;
3654 parentPrim.ScheduleGroupForFullUpdate(); 3982 parentPrim.ScheduleGroupForFullUpdate();
3655 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3983 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3658,11 +3986,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3658 { 3986 {
3659 SceneObjectPart newRoot = parts[0]; 3987 SceneObjectPart newRoot = parts[0];
3660 parts.Remove(newRoot); 3988 parts.Remove(newRoot);
3661 foreach (SceneObjectPart part in parts) 3989
3990 try
3662 { 3991 {
3663 part.UpdateFlag = 0; 3992 parts[0].ParentGroup.areUpdatesSuspended = true;
3664 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3993 foreach (SceneObjectPart part in parts)
3994 {
3995 part.UpdateFlag = 0;
3996 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3997 }
3665 } 3998 }
3999 finally
4000 {
4001 parts[0].ParentGroup.areUpdatesSuspended = false;
4002 }
4003
4004
3666 newRoot.ParentGroup.HasGroupChanged = true; 4005 newRoot.ParentGroup.HasGroupChanged = true;
3667 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4006 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3668 } 4007 }
@@ -3708,6 +4047,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3708 } 4047 }
3709 else 4048 else
3710 { 4049 {
4050 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4051 {
4052 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4053
4054 if (linknum < 0)
4055 return UUID.Zero.ToString();
4056
4057 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4058 if (avatars.Count > linknum)
4059 {
4060 return avatars[linknum].UUID.ToString();
4061 }
4062 }
3711 return UUID.Zero.ToString(); 4063 return UUID.Zero.ToString();
3712 } 4064 }
3713 } 4065 }
@@ -3784,17 +4136,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3784 m_host.AddScriptLPS(1); 4136 m_host.AddScriptLPS(1);
3785 int count = 0; 4137 int count = 0;
3786 4138
3787 lock (m_host.TaskInventory) 4139 m_host.TaskInventory.LockItemsForRead(true);
4140 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3788 { 4141 {
3789 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4142 if (inv.Value.Type == type || type == -1)
3790 { 4143 {
3791 if (inv.Value.Type == type || type == -1) 4144 count = count + 1;
3792 {
3793 count = count + 1;
3794 }
3795 } 4145 }
3796 } 4146 }
3797 4147
4148 m_host.TaskInventory.LockItemsForRead(false);
3798 return count; 4149 return count;
3799 } 4150 }
3800 4151
@@ -3803,16 +4154,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3803 m_host.AddScriptLPS(1); 4154 m_host.AddScriptLPS(1);
3804 ArrayList keys = new ArrayList(); 4155 ArrayList keys = new ArrayList();
3805 4156
3806 lock (m_host.TaskInventory) 4157 m_host.TaskInventory.LockItemsForRead(true);
4158 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3807 { 4159 {
3808 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4160 if (inv.Value.Type == type || type == -1)
3809 { 4161 {
3810 if (inv.Value.Type == type || type == -1) 4162 keys.Add(inv.Value.Name);
3811 {
3812 keys.Add(inv.Value.Name);
3813 }
3814 } 4163 }
3815 } 4164 }
4165 m_host.TaskInventory.LockItemsForRead(false);
3816 4166
3817 if (keys.Count == 0) 4167 if (keys.Count == 0)
3818 { 4168 {
@@ -3849,30 +4199,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3849 } 4199 }
3850 4200
3851 // move the first object found with this inventory name 4201 // move the first object found with this inventory name
3852 lock (m_host.TaskInventory) 4202 m_host.TaskInventory.LockItemsForRead(true);
4203 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3853 { 4204 {
3854 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4205 if (inv.Value.Name == inventory)
3855 { 4206 {
3856 if (inv.Value.Name == inventory) 4207 found = true;
3857 { 4208 objId = inv.Key;
3858 found = true; 4209 assetType = inv.Value.Type;
3859 objId = inv.Key; 4210 objName = inv.Value.Name;
3860 assetType = inv.Value.Type; 4211 break;
3861 objName = inv.Value.Name;
3862 break;
3863 }
3864 } 4212 }
3865 } 4213 }
4214 m_host.TaskInventory.LockItemsForRead(false);
3866 4215
3867 if (!found) 4216 if (!found)
3868 { 4217 {
3869 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4218 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)); 4219 return;
4220// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3871 } 4221 }
3872 4222
3873 // check if destination is an avatar 4223 // check if destination is an object
3874 if (World.GetScenePresence(destId) != null) 4224 if (World.GetSceneObjectPart(destId) != null)
3875 { 4225 {
4226 // destination is an object
4227 World.MoveTaskInventoryItem(destId, m_host, objId);
4228 }
4229 else
4230 {
4231 ScenePresence presence = World.GetScenePresence(destId);
4232
4233 if (presence == null)
4234 {
4235 UserAccount account =
4236 World.UserAccountService.GetUserAccount(
4237 World.RegionInfo.ScopeID,
4238 destId);
4239
4240 if (account == null)
4241 {
4242 llSay(0, "Can't find destination "+destId.ToString());
4243 return;
4244 }
4245 }
4246
3876 // destination is an avatar 4247 // destination is an avatar
3877 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4248 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3878 4249
@@ -3896,31 +4267,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 4267
3897 if (m_TransferModule != null) 4268 if (m_TransferModule != null)
3898 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4269 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4270
4271 //This delay should only occur when giving inventory to avatars.
4272 ScriptSleep(3000);
3899 } 4273 }
3900 else
3901 {
3902 // destination is an object
3903 World.MoveTaskInventoryItem(destId, m_host, objId);
3904 }
3905 ScriptSleep(3000);
3906 } 4274 }
3907 4275
4276 [DebuggerNonUserCode]
3908 public void llRemoveInventory(string name) 4277 public void llRemoveInventory(string name)
3909 { 4278 {
3910 m_host.AddScriptLPS(1); 4279 m_host.AddScriptLPS(1);
3911 4280
3912 lock (m_host.TaskInventory) 4281 List<TaskInventoryItem> inv;
4282 try
3913 { 4283 {
3914 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4284 m_host.TaskInventory.LockItemsForRead(true);
4285 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4286 }
4287 finally
4288 {
4289 m_host.TaskInventory.LockItemsForRead(false);
4290 }
4291 foreach (TaskInventoryItem item in inv)
4292 {
4293 if (item.Name == name)
3915 { 4294 {
3916 if (item.Name == name) 4295 if (item.ItemID == m_itemID)
3917 { 4296 throw new ScriptDeleteException();
3918 if (item.ItemID == m_itemID) 4297 else
3919 throw new ScriptDeleteException(); 4298 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3920 else 4299 return;
3921 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3922 return;
3923 }
3924 } 4300 }
3925 } 4301 }
3926 } 4302 }
@@ -3955,112 +4331,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 { 4331 {
3956 m_host.AddScriptLPS(1); 4332 m_host.AddScriptLPS(1);
3957 4333
3958 UUID uuid = (UUID)id; 4334 UUID uuid;
3959 PresenceInfo pinfo = null; 4335 if (UUID.TryParse(id, out uuid))
3960 UserAccount account;
3961
3962 UserInfoCacheEntry ce;
3963 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3964 { 4336 {
3965 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4337 PresenceInfo pinfo = null;
3966 if (account == null) 4338 UserAccount account;
4339
4340 UserInfoCacheEntry ce;
4341 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3967 { 4342 {
3968 m_userInfoCache[uuid] = null; // Cache negative 4343 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3969 return UUID.Zero.ToString(); 4344 if (account == null)
3970 } 4345 {
4346 m_userInfoCache[uuid] = null; // Cache negative
4347 return UUID.Zero.ToString();
4348 }
3971 4349
3972 4350
3973 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4351 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3974 if (pinfos != null && pinfos.Length > 0) 4352 if (pinfos != null && pinfos.Length > 0)
3975 {
3976 foreach (PresenceInfo p in pinfos)
3977 { 4353 {
3978 if (p.RegionID != UUID.Zero) 4354 foreach (PresenceInfo p in pinfos)
3979 { 4355 {
3980 pinfo = p; 4356 if (p.RegionID != UUID.Zero)
4357 {
4358 pinfo = p;
4359 }
3981 } 4360 }
3982 } 4361 }
3983 }
3984 4362
3985 ce = new UserInfoCacheEntry(); 4363 ce = new UserInfoCacheEntry();
3986 ce.time = Util.EnvironmentTickCount(); 4364 ce.time = Util.EnvironmentTickCount();
3987 ce.account = account; 4365 ce.account = account;
3988 ce.pinfo = pinfo; 4366 ce.pinfo = pinfo;
3989 } 4367 m_userInfoCache[uuid] = ce;
3990 else 4368 }
3991 { 4369 else
3992 if (ce == null) 4370 {
3993 return UUID.Zero.ToString(); 4371 if (ce == null)
4372 return UUID.Zero.ToString();
3994 4373
3995 account = ce.account; 4374 account = ce.account;
3996 pinfo = ce.pinfo; 4375 pinfo = ce.pinfo;
3997 } 4376 }
3998 4377
3999 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4378 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 { 4379 {
4004 foreach (PresenceInfo p in pinfos) 4380 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4381 if (pinfos != null && pinfos.Length > 0)
4005 { 4382 {
4006 if (p.RegionID != UUID.Zero) 4383 foreach (PresenceInfo p in pinfos)
4007 { 4384 {
4008 pinfo = p; 4385 if (p.RegionID != UUID.Zero)
4386 {
4387 pinfo = p;
4388 }
4009 } 4389 }
4010 } 4390 }
4011 } 4391 else
4012 else 4392 pinfo = null;
4013 pinfo = null;
4014 4393
4015 ce.time = Util.EnvironmentTickCount(); 4394 ce.time = Util.EnvironmentTickCount();
4016 ce.pinfo = pinfo; 4395 ce.pinfo = pinfo;
4017 } 4396 }
4018 4397
4019 string reply = String.Empty; 4398 string reply = String.Empty;
4020 4399
4021 switch (data) 4400 switch (data)
4022 { 4401 {
4023 case 1: // DATA_ONLINE (0|1) 4402 case 1: // DATA_ONLINE (0|1)
4024 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4403 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4025 reply = "1"; 4404 reply = "1";
4026 else 4405 else
4027 reply = "0"; 4406 reply = "0";
4028 break; 4407 break;
4029 case 2: // DATA_NAME (First Last) 4408 case 2: // DATA_NAME (First Last)
4030 reply = account.FirstName + " " + account.LastName; 4409 reply = account.FirstName + " " + account.LastName;
4031 break; 4410 break;
4032 case 3: // DATA_BORN (YYYY-MM-DD) 4411 case 3: // DATA_BORN (YYYY-MM-DD)
4033 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4412 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4034 born = born.AddSeconds(account.Created); 4413 born = born.AddSeconds(account.Created);
4035 reply = born.ToString("yyyy-MM-dd"); 4414 reply = born.ToString("yyyy-MM-dd");
4036 break; 4415 break;
4037 case 4: // DATA_RATING (0,0,0,0,0,0) 4416 case 4: // DATA_RATING (0,0,0,0,0,0)
4038 reply = "0,0,0,0,0,0"; 4417 reply = "0,0,0,0,0,0";
4039 break; 4418 break;
4040 case 8: // DATA_PAYINFO (0|1|2|3) 4419 case 8: // DATA_PAYINFO (0|1|2|3)
4041 reply = "0"; 4420 reply = "0";
4042 break; 4421 break;
4043 default: 4422 default:
4044 return UUID.Zero.ToString(); // Raise no event 4423 return UUID.Zero.ToString(); // Raise no event
4045 } 4424 }
4046 4425
4047 UUID rq = UUID.Random(); 4426 UUID rq = UUID.Random();
4048 4427
4049 UUID tid = AsyncCommands. 4428 UUID tid = AsyncCommands.
4050 DataserverPlugin.RegisterRequest(m_localID, 4429 DataserverPlugin.RegisterRequest(m_localID,
4051 m_itemID, rq.ToString()); 4430 m_itemID, rq.ToString());
4052 4431
4053 AsyncCommands. 4432 AsyncCommands.
4054 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4433 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4055 4434
4056 ScriptSleep(100); 4435 ScriptSleep(100);
4057 return tid.ToString(); 4436 return tid.ToString();
4437 }
4438 else
4439 {
4440 ShoutError("Invalid UUID passed to llRequestAgentData.");
4441 }
4442 return "";
4058 } 4443 }
4059 4444
4060 public LSL_String llRequestInventoryData(string name) 4445 public LSL_String llRequestInventoryData(string name)
4061 { 4446 {
4062 m_host.AddScriptLPS(1); 4447 m_host.AddScriptLPS(1);
4063 4448
4449 //Clone is thread safe
4064 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4450 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4065 4451
4066 foreach (TaskInventoryItem item in itemDictionary.Values) 4452 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4114,6 +4500,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4114 ScenePresence presence = World.GetScenePresence(agentId); 4500 ScenePresence presence = World.GetScenePresence(agentId);
4115 if (presence != null) 4501 if (presence != null)
4116 { 4502 {
4503 // agent must not be a god
4504 if (presence.UserLevel >= 200) return;
4505
4117 // agent must be over the owners land 4506 // agent must be over the owners land
4118 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4507 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4119 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4508 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4136,7 +4525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4136 UUID av = new UUID(); 4525 UUID av = new UUID();
4137 if (!UUID.TryParse(agent,out av)) 4526 if (!UUID.TryParse(agent,out av))
4138 { 4527 {
4139 LSLError("First parameter to llDialog needs to be a key"); 4528 //LSLError("First parameter to llDialog needs to be a key");
4140 return; 4529 return;
4141 } 4530 }
4142 4531
@@ -4173,17 +4562,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 UUID soundId = UUID.Zero; 4562 UUID soundId = UUID.Zero;
4174 if (!UUID.TryParse(impact_sound, out soundId)) 4563 if (!UUID.TryParse(impact_sound, out soundId))
4175 { 4564 {
4176 lock (m_host.TaskInventory) 4565 m_host.TaskInventory.LockItemsForRead(true);
4566 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4177 { 4567 {
4178 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4568 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4179 { 4569 {
4180 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4570 soundId = item.AssetID;
4181 { 4571 break;
4182 soundId = item.AssetID;
4183 break;
4184 }
4185 } 4572 }
4186 } 4573 }
4574 m_host.TaskInventory.LockItemsForRead(false);
4187 } 4575 }
4188 m_host.CollisionSound = soundId; 4576 m_host.CollisionSound = soundId;
4189 m_host.CollisionSoundVolume = (float)impact_volume; 4577 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4229,6 +4617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 UUID partItemID; 4617 UUID partItemID;
4230 foreach (SceneObjectPart part in parts) 4618 foreach (SceneObjectPart part in parts)
4231 { 4619 {
4620 //Clone is thread safe
4232 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4621 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4233 4622
4234 foreach (TaskInventoryItem item in itemsDictionary.Values) 4623 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4443,17 +4832,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4443 4832
4444 m_host.AddScriptLPS(1); 4833 m_host.AddScriptLPS(1);
4445 4834
4446 lock (m_host.TaskInventory) 4835 m_host.TaskInventory.LockItemsForRead(true);
4836 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4447 { 4837 {
4448 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4838 if (item.Type == 10 && item.ItemID == m_itemID)
4449 { 4839 {
4450 if (item.Type == 10 && item.ItemID == m_itemID) 4840 result = item.Name!=null?item.Name:String.Empty;
4451 { 4841 break;
4452 result = item.Name != null ? item.Name : String.Empty;
4453 break;
4454 }
4455 } 4842 }
4456 } 4843 }
4844 m_host.TaskInventory.LockItemsForRead(false);
4457 4845
4458 return result; 4846 return result;
4459 } 4847 }
@@ -4606,23 +4994,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4606 { 4994 {
4607 m_host.AddScriptLPS(1); 4995 m_host.AddScriptLPS(1);
4608 4996
4609 lock (m_host.TaskInventory) 4997 m_host.TaskInventory.LockItemsForRead(true);
4998 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4610 { 4999 {
4611 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5000 if (inv.Value.Name == name)
4612 { 5001 {
4613 if (inv.Value.Name == name) 5002 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4614 { 5003 {
4615 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5004 m_host.TaskInventory.LockItemsForRead(false);
4616 { 5005 return inv.Value.AssetID.ToString();
4617 return inv.Value.AssetID.ToString(); 5006 }
4618 } 5007 else
4619 else 5008 {
4620 { 5009 m_host.TaskInventory.LockItemsForRead(false);
4621 return UUID.Zero.ToString(); 5010 return UUID.Zero.ToString();
4622 }
4623 } 5011 }
4624 } 5012 }
4625 } 5013 }
5014 m_host.TaskInventory.LockItemsForRead(false);
4626 5015
4627 return UUID.Zero.ToString(); 5016 return UUID.Zero.ToString();
4628 } 5017 }
@@ -4775,14 +5164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4775 { 5164 {
4776 m_host.AddScriptLPS(1); 5165 m_host.AddScriptLPS(1);
4777 5166
4778 if (src == null) 5167 return src.Length;
4779 {
4780 return 0;
4781 }
4782 else
4783 {
4784 return src.Length;
4785 }
4786 } 5168 }
4787 5169
4788 public LSL_Integer llList2Integer(LSL_List src, int index) 5170 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4828,7 +5210,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4828 else if (src.Data[index] is LSL_Float) 5210 else if (src.Data[index] is LSL_Float)
4829 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5211 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4830 else if (src.Data[index] is LSL_String) 5212 else if (src.Data[index] is LSL_String)
4831 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5213 {
5214 string str = ((LSL_String) src.Data[index]).m_string;
5215 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5216 if (m != Match.Empty)
5217 {
5218 str = m.Value;
5219 double d = 0.0;
5220 if (!Double.TryParse(str, out d))
5221 return 0.0;
5222
5223 return d;
5224 }
5225 return 0.0;
5226 }
4832 return Convert.ToDouble(src.Data[index]); 5227 return Convert.ToDouble(src.Data[index]);
4833 } 5228 }
4834 catch (FormatException) 5229 catch (FormatException)
@@ -5101,7 +5496,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5101 } 5496 }
5102 } 5497 }
5103 } 5498 }
5104 else { 5499 else
5500 {
5105 object[] array = new object[src.Length]; 5501 object[] array = new object[src.Length];
5106 Array.Copy(src.Data, 0, array, 0, src.Length); 5502 Array.Copy(src.Data, 0, array, 0, src.Length);
5107 result = new LSL_List(array); 5503 result = new LSL_List(array);
@@ -5513,7 +5909,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5513 public void llSetSoundQueueing(int queue) 5909 public void llSetSoundQueueing(int queue)
5514 { 5910 {
5515 m_host.AddScriptLPS(1); 5911 m_host.AddScriptLPS(1);
5516 NotImplemented("llSetSoundQueueing");
5517 } 5912 }
5518 5913
5519 public void llSetSoundRadius(double radius) 5914 public void llSetSoundRadius(double radius)
@@ -5558,10 +5953,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5558 m_host.AddScriptLPS(1); 5953 m_host.AddScriptLPS(1);
5559 5954
5560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5955 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5561 5956 if (parts.Count > 0)
5562 foreach (var part in parts)
5563 { 5957 {
5564 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5958 try
5959 {
5960 parts[0].ParentGroup.areUpdatesSuspended = true;
5961 foreach (var part in parts)
5962 {
5963 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5964 }
5965 }
5966 finally
5967 {
5968 parts[0].ParentGroup.areUpdatesSuspended = false;
5969 }
5565 } 5970 }
5566 } 5971 }
5567 5972
@@ -5615,6 +6020,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5615 ScriptSleep(5000); 6020 ScriptSleep(5000);
5616 } 6021 }
5617 6022
6023 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6024 {
6025 return ParseString2List(str, separators, in_spacers, false);
6026 }
6027
5618 public LSL_Integer llOverMyLand(string id) 6028 public LSL_Integer llOverMyLand(string id)
5619 { 6029 {
5620 m_host.AddScriptLPS(1); 6030 m_host.AddScriptLPS(1);
@@ -5815,7 +6225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5815 return m_host.ParentGroup.RootPart.AttachmentPoint; 6225 return m_host.ParentGroup.RootPart.AttachmentPoint;
5816 } 6226 }
5817 6227
5818 public LSL_Integer llGetFreeMemory() 6228 public virtual LSL_Integer llGetFreeMemory()
5819 { 6229 {
5820 m_host.AddScriptLPS(1); 6230 m_host.AddScriptLPS(1);
5821 // Make scripts designed for LSO happy 6231 // Make scripts designed for LSO happy
@@ -5932,7 +6342,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5932 SetParticleSystem(m_host, rules); 6342 SetParticleSystem(m_host, rules);
5933 } 6343 }
5934 6344
5935 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6345 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6346 {
5936 6347
5937 6348
5938 if (rules.Length == 0) 6349 if (rules.Length == 0)
@@ -6126,14 +6537,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6126 6537
6127 protected UUID GetTaskInventoryItem(string name) 6538 protected UUID GetTaskInventoryItem(string name)
6128 { 6539 {
6129 lock (m_host.TaskInventory) 6540 m_host.TaskInventory.LockItemsForRead(true);
6541 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6130 { 6542 {
6131 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6543 if (inv.Value.Name == name)
6132 { 6544 {
6133 if (inv.Value.Name == name) 6545 m_host.TaskInventory.LockItemsForRead(false);
6134 return inv.Key; 6546 return inv.Key;
6135 } 6547 }
6136 } 6548 }
6549 m_host.TaskInventory.LockItemsForRead(false);
6137 6550
6138 return UUID.Zero; 6551 return UUID.Zero;
6139 } 6552 }
@@ -6383,13 +6796,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6383 UUID av = new UUID(); 6796 UUID av = new UUID();
6384 if (!UUID.TryParse(avatar,out av)) 6797 if (!UUID.TryParse(avatar,out av))
6385 { 6798 {
6386 LSLError("First parameter to llDialog needs to be a key"); 6799 //LSLError("First parameter to llDialog needs to be a key");
6387 return; 6800 return;
6388 } 6801 }
6389 if (buttons.Length < 1) 6802 if (buttons.Length < 1)
6390 { 6803 {
6391 LSLError("No less than 1 button can be shown"); 6804 buttons.Add("OK");
6392 return;
6393 } 6805 }
6394 if (buttons.Length > 12) 6806 if (buttons.Length > 12)
6395 { 6807 {
@@ -6406,7 +6818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6406 } 6818 }
6407 if (buttons.Data[i].ToString().Length > 24) 6819 if (buttons.Data[i].ToString().Length > 24)
6408 { 6820 {
6409 LSLError("button label cannot be longer than 24 characters"); 6821 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6410 return; 6822 return;
6411 } 6823 }
6412 buts[i] = buttons.Data[i].ToString(); 6824 buts[i] = buttons.Data[i].ToString();
@@ -6470,22 +6882,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6470 } 6882 }
6471 6883
6472 // copy the first script found with this inventory name 6884 // copy the first script found with this inventory name
6473 lock (m_host.TaskInventory) 6885 TaskInventoryItem scriptItem = null;
6886 m_host.TaskInventory.LockItemsForRead(true);
6887 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6474 { 6888 {
6475 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6889 if (inv.Value.Name == name)
6476 { 6890 {
6477 if (inv.Value.Name == name) 6891 // make sure the object is a script
6892 if (10 == inv.Value.Type)
6478 { 6893 {
6479 // make sure the object is a script 6894 found = true;
6480 if (10 == inv.Value.Type) 6895 srcId = inv.Key;
6481 { 6896 scriptItem = inv.Value;
6482 found = true; 6897 break;
6483 srcId = inv.Key;
6484 break;
6485 }
6486 } 6898 }
6487 } 6899 }
6488 } 6900 }
6901 m_host.TaskInventory.LockItemsForRead(false);
6489 6902
6490 if (!found) 6903 if (!found)
6491 { 6904 {
@@ -6493,8 +6906,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6493 return; 6906 return;
6494 } 6907 }
6495 6908
6496 // the rest of the permission checks are done in RezScript, so check the pin there as well 6909 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6497 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6910 if (dest != null)
6911 {
6912 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
6913 {
6914 // the rest of the permission checks are done in RezScript, so check the pin there as well
6915 World.RezScript(srcId, m_host, destId, pin, running, start_param);
6916
6917 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
6918 m_host.Inventory.RemoveInventoryItem(srcId);
6919 }
6920 }
6498 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6921 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6499 ScriptSleep(3000); 6922 ScriptSleep(3000);
6500 } 6923 }
@@ -6557,18 +6980,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6557 public LSL_String llMD5String(string src, int nonce) 6980 public LSL_String llMD5String(string src, int nonce)
6558 { 6981 {
6559 m_host.AddScriptLPS(1); 6982 m_host.AddScriptLPS(1);
6560 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 6983 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6561 } 6984 }
6562 6985
6563 public LSL_String llSHA1String(string src) 6986 public LSL_String llSHA1String(string src)
6564 { 6987 {
6565 m_host.AddScriptLPS(1); 6988 m_host.AddScriptLPS(1);
6566 return Util.SHA1Hash(src).ToLower(); 6989 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6567 } 6990 }
6568 6991
6569 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6992 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6570 { 6993 {
6571 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6994 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6996 return shapeBlock;
6572 6997
6573 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6998 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6574 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6999 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6644,6 +7069,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6644 7069
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) 7070 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 { 7071 {
7072 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7073 return;
7074
6647 ObjectShapePacket.ObjectDataBlock shapeBlock; 7075 ObjectShapePacket.ObjectDataBlock shapeBlock;
6648 7076
6649 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7077 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6693,6 +7121,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6693 7121
6694 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7122 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6695 { 7123 {
7124 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7125 return;
7126
6696 ObjectShapePacket.ObjectDataBlock shapeBlock; 7127 ObjectShapePacket.ObjectDataBlock shapeBlock;
6697 7128
6698 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7129 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6735,6 +7166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6735 7166
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) 7167 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 { 7168 {
7169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7170 return;
7171
6738 ObjectShapePacket.ObjectDataBlock shapeBlock; 7172 ObjectShapePacket.ObjectDataBlock shapeBlock;
6739 7173
6740 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7174 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6861,6 +7295,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 7295
6862 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7296 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6863 { 7297 {
7298 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7299 return;
7300
6864 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7301 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6865 UUID sculptId; 7302 UUID sculptId;
6866 7303
@@ -6876,13 +7313,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6876 shapeBlock.PathScaleX = 100; 7313 shapeBlock.PathScaleX = 100;
6877 shapeBlock.PathScaleY = 150; 7314 shapeBlock.PathScaleY = 150;
6878 7315
6879 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7316 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6880 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7317 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6881 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7318 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6882 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7319 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6883 { 7320 {
6884 // default 7321 // default
6885 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7322 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6886 } 7323 }
6887 7324
6888 // retain pathcurve 7325 // retain pathcurve
@@ -6901,32 +7338,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6901 ScriptSleep(200); 7338 ScriptSleep(200);
6902 } 7339 }
6903 7340
6904 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7341 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6905 { 7342 {
6906 m_host.AddScriptLPS(1); 7343 m_host.AddScriptLPS(1);
6907 7344
6908 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7345 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7346 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7347 if (parts.Count>0)
7348 {
7349 try
7350 {
7351 parts[0].ParentGroup.areUpdatesSuspended = true;
7352 foreach (SceneObjectPart part in parts)
7353 SetPrimParams(part, rules);
7354 }
7355 finally
7356 {
7357 parts[0].ParentGroup.areUpdatesSuspended = false;
7358 }
7359 }
7360 if (avatars.Count > 0)
7361 {
7362 foreach (ScenePresence avatar in avatars)
7363 SetPrimParams(avatar, rules);
7364 }
7365 }
6909 7366
6910 foreach (SceneObjectPart part in parts) 7367 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6911 SetPrimParams(part, rules); 7368 {
6912 7369 llSetLinkPrimitiveParamsFast(linknumber, rules);
6913 ScriptSleep(200); 7370 ScriptSleep(200);
6914 } 7371 }
6915 7372
6916 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7373 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6917 { 7374 {
6918 m_host.AddScriptLPS(1); 7375 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7376 //We only support PRIM_POSITION and PRIM_ROTATION
6919 7377
6920 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7378 int idx = 0;
6921 7379
6922 foreach (SceneObjectPart part in parts) 7380 while (idx < rules.Length)
6923 SetPrimParams(part, rules); 7381 {
7382 int code = rules.GetLSLIntegerItem(idx++);
7383
7384 int remain = rules.Length - idx;
7385
7386
7387
7388 switch (code)
7389 {
7390 case (int)ScriptBaseClass.PRIM_POSITION:
7391 if (remain < 1)
7392 return;
7393 LSL_Vector v;
7394 v = rules.GetVector3Item(idx++);
7395 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7396 av.SendAvatarDataToAllAgents();
7397
7398 break;
7399
7400 case (int)ScriptBaseClass.PRIM_ROTATION:
7401 if (remain < 1)
7402 return;
7403 LSL_Rotation r;
7404 r = rules.GetQuaternionItem(idx++);
7405 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7406 av.SendAvatarDataToAllAgents();
7407 break;
7408 }
7409 }
6924 } 7410 }
6925 7411
6926 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7412 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6927 { 7413 {
7414 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7415 return;
7416
6928 int idx = 0; 7417 int idx = 0;
6929 7418
7419 bool positionChanged = false;
7420 LSL_Vector currentPosition = GetPartLocalPos(part);
7421
6930 while (idx < rules.Length) 7422 while (idx < rules.Length)
6931 { 7423 {
6932 int code = rules.GetLSLIntegerItem(idx++); 7424 int code = rules.GetLSLIntegerItem(idx++);
@@ -6935,7 +7427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6935 7427
6936 int face; 7428 int face;
6937 LSL_Vector v; 7429 LSL_Vector v;
6938 7430
6939 switch (code) 7431 switch (code)
6940 { 7432 {
6941 case (int)ScriptBaseClass.PRIM_POSITION: 7433 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -6943,7 +7435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6943 return; 7435 return;
6944 7436
6945 v=rules.GetVector3Item(idx++); 7437 v=rules.GetVector3Item(idx++);
6946 SetPos(part, v); 7438 positionChanged = true;
7439 currentPosition = GetSetPosTarget(part, v, currentPosition);
6947 7440
6948 break; 7441 break;
6949 case (int)ScriptBaseClass.PRIM_SIZE: 7442 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7311,6 +7804,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7311 break; 7804 break;
7312 } 7805 }
7313 } 7806 }
7807
7808 if (positionChanged)
7809 {
7810 if (part.ParentGroup.RootPart == part)
7811 {
7812 SceneObjectGroup parent = part.ParentGroup;
7813 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7814 }
7815 else
7816 {
7817 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7818 SceneObjectGroup parent = part.ParentGroup;
7819 parent.HasGroupChanged = true;
7820 parent.ScheduleGroupForTerseUpdate();
7821 }
7822 }
7314 } 7823 }
7315 7824
7316 public LSL_String llStringToBase64(string str) 7825 public LSL_String llStringToBase64(string str)
@@ -7459,13 +7968,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7459 public LSL_Integer llGetNumberOfPrims() 7968 public LSL_Integer llGetNumberOfPrims()
7460 { 7969 {
7461 m_host.AddScriptLPS(1); 7970 m_host.AddScriptLPS(1);
7462 int avatarCount = 0; 7971 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7463 World.ForEachScenePresence(delegate(ScenePresence presence) 7972
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; 7973 return m_host.ParentGroup.PrimCount + avatarCount;
7470 } 7974 }
7471 7975
@@ -7481,55 +7985,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7481 m_host.AddScriptLPS(1); 7985 m_host.AddScriptLPS(1);
7482 UUID objID = UUID.Zero; 7986 UUID objID = UUID.Zero;
7483 LSL_List result = new LSL_List(); 7987 LSL_List result = new LSL_List();
7988
7989 // If the ID is not valid, return null result
7484 if (!UUID.TryParse(obj, out objID)) 7990 if (!UUID.TryParse(obj, out objID))
7485 { 7991 {
7486 result.Add(new LSL_Vector()); 7992 result.Add(new LSL_Vector());
7487 result.Add(new LSL_Vector()); 7993 result.Add(new LSL_Vector());
7488 return result; 7994 return result;
7489 } 7995 }
7996
7997 // Check if this is an attached prim. If so, replace
7998 // the UUID with the avatar UUID and report it's bounding box
7999 SceneObjectPart part = World.GetSceneObjectPart(objID);
8000 if (part != null && part.ParentGroup.IsAttachment)
8001 objID = part.ParentGroup.RootPart.AttachedAvatar;
8002
8003 // Find out if this is an avatar ID. If so, return it's box
7490 ScenePresence presence = World.GetScenePresence(objID); 8004 ScenePresence presence = World.GetScenePresence(objID);
7491 if (presence != null) 8005 if (presence != null)
7492 { 8006 {
7493 if (presence.ParentID == 0) // not sat on an object 8007 // As per LSL Wiki, there is no difference between sitting
8008 // and standing avatar since server 1.36
8009 LSL_Vector lower;
8010 LSL_Vector upper;
8011 if (presence.Animator.Animations.DefaultAnimation.AnimID
8012 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7494 { 8013 {
7495 LSL_Vector lower; 8014 // This is for ground sitting avatars
7496 LSL_Vector upper; 8015 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7497 if (presence.Animator.Animations.DefaultAnimation.AnimID 8016 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7498 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8017 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 } 8018 }
7516 else 8019 else
7517 { 8020 {
7518 // sitting on an object so we need the bounding box of that 8021 // This is for standing/flying avatars
7519 // which should include the avatar so set the UUID to the 8022 float height = presence.Appearance.AvatarHeight / 2.0f;
7520 // UUID of the object the avatar is sat on and allow it to fall through 8023 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7521 // to processing an object 8024 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7522 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7523 objID = p.UUID;
7524 } 8025 }
8026
8027 // Adjust to the documented error offsets (see LSL Wiki)
8028 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8029 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8030
8031 if (lower.x > upper.x)
8032 lower.x = upper.x;
8033 if (lower.y > upper.y)
8034 lower.y = upper.y;
8035 if (lower.z > upper.z)
8036 lower.z = upper.z;
8037
8038 result.Add(lower);
8039 result.Add(upper);
8040 return result;
7525 } 8041 }
7526 SceneObjectPart part = World.GetSceneObjectPart(objID); 8042
8043 part = World.GetSceneObjectPart(objID);
7527 // Currently only works for single prims without a sitting avatar 8044 // Currently only works for single prims without a sitting avatar
7528 if (part != null) 8045 if (part != null)
7529 { 8046 {
7530 Vector3 halfSize = part.Scale / 2.0f; 8047 float minX;
7531 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8048 float maxX;
7532 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8049 float minY;
8050 float maxY;
8051 float minZ;
8052 float maxZ;
8053
8054 // This BBox is in sim coordinates, with the offset being
8055 // a contained point.
8056 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8057 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8058
8059 minX -= offsets[0].X;
8060 maxX -= offsets[0].X;
8061 minY -= offsets[0].Y;
8062 maxY -= offsets[0].Y;
8063 minZ -= offsets[0].Z;
8064 maxZ -= offsets[0].Z;
8065
8066 LSL_Vector lower;
8067 LSL_Vector upper;
8068
8069 // Adjust to the documented error offsets (see LSL Wiki)
8070 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8071 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8072
8073 if (lower.x > upper.x)
8074 lower.x = upper.x;
8075 if (lower.y > upper.y)
8076 lower.y = upper.y;
8077 if (lower.z > upper.z)
8078 lower.z = upper.z;
8079
7533 result.Add(lower); 8080 result.Add(lower);
7534 result.Add(upper); 8081 result.Add(upper);
7535 return result; 8082 return result;
@@ -7609,13 +8156,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7609 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8156 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7610 part.AbsolutePosition.Y, 8157 part.AbsolutePosition.Y,
7611 part.AbsolutePosition.Z); 8158 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); 8159 res.Add(v);
7620 break; 8160 break;
7621 8161
@@ -7776,56 +8316,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8316 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7777 if (remain < 1) 8317 if (remain < 1)
7778 return res; 8318 return res;
7779 8319 face = (int)rules.GetLSLIntegerItem(idx++);
7780 face=(int)rules.GetLSLIntegerItem(idx++);
7781 8320
7782 tex = part.Shape.Textures; 8321 tex = part.Shape.Textures;
8322 int shiny;
7783 if (face == ScriptBaseClass.ALL_SIDES) 8323 if (face == ScriptBaseClass.ALL_SIDES)
7784 { 8324 {
7785 for (face = 0; face < GetNumberOfSides(part); face++) 8325 for (face = 0; face < GetNumberOfSides(part); face++)
7786 { 8326 {
7787 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8327 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7788 // Convert Shininess to PRIM_SHINY_* 8328 if (shinyness == Shininess.High)
7789 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8329 {
7790 // PRIM_BUMP_* 8330 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7791 res.Add(new LSL_Integer((int)texface.Bump)); 8331 }
8332 else if (shinyness == Shininess.Medium)
8333 {
8334 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8335 }
8336 else if (shinyness == Shininess.Low)
8337 {
8338 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8339 }
8340 else
8341 {
8342 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8343 }
8344 res.Add(new LSL_Integer(shiny));
8345 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7792 } 8346 }
7793 } 8347 }
7794 else 8348 else
7795 { 8349 {
7796 if (face >= 0 && face < GetNumberOfSides(part)) 8350 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8351 if (shinyness == Shininess.High)
7797 { 8352 {
7798 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8353 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7799 // Convert Shininess to PRIM_SHINY_*
7800 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7801 // PRIM_BUMP_*
7802 res.Add(new LSL_Integer((int)texface.Bump));
7803 } 8354 }
8355 else if (shinyness == Shininess.Medium)
8356 {
8357 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8358 }
8359 else if (shinyness == Shininess.Low)
8360 {
8361 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8362 }
8363 else
8364 {
8365 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8366 }
8367 res.Add(new LSL_Integer(shiny));
8368 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7804 } 8369 }
7805 break; 8370 break;
7806 8371
7807 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8372 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7808 if (remain < 1) 8373 if (remain < 1)
7809 return res; 8374 return res;
7810 8375 face = (int)rules.GetLSLIntegerItem(idx++);
7811 face=(int)rules.GetLSLIntegerItem(idx++);
7812 8376
7813 tex = part.Shape.Textures; 8377 tex = part.Shape.Textures;
8378 int fullbright;
7814 if (face == ScriptBaseClass.ALL_SIDES) 8379 if (face == ScriptBaseClass.ALL_SIDES)
7815 { 8380 {
7816 for (face = 0; face < GetNumberOfSides(part); face++) 8381 for (face = 0; face < GetNumberOfSides(part); face++)
7817 { 8382 {
7818 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8383 if (tex.GetFace((uint)face).Fullbright == true)
7819 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8384 {
8385 fullbright = ScriptBaseClass.TRUE;
8386 }
8387 else
8388 {
8389 fullbright = ScriptBaseClass.FALSE;
8390 }
8391 res.Add(new LSL_Integer(fullbright));
7820 } 8392 }
7821 } 8393 }
7822 else 8394 else
7823 { 8395 {
7824 if (face >= 0 && face < GetNumberOfSides(part)) 8396 if (tex.GetFace((uint)face).Fullbright == true)
7825 { 8397 {
7826 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8398 fullbright = ScriptBaseClass.TRUE;
7827 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8399 }
8400 else
8401 {
8402 fullbright = ScriptBaseClass.FALSE;
7828 } 8403 }
8404 res.Add(new LSL_Integer(fullbright));
7829 } 8405 }
7830 break; 8406 break;
7831 8407
@@ -7847,27 +8423,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7847 break; 8423 break;
7848 8424
7849 case (int)ScriptBaseClass.PRIM_TEXGEN: 8425 case (int)ScriptBaseClass.PRIM_TEXGEN:
8426 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7850 if (remain < 1) 8427 if (remain < 1)
7851 return res; 8428 return res;
7852 8429 face = (int)rules.GetLSLIntegerItem(idx++);
7853 face=(int)rules.GetLSLIntegerItem(idx++);
7854 8430
7855 tex = part.Shape.Textures; 8431 tex = part.Shape.Textures;
7856 if (face == ScriptBaseClass.ALL_SIDES) 8432 if (face == ScriptBaseClass.ALL_SIDES)
7857 { 8433 {
7858 for (face = 0; face < GetNumberOfSides(part); face++) 8434 for (face = 0; face < GetNumberOfSides(part); face++)
7859 { 8435 {
7860 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8436 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7861 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8437 {
7862 res.Add(new LSL_Integer((uint)texgen >> 1)); 8438 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8439 }
8440 else
8441 {
8442 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8443 }
7863 } 8444 }
7864 } 8445 }
7865 else 8446 else
7866 { 8447 {
7867 if (face >= 0 && face < GetNumberOfSides(part)) 8448 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7868 { 8449 {
7869 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8450 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
7870 res.Add(new LSL_Integer((uint)texgen >> 1)); 8451 }
8452 else
8453 {
8454 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7871 } 8455 }
7872 } 8456 }
7873 break; 8457 break;
@@ -7890,28 +8474,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7890 case (int)ScriptBaseClass.PRIM_GLOW: 8474 case (int)ScriptBaseClass.PRIM_GLOW:
7891 if (remain < 1) 8475 if (remain < 1)
7892 return res; 8476 return res;
7893 8477 face = (int)rules.GetLSLIntegerItem(idx++);
7894 face=(int)rules.GetLSLIntegerItem(idx++);
7895 8478
7896 tex = part.Shape.Textures; 8479 tex = part.Shape.Textures;
8480 float primglow;
7897 if (face == ScriptBaseClass.ALL_SIDES) 8481 if (face == ScriptBaseClass.ALL_SIDES)
7898 { 8482 {
7899 for (face = 0; face < GetNumberOfSides(part); face++) 8483 for (face = 0; face < GetNumberOfSides(part); face++)
7900 { 8484 {
7901 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8485 primglow = tex.GetFace((uint)face).Glow;
7902 res.Add(new LSL_Float(texface.Glow)); 8486 res.Add(new LSL_Float(primglow));
7903 } 8487 }
7904 } 8488 }
7905 else 8489 else
7906 { 8490 {
7907 if (face >= 0 && face < GetNumberOfSides(part)) 8491 primglow = tex.GetFace((uint)face).Glow;
7908 { 8492 res.Add(new LSL_Float(primglow));
7909 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7910 res.Add(new LSL_Float(texface.Glow));
7911 }
7912 } 8493 }
7913 break; 8494 break;
7914
7915 case (int)ScriptBaseClass.PRIM_TEXT: 8495 case (int)ScriptBaseClass.PRIM_TEXT:
7916 Color4 textColor = part.GetTextColor(); 8496 Color4 textColor = part.GetTextColor();
7917 res.Add(part.Text); 8497 res.Add(part.Text);
@@ -8460,8 +9040,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8460 // The function returns an ordered list 9040 // The function returns an ordered list
8461 // representing the tokens found in the supplied 9041 // representing the tokens found in the supplied
8462 // sources string. If two successive tokenizers 9042 // sources string. If two successive tokenizers
8463 // are encountered, then a NULL entry is added 9043 // are encountered, then a null-string entry is
8464 // to the list. 9044 // added to the list.
8465 // 9045 //
8466 // It is a precondition that the source and 9046 // It is a precondition that the source and
8467 // toekizer lisst are non-null. If they are null, 9047 // toekizer lisst are non-null. If they are null,
@@ -8469,7 +9049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8469 // while their lengths are being determined. 9049 // while their lengths are being determined.
8470 // 9050 //
8471 // A small amount of working memoryis required 9051 // A small amount of working memoryis required
8472 // of approximately 8*#tokenizers. 9052 // of approximately 8*#tokenizers + 8*srcstrlen.
8473 // 9053 //
8474 // There are many ways in which this function 9054 // There are many ways in which this function
8475 // can be implemented, this implementation is 9055 // can be implemented, this implementation is
@@ -8485,155 +9065,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8485 // and eliminates redundant tokenizers as soon 9065 // and eliminates redundant tokenizers as soon
8486 // as is possible. 9066 // as is possible.
8487 // 9067 //
8488 // The implementation tries to avoid any copying 9068 // The implementation tries to minimize temporary
8489 // of arrays or other objects. 9069 // garbage generation.
8490 // </remarks> 9070 // </remarks>
8491 9071
8492 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9072 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8493 { 9073 {
8494 int beginning = 0; 9074 return ParseString2List(src, separators, spacers, true);
8495 int srclen = src.Length; 9075 }
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 9076
8510 LSL_List tokens = new LSL_List(); 9077 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9078 {
9079 int srclen = src.Length;
9080 int seplen = separators.Length;
9081 object[] separray = separators.Data;
9082 int spclen = spacers.Length;
9083 object[] spcarray = spacers.Data;
9084 int dellen = 0;
9085 string[] delarray = new string[seplen+spclen];
8511 9086
8512 // All entries are initially valid 9087 int outlen = 0;
9088 string[] outarray = new string[srclen*2+1];
8513 9089
8514 for (int i = 0; i < mlen; i++) 9090 int i, j;
8515 active[i] = true; 9091 string d;
8516 9092
8517 offset[mlen] = srclen; 9093 m_host.AddScriptLPS(1);
8518 9094
8519 while (beginning < srclen) 9095 /*
9096 * Convert separator and spacer lists to C# strings.
9097 * Also filter out null strings so we don't hang.
9098 */
9099 for (i = 0; i < seplen; i ++)
8520 { 9100 {
9101 d = separray[i].ToString();
9102 if (d.Length > 0)
9103 {
9104 delarray[dellen++] = d;
9105 }
9106 }
9107 seplen = dellen;
8521 9108
8522 best = mlen; // as bad as it gets 9109 for (i = 0; i < spclen; i ++)
9110 {
9111 d = spcarray[i].ToString();
9112 if (d.Length > 0)
9113 {
9114 delarray[dellen++] = d;
9115 }
9116 }
8523 9117
8524 // Scan for separators 9118 /*
9119 * Scan through source string from beginning to end.
9120 */
9121 for (i = 0;;)
9122 {
8525 9123
8526 for (j = 0; j < seplen; j++) 9124 /*
9125 * Find earliest delimeter in src starting at i (if any).
9126 */
9127 int earliestDel = -1;
9128 int earliestSrc = srclen;
9129 string earliestStr = null;
9130 for (j = 0; j < dellen; j ++)
8527 { 9131 {
8528 if (separray[j].ToString() == String.Empty) 9132 d = delarray[j];
8529 active[j] = false; 9133 if (d != null)
8530
8531 if (active[j])
8532 { 9134 {
8533 // scan all of the markers 9135 int index = src.IndexOf(d, i);
8534 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9136 if (index < 0)
8535 { 9137 {
8536 // not present at all 9138 delarray[j] = null; // delim nowhere in src, don't check it anymore
8537 active[j] = false;
8538 } 9139 }
8539 else 9140 else if (index < earliestSrc)
8540 { 9141 {
8541 // present and correct 9142 earliestSrc = index; // where delimeter starts in source string
8542 if (offset[j] < offset[best]) 9143 earliestDel = j; // where delimeter is in delarray[]
8543 { 9144 earliestStr = d; // the delimeter string from delarray[]
8544 // closest so far 9145 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 } 9146 }
8550 } 9147 }
8551 } 9148 }
8552 9149
8553 // Scan for spacers 9150 /*
8554 9151 * Output source string starting at i through start of earliest delimeter.
8555 if (offset[best] != beginning) 9152 */
9153 if (keepNulls || (earliestSrc > i))
8556 { 9154 {
8557 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9155 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 } 9156 }
8582 9157
8583 // This is the normal exit from the scanning loop 9158 /*
9159 * If no delimeter found at or after i, we're done scanning.
9160 */
9161 if (earliestDel < 0) break;
8584 9162
8585 if (best == mlen) 9163 /*
9164 * If delimeter was a spacer, output the spacer.
9165 */
9166 if (earliestDel >= seplen)
8586 { 9167 {
8587 // no markers were found on this pass 9168 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 } 9169 }
8593 9170
8594 // Otherwise we just add the newly delimited token 9171 /*
8595 // and recalculate where the search should continue. 9172 * Look at rest of src string following delimeter.
8596 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9173 */
8597 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9174 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 } 9175 }
8611 9176
8612 // This an awkward an not very intuitive boundary case. If the 9177 /*
8613 // last substring is a tokenizer, then there is an implied trailing 9178 * 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 9179 */
8615 // arduous. Alternatively the 'break' could be replced with a return 9180 object[] outlist = new object[outlen];
8616 // but that's shabby programming. 9181 for (i = 0; i < outlen; i ++)
8617
8618 if ((beginning == srclen) && (keepNulls))
8619 { 9182 {
8620 if (srclen != 0) 9183 outlist[i] = new LSL_String(outarray[i]);
8621 tokens.Add(new LSL_String(""));
8622 } 9184 }
8623 9185 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 } 9186 }
8638 9187
8639 public LSL_Integer llGetObjectPermMask(int mask) 9188 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8710,28 +9259,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8710 { 9259 {
8711 m_host.AddScriptLPS(1); 9260 m_host.AddScriptLPS(1);
8712 9261
8713 lock (m_host.TaskInventory) 9262 m_host.TaskInventory.LockItemsForRead(true);
9263 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8714 { 9264 {
8715 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9265 if (inv.Value.Name == item)
8716 { 9266 {
8717 if (inv.Value.Name == item) 9267 m_host.TaskInventory.LockItemsForRead(false);
9268 switch (mask)
8718 { 9269 {
8719 switch (mask) 9270 case 0:
8720 { 9271 return (int)inv.Value.BasePermissions;
8721 case 0: 9272 case 1:
8722 return (int)inv.Value.BasePermissions; 9273 return (int)inv.Value.CurrentPermissions;
8723 case 1: 9274 case 2:
8724 return (int)inv.Value.CurrentPermissions; 9275 return (int)inv.Value.GroupPermissions;
8725 case 2: 9276 case 3:
8726 return (int)inv.Value.GroupPermissions; 9277 return (int)inv.Value.EveryonePermissions;
8727 case 3: 9278 case 4:
8728 return (int)inv.Value.EveryonePermissions; 9279 return (int)inv.Value.NextPermissions;
8729 case 4:
8730 return (int)inv.Value.NextPermissions;
8731 }
8732 } 9280 }
8733 } 9281 }
8734 } 9282 }
9283 m_host.TaskInventory.LockItemsForRead(false);
8735 9284
8736 return -1; 9285 return -1;
8737 } 9286 }
@@ -8778,16 +9327,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8778 { 9327 {
8779 m_host.AddScriptLPS(1); 9328 m_host.AddScriptLPS(1);
8780 9329
8781 lock (m_host.TaskInventory) 9330 m_host.TaskInventory.LockItemsForRead(true);
9331 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8782 { 9332 {
8783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9333 if (inv.Value.Name == item)
8784 { 9334 {
8785 if (inv.Value.Name == item) 9335 m_host.TaskInventory.LockItemsForRead(false);
8786 { 9336 return inv.Value.CreatorID.ToString();
8787 return inv.Value.CreatorID.ToString();
8788 }
8789 } 9337 }
8790 } 9338 }
9339 m_host.TaskInventory.LockItemsForRead(false);
8791 9340
8792 llSay(0, "No item name '" + item + "'"); 9341 llSay(0, "No item name '" + item + "'");
8793 9342
@@ -8935,7 +9484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8935 } 9484 }
8936 9485
8937 /// <summary> 9486 /// <summary>
8938 /// illListReplaceList removes the sub-list defined by the inclusive indices 9487 /// llListReplaceList removes the sub-list defined by the inclusive indices
8939 /// start and end and inserts the src list in its place. The inclusive 9488 /// 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 9489 /// 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 9490 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8992,16 +9541,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8992 // based upon end. Note that if end exceeds the upper 9541 // based upon end. Note that if end exceeds the upper
8993 // bound in this case, the entire destination list 9542 // bound in this case, the entire destination list
8994 // is removed. 9543 // is removed.
8995 else 9544 else if (start == 0)
8996 { 9545 {
8997 if (end + 1 < dest.Length) 9546 if (end + 1 < dest.Length)
8998 {
8999 return src + dest.GetSublist(end + 1, -1); 9547 return src + dest.GetSublist(end + 1, -1);
9000 }
9001 else 9548 else
9002 {
9003 return src; 9549 return src;
9004 } 9550 }
9551 else // Start < 0
9552 {
9553 if (end + 1 < dest.Length)
9554 return dest.GetSublist(end + 1, -1);
9555 else
9556 return new LSL_List();
9005 } 9557 }
9006 } 9558 }
9007 // Finally, if start > end, we strip away a prefix and 9559 // Finally, if start > end, we strip away a prefix and
@@ -9052,17 +9604,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 int width = 0; 9604 int width = 0;
9053 int height = 0; 9605 int height = 0;
9054 9606
9055 ParcelMediaCommandEnum? commandToSend = null; 9607 uint commandToSend = 0;
9056 float time = 0.0f; // default is from start 9608 float time = 0.0f; // default is from start
9057 9609
9058 ScenePresence presence = null; 9610 ScenePresence presence = null;
9059 9611
9060 for (int i = 0; i < commandList.Data.Length; i++) 9612 for (int i = 0; i < commandList.Data.Length; i++)
9061 { 9613 {
9062 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9614 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9063 switch (command) 9615 switch (command)
9064 { 9616 {
9065 case ParcelMediaCommandEnum.Agent: 9617 case (uint)ParcelMediaCommandEnum.Agent:
9066 // we send only to one agent 9618 // we send only to one agent
9067 if ((i + 1) < commandList.Length) 9619 if ((i + 1) < commandList.Length)
9068 { 9620 {
@@ -9079,25 +9631,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9079 } 9631 }
9080 break; 9632 break;
9081 9633
9082 case ParcelMediaCommandEnum.Loop: 9634 case (uint)ParcelMediaCommandEnum.Loop:
9083 loop = 1; 9635 loop = 1;
9084 commandToSend = command; 9636 commandToSend = command;
9085 update = true; //need to send the media update packet to set looping 9637 update = true; //need to send the media update packet to set looping
9086 break; 9638 break;
9087 9639
9088 case ParcelMediaCommandEnum.Play: 9640 case (uint)ParcelMediaCommandEnum.Play:
9089 loop = 0; 9641 loop = 0;
9090 commandToSend = command; 9642 commandToSend = command;
9091 update = true; //need to send the media update packet to make sure it doesn't loop 9643 update = true; //need to send the media update packet to make sure it doesn't loop
9092 break; 9644 break;
9093 9645
9094 case ParcelMediaCommandEnum.Pause: 9646 case (uint)ParcelMediaCommandEnum.Pause:
9095 case ParcelMediaCommandEnum.Stop: 9647 case (uint)ParcelMediaCommandEnum.Stop:
9096 case ParcelMediaCommandEnum.Unload: 9648 case (uint)ParcelMediaCommandEnum.Unload:
9097 commandToSend = command; 9649 commandToSend = command;
9098 break; 9650 break;
9099 9651
9100 case ParcelMediaCommandEnum.Url: 9652 case (uint)ParcelMediaCommandEnum.Url:
9101 if ((i + 1) < commandList.Length) 9653 if ((i + 1) < commandList.Length)
9102 { 9654 {
9103 if (commandList.Data[i + 1] is LSL_String) 9655 if (commandList.Data[i + 1] is LSL_String)
@@ -9110,7 +9662,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9110 } 9662 }
9111 break; 9663 break;
9112 9664
9113 case ParcelMediaCommandEnum.Texture: 9665 case (uint)ParcelMediaCommandEnum.Texture:
9114 if ((i + 1) < commandList.Length) 9666 if ((i + 1) < commandList.Length)
9115 { 9667 {
9116 if (commandList.Data[i + 1] is LSL_String) 9668 if (commandList.Data[i + 1] is LSL_String)
@@ -9123,7 +9675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9123 } 9675 }
9124 break; 9676 break;
9125 9677
9126 case ParcelMediaCommandEnum.Time: 9678 case (uint)ParcelMediaCommandEnum.Time:
9127 if ((i + 1) < commandList.Length) 9679 if ((i + 1) < commandList.Length)
9128 { 9680 {
9129 if (commandList.Data[i + 1] is LSL_Float) 9681 if (commandList.Data[i + 1] is LSL_Float)
@@ -9135,7 +9687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9135 } 9687 }
9136 break; 9688 break;
9137 9689
9138 case ParcelMediaCommandEnum.AutoAlign: 9690 case (uint)ParcelMediaCommandEnum.AutoAlign:
9139 if ((i + 1) < commandList.Length) 9691 if ((i + 1) < commandList.Length)
9140 { 9692 {
9141 if (commandList.Data[i + 1] is LSL_Integer) 9693 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9149,7 +9701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9149 } 9701 }
9150 break; 9702 break;
9151 9703
9152 case ParcelMediaCommandEnum.Type: 9704 case (uint)ParcelMediaCommandEnum.Type:
9153 if ((i + 1) < commandList.Length) 9705 if ((i + 1) < commandList.Length)
9154 { 9706 {
9155 if (commandList.Data[i + 1] is LSL_String) 9707 if (commandList.Data[i + 1] is LSL_String)
@@ -9162,7 +9714,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9162 } 9714 }
9163 break; 9715 break;
9164 9716
9165 case ParcelMediaCommandEnum.Desc: 9717 case (uint)ParcelMediaCommandEnum.Desc:
9166 if ((i + 1) < commandList.Length) 9718 if ((i + 1) < commandList.Length)
9167 { 9719 {
9168 if (commandList.Data[i + 1] is LSL_String) 9720 if (commandList.Data[i + 1] is LSL_String)
@@ -9175,7 +9727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9175 } 9727 }
9176 break; 9728 break;
9177 9729
9178 case ParcelMediaCommandEnum.Size: 9730 case (uint)ParcelMediaCommandEnum.Size:
9179 if ((i + 2) < commandList.Length) 9731 if ((i + 2) < commandList.Length)
9180 { 9732 {
9181 if (commandList.Data[i + 1] is LSL_Integer) 9733 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9245,7 +9797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9245 } 9797 }
9246 } 9798 }
9247 9799
9248 if (commandToSend != null) 9800 if (commandToSend != 0)
9249 { 9801 {
9250 // the commandList contained a start/stop/... command, too 9802 // the commandList contained a start/stop/... command, too
9251 if (presence == null) 9803 if (presence == null)
@@ -9282,7 +9834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9282 9834
9283 if (aList.Data[i] != null) 9835 if (aList.Data[i] != null)
9284 { 9836 {
9285 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9837 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9286 { 9838 {
9287 case ParcelMediaCommandEnum.Url: 9839 case ParcelMediaCommandEnum.Url:
9288 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9840 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9325,16 +9877,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9325 { 9877 {
9326 m_host.AddScriptLPS(1); 9878 m_host.AddScriptLPS(1);
9327 9879
9328 lock (m_host.TaskInventory) 9880 m_host.TaskInventory.LockItemsForRead(true);
9881 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9329 { 9882 {
9330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9883 if (inv.Value.Name == name)
9331 { 9884 {
9332 if (inv.Value.Name == name) 9885 m_host.TaskInventory.LockItemsForRead(false);
9333 { 9886 return inv.Value.Type;
9334 return inv.Value.Type;
9335 }
9336 } 9887 }
9337 } 9888 }
9889 m_host.TaskInventory.LockItemsForRead(false);
9338 9890
9339 return -1; 9891 return -1;
9340 } 9892 }
@@ -9345,15 +9897,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9345 9897
9346 if (quick_pay_buttons.Data.Length < 4) 9898 if (quick_pay_buttons.Data.Length < 4)
9347 { 9899 {
9348 LSLError("List must have at least 4 elements"); 9900 int x;
9349 return; 9901 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9902 {
9903 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9904 }
9350 } 9905 }
9351 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9906 int[] nPrice = new int[5];
9352 9907 nPrice[0] = price;
9353 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9908 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9354 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9909 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9355 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9910 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9356 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9911 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9912 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9357 m_host.ParentGroup.HasGroupChanged = true; 9913 m_host.ParentGroup.HasGroupChanged = true;
9358 } 9914 }
9359 9915
@@ -9365,17 +9921,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9365 if (invItemID == UUID.Zero) 9921 if (invItemID == UUID.Zero)
9366 return new LSL_Vector(); 9922 return new LSL_Vector();
9367 9923
9368 lock (m_host.TaskInventory) 9924 m_host.TaskInventory.LockItemsForRead(true);
9925 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9369 { 9926 {
9370 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9927 m_host.TaskInventory.LockItemsForRead(false);
9371 return new LSL_Vector(); 9928 return new LSL_Vector();
9929 }
9372 9930
9373 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9931 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9374 { 9932 {
9375 ShoutError("No permissions to track the camera"); 9933 ShoutError("No permissions to track the camera");
9376 return new LSL_Vector(); 9934 m_host.TaskInventory.LockItemsForRead(false);
9377 } 9935 return new LSL_Vector();
9378 } 9936 }
9937 m_host.TaskInventory.LockItemsForRead(false);
9379 9938
9380 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9939 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9381 if (presence != null) 9940 if (presence != null)
@@ -9393,17 +9952,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9393 if (invItemID == UUID.Zero) 9952 if (invItemID == UUID.Zero)
9394 return new LSL_Rotation(); 9953 return new LSL_Rotation();
9395 9954
9396 lock (m_host.TaskInventory) 9955 m_host.TaskInventory.LockItemsForRead(true);
9956 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9397 { 9957 {
9398 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9958 m_host.TaskInventory.LockItemsForRead(false);
9399 return new LSL_Rotation(); 9959 return new LSL_Rotation();
9400
9401 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9402 {
9403 ShoutError("No permissions to track the camera");
9404 return new LSL_Rotation();
9405 }
9406 } 9960 }
9961 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9962 {
9963 ShoutError("No permissions to track the camera");
9964 m_host.TaskInventory.LockItemsForRead(false);
9965 return new LSL_Rotation();
9966 }
9967 m_host.TaskInventory.LockItemsForRead(false);
9407 9968
9408 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9969 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9409 if (presence != null) 9970 if (presence != null)
@@ -9465,8 +10026,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 { 10026 {
9466 m_host.AddScriptLPS(1); 10027 m_host.AddScriptLPS(1);
9467 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10028 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9468 if (detectedParams == null) return; // only works on the first detected avatar 10029 if (detectedParams == null)
9469 10030 {
10031 if (m_host.IsAttachment == true)
10032 {
10033 detectedParams = new DetectParams();
10034 detectedParams.Key = m_host.OwnerID;
10035 }
10036 else
10037 {
10038 return;
10039 }
10040 }
10041
9470 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10042 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9471 if (avatar != null) 10043 if (avatar != null)
9472 { 10044 {
@@ -9474,6 +10046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9474 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10046 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9475 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10047 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9476 } 10048 }
10049
9477 ScriptSleep(1000); 10050 ScriptSleep(1000);
9478 } 10051 }
9479 10052
@@ -9566,14 +10139,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 if (objectID == UUID.Zero) return; 10139 if (objectID == UUID.Zero) return;
9567 10140
9568 UUID agentID; 10141 UUID agentID;
9569 lock (m_host.TaskInventory) 10142 m_host.TaskInventory.LockItemsForRead(true);
9570 { 10143 // 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 10144 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9572 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9573 10145
9574 if (agentID == UUID.Zero) return; 10146 if (agentID == UUID.Zero)
9575 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10147 {
10148 m_host.TaskInventory.LockItemsForRead(false);
10149 return;
9576 } 10150 }
10151 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10152 {
10153 m_host.TaskInventory.LockItemsForRead(false);
10154 return;
10155 }
10156 m_host.TaskInventory.LockItemsForRead(false);
9577 10157
9578 ScenePresence presence = World.GetScenePresence(agentID); 10158 ScenePresence presence = World.GetScenePresence(agentID);
9579 10159
@@ -9582,12 +10162,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 10162
9583 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10163 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9584 object[] data = rules.Data; 10164 object[] data = rules.Data;
9585 for (int i = 0; i < data.Length; ++i) { 10165 for (int i = 0; i < data.Length; ++i)
10166 {
9586 int type = Convert.ToInt32(data[i++].ToString()); 10167 int type = Convert.ToInt32(data[i++].ToString());
9587 if (i >= data.Length) break; // odd number of entries => ignore the last 10168 if (i >= data.Length) break; // odd number of entries => ignore the last
9588 10169
9589 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10170 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9590 switch (type) { 10171 switch (type)
10172 {
9591 case ScriptBaseClass.CAMERA_FOCUS: 10173 case ScriptBaseClass.CAMERA_FOCUS:
9592 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10174 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9593 case ScriptBaseClass.CAMERA_POSITION: 10175 case ScriptBaseClass.CAMERA_POSITION:
@@ -9623,12 +10205,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 10205
9624 // we need the permission first, to know which avatar we want to clear the camera for 10206 // we need the permission first, to know which avatar we want to clear the camera for
9625 UUID agentID; 10207 UUID agentID;
9626 lock (m_host.TaskInventory) 10208 m_host.TaskInventory.LockItemsForRead(true);
10209 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10210 if (agentID == UUID.Zero)
10211 {
10212 m_host.TaskInventory.LockItemsForRead(false);
10213 return;
10214 }
10215 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9627 { 10216 {
9628 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10217 m_host.TaskInventory.LockItemsForRead(false);
9629 if (agentID == UUID.Zero) return; 10218 return;
9630 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9631 } 10219 }
10220 m_host.TaskInventory.LockItemsForRead(false);
9632 10221
9633 ScenePresence presence = World.GetScenePresence(agentID); 10222 ScenePresence presence = World.GetScenePresence(agentID);
9634 10223
@@ -9695,19 +10284,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10284 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9696 { 10285 {
9697 m_host.AddScriptLPS(1); 10286 m_host.AddScriptLPS(1);
9698 string ret = String.Empty; 10287
9699 string src1 = llBase64ToString(str1); 10288 if (str1 == String.Empty)
9700 string src2 = llBase64ToString(str2); 10289 return String.Empty;
9701 int c = 0; 10290 if (str2 == String.Empty)
9702 for (int i = 0; i < src1.Length; i++) 10291 return str1;
10292
10293 int len = str2.Length;
10294 if ((len % 4) != 0) // LL is EVIL!!!!
9703 { 10295 {
9704 ret += (char) (src1[i] ^ src2[c]); 10296 while (str2.EndsWith("="))
10297 str2 = str2.Substring(0, str2.Length - 1);
9705 10298
9706 c++; 10299 len = str2.Length;
9707 if (c >= src2.Length) 10300 int mod = len % 4;
9708 c = 0; 10301
10302 if (mod == 1)
10303 str2 = str2.Substring(0, str2.Length - 1);
10304 else if (mod == 2)
10305 str2 += "==";
10306 else if (mod == 3)
10307 str2 += "=";
10308 }
10309
10310 byte[] data1;
10311 byte[] data2;
10312 try
10313 {
10314 data1 = Convert.FromBase64String(str1);
10315 data2 = Convert.FromBase64String(str2);
9709 } 10316 }
9710 return llStringToBase64(ret); 10317 catch (Exception)
10318 {
10319 return new LSL_String(String.Empty);
10320 }
10321
10322 byte[] d2 = new Byte[data1.Length];
10323 int pos = 0;
10324
10325 if (data1.Length <= data2.Length)
10326 {
10327 Array.Copy(data2, 0, d2, 0, data1.Length);
10328 }
10329 else
10330 {
10331 while (pos < data1.Length)
10332 {
10333 len = data1.Length - pos;
10334 if (len > data2.Length)
10335 len = data2.Length;
10336
10337 Array.Copy(data2, 0, d2, pos, len);
10338 pos += len;
10339 }
10340 }
10341
10342 for (pos = 0 ; pos < data1.Length ; pos++ )
10343 data1[pos] ^= d2[pos];
10344
10345 return Convert.ToBase64String(data1);
9711 } 10346 }
9712 10347
9713 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10348 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9766,12 +10401,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9766 Regex r = new Regex(authregex); 10401 Regex r = new Regex(authregex);
9767 int[] gnums = r.GetGroupNumbers(); 10402 int[] gnums = r.GetGroupNumbers();
9768 Match m = r.Match(url); 10403 Match m = r.Match(url);
9769 if (m.Success) { 10404 if (m.Success)
9770 for (int i = 1; i < gnums.Length; i++) { 10405 {
10406 for (int i = 1; i < gnums.Length; i++)
10407 {
9771 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10408 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9772 //CaptureCollection cc = g.Captures; 10409 //CaptureCollection cc = g.Captures;
9773 } 10410 }
9774 if (m.Groups.Count == 5) { 10411 if (m.Groups.Count == 5)
10412 {
9775 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10413 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(); 10414 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9777 } 10415 }
@@ -9883,7 +10521,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 { 10521 {
9884 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10522 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9885 { 10523 {
9886 ret.Add(detectedParams.Key.ToString()); 10524 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9887 ret.Add(detectedParams.Value); 10525 ret.Add(detectedParams.Value);
9888 } 10526 }
9889 } 10527 }
@@ -10067,15 +10705,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10067 10705
10068 internal UUID ScriptByName(string name) 10706 internal UUID ScriptByName(string name)
10069 { 10707 {
10070 lock (m_host.TaskInventory) 10708 m_host.TaskInventory.LockItemsForRead(true);
10709
10710 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10071 { 10711 {
10072 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10712 if (item.Type == 10 && item.Name == name)
10073 { 10713 {
10074 if (item.Type == 10 && item.Name == name) 10714 m_host.TaskInventory.LockItemsForRead(false);
10075 return item.ItemID; 10715 return item.ItemID;
10076 } 10716 }
10077 } 10717 }
10078 10718
10719 m_host.TaskInventory.LockItemsForRead(false);
10720
10079 return UUID.Zero; 10721 return UUID.Zero;
10080 } 10722 }
10081 10723
@@ -10116,6 +10758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10116 { 10758 {
10117 m_host.AddScriptLPS(1); 10759 m_host.AddScriptLPS(1);
10118 10760
10761 //Clone is thread safe
10119 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10762 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10120 10763
10121 UUID assetID = UUID.Zero; 10764 UUID assetID = UUID.Zero;
@@ -10178,6 +10821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10178 { 10821 {
10179 m_host.AddScriptLPS(1); 10822 m_host.AddScriptLPS(1);
10180 10823
10824 //Clone is thread safe
10181 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10825 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10182 10826
10183 UUID assetID = UUID.Zero; 10827 UUID assetID = UUID.Zero;
@@ -10258,15 +10902,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10258 return GetLinkPrimitiveParams(obj, rules); 10902 return GetLinkPrimitiveParams(obj, rules);
10259 } 10903 }
10260 10904
10261 public void print(string str) 10905 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10262 { 10906 {
10263 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 10907 List<SceneObjectPart> parts = GetLinkParts(link);
10264 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 10908 if (parts.Count < 1)
10265 if (ossl != null) 10909 return 0;
10266 { 10910
10267 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 10911 return GetNumberOfSides(parts[0]);
10268 m_log.Info("LSL print():" + str);
10269 }
10270 } 10912 }
10271 10913
10272 private string Name2Username(string name) 10914 private string Name2Username(string name)
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);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 3575889..e9edf6c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 783791f..9548253 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 298d664..665f4a6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 97ab411..9a78a42 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -269,43 +337,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
269 337
270 public void RemoveRegion(Scene scene) 338 public void RemoveRegion(Scene scene)
271 { 339 {
272 lock (m_Scripts) 340 lockScriptsForRead(true);
341 foreach (IScriptInstance instance in m_Scripts.Values)
273 { 342 {
274 foreach (IScriptInstance instance in m_Scripts.Values) 343 // Force a final state save
344 //
345 if (m_Assemblies.ContainsKey(instance.AssetID))
275 { 346 {
276 // Force a final state save 347 string assembly = m_Assemblies[instance.AssetID];
277 // 348 instance.SaveState(assembly);
278 if (m_Assemblies.ContainsKey(instance.AssetID)) 349 }
279 {
280 string assembly = m_Assemblies[instance.AssetID];
281 instance.SaveState(assembly);
282 }
283 350
284 // Clear the event queue and abort the instance thread 351 // Clear the event queue and abort the instance thread
285 // 352 //
286 instance.ClearQueue(); 353 instance.ClearQueue();
287 instance.Stop(0); 354 instance.Stop(0);
288 355
289 // Release events, timer, etc 356 // Release events, timer, etc
290 // 357 //
291 instance.DestroyScriptInstance(); 358 instance.DestroyScriptInstance();
292 359
293 // Unload scripts and app domains 360 // Unload scripts and app domains
294 // Must be done explicitly because they have infinite 361 // Must be done explicitly because they have infinite
295 // lifetime 362 // lifetime
296 // 363 //
297 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 364 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
298 if (m_DomainScripts[instance.AppDomain].Count == 0) 365 if (m_DomainScripts[instance.AppDomain].Count == 0)
299 { 366 {
300 m_DomainScripts.Remove(instance.AppDomain); 367 m_DomainScripts.Remove(instance.AppDomain);
301 UnloadAppDomain(instance.AppDomain); 368 UnloadAppDomain(instance.AppDomain);
302 }
303 } 369 }
304 m_Scripts.Clear();
305 m_PrimObjects.Clear();
306 m_Assemblies.Clear();
307 m_DomainScripts.Clear();
308 } 370 }
371 lockScriptsForRead(false);
372 lockScriptsForWrite(true);
373 m_Scripts.Clear();
374 lockScriptsForWrite(false);
375 m_PrimObjects.Clear();
376 m_Assemblies.Clear();
377 m_DomainScripts.Clear();
378
309 lock (m_ScriptEngines) 379 lock (m_ScriptEngines)
310 { 380 {
311 m_ScriptEngines.Remove(this); 381 m_ScriptEngines.Remove(this);
@@ -364,22 +434,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
364 434
365 List<IScriptInstance> instances = new List<IScriptInstance>(); 435 List<IScriptInstance> instances = new List<IScriptInstance>();
366 436
367 lock (m_Scripts) 437 lockScriptsForRead(true);
368 { 438 foreach (IScriptInstance instance in m_Scripts.Values)
369 foreach (IScriptInstance instance in m_Scripts.Values)
370 instances.Add(instance); 439 instances.Add(instance);
371 } 440 lockScriptsForRead(false);
372 441
373 foreach (IScriptInstance i in instances) 442 foreach (IScriptInstance i in instances)
374 { 443 {
375 string assembly = String.Empty; 444 string assembly = String.Empty;
376 445
377 lock (m_Scripts) 446
378 {
379 if (!m_Assemblies.ContainsKey(i.AssetID)) 447 if (!m_Assemblies.ContainsKey(i.AssetID))
380 continue; 448 continue;
381 assembly = m_Assemblies[i.AssetID]; 449 assembly = m_Assemblies[i.AssetID];
382 } 450
383 451
384 i.SaveState(assembly); 452 i.SaveState(assembly);
385 } 453 }
@@ -708,92 +776,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
708 } 776 }
709 777
710 ScriptInstance instance = null; 778 ScriptInstance instance = null;
711 lock (m_Scripts) 779 // Create the object record
780 lockScriptsForRead(true);
781 if ((!m_Scripts.ContainsKey(itemID)) ||
782 (m_Scripts[itemID].AssetID != assetID))
712 { 783 {
713 // Create the object record 784 lockScriptsForRead(false);
714 785
715 if ((!m_Scripts.ContainsKey(itemID)) || 786 UUID appDomain = assetID;
716 (m_Scripts[itemID].AssetID != assetID))
717 {
718 UUID appDomain = assetID;
719 787
720 if (part.ParentGroup.IsAttachment) 788 if (part.ParentGroup.IsAttachment)
721 appDomain = part.ParentGroup.RootPart.UUID; 789 appDomain = part.ParentGroup.RootPart.UUID;
722 790
723 if (!m_AppDomains.ContainsKey(appDomain)) 791 if (!m_AppDomains.ContainsKey(appDomain))
792 {
793 try
724 { 794 {
725 try 795 AppDomainSetup appSetup = new AppDomainSetup();
726 { 796 appSetup.PrivateBinPath = Path.Combine(
727 AppDomainSetup appSetup = new AppDomainSetup(); 797 m_ScriptEnginesPath,
728 appSetup.PrivateBinPath = Path.Combine( 798 m_Scene.RegionInfo.RegionID.ToString());
729 m_ScriptEnginesPath, 799
730 m_Scene.RegionInfo.RegionID.ToString()); 800 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
731 801 Evidence evidence = new Evidence(baseEvidence);
732 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 802
733 Evidence evidence = new Evidence(baseEvidence); 803 AppDomain sandbox;
734 804 if (m_AppDomainLoading)
735 AppDomain sandbox; 805 sandbox = AppDomain.CreateDomain(
736 if (m_AppDomainLoading) 806 m_Scene.RegionInfo.RegionID.ToString(),
737 sandbox = AppDomain.CreateDomain( 807 evidence, appSetup);
738 m_Scene.RegionInfo.RegionID.ToString(), 808 else
739 evidence, appSetup); 809 sandbox = AppDomain.CurrentDomain;
740 else 810
741 sandbox = AppDomain.CurrentDomain; 811 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
742 812 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
743 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 813 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
744 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 814 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
745 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 815 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
746 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 816 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
747 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 817 //sandbox.SetAppDomainPolicy(sandboxPolicy);
748 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 818
749 //sandbox.SetAppDomainPolicy(sandboxPolicy); 819 m_AppDomains[appDomain] = sandbox;
750 820
751 m_AppDomains[appDomain] = sandbox; 821 m_AppDomains[appDomain].AssemblyResolve +=
752 822 new ResolveEventHandler(
753 m_AppDomains[appDomain].AssemblyResolve += 823 AssemblyResolver.OnAssemblyResolve);
754 new ResolveEventHandler( 824 m_DomainScripts[appDomain] = new List<UUID>();
755 AssemblyResolver.OnAssemblyResolve); 825 }
756 m_DomainScripts[appDomain] = new List<UUID>(); 826 catch (Exception e)
757 } 827 {
758 catch (Exception e) 828 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
829 m_ScriptErrorMessage += "Exception creating app domain:\n";
830 m_ScriptFailCount++;
831 lock (m_AddingAssemblies)
759 { 832 {
760 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 833 m_AddingAssemblies[assembly]--;
761 m_ScriptErrorMessage += "Exception creating app domain:\n";
762 m_ScriptFailCount++;
763 lock (m_AddingAssemblies)
764 {
765 m_AddingAssemblies[assembly]--;
766 }
767 return false;
768 } 834 }
835 return false;
769 } 836 }
770 m_DomainScripts[appDomain].Add(itemID); 837 }
771 838 m_DomainScripts[appDomain].Add(itemID);
772 instance = new ScriptInstance(this, part, 839
773 itemID, assetID, assembly, 840 instance = new ScriptInstance(this, part,
774 m_AppDomains[appDomain], 841 itemID, assetID, assembly,
775 part.ParentGroup.RootPart.Name, 842 m_AppDomains[appDomain],
776 item.Name, startParam, postOnRez, 843 part.ParentGroup.RootPart.Name,
777 stateSource, m_MaxScriptQueue); 844 item.Name, startParam, postOnRez,
778 845 stateSource, m_MaxScriptQueue);
779 m_log.DebugFormat( 846
847 m_log.DebugFormat(
780 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 848 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
781 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 849 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
782 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 850 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
783 851
784 if (presence != null) 852 if (presence != null)
785 { 853 {
786 ShowScriptSaveResponse(item.OwnerID, 854 ShowScriptSaveResponse(item.OwnerID,
787 assetID, "Compile successful", true); 855 assetID, "Compile successful", true);
788 }
789
790 instance.AppDomain = appDomain;
791 instance.LineMap = linemap;
792
793 m_Scripts[itemID] = instance;
794 } 856 }
795 }
796 857
858 instance.AppDomain = appDomain;
859 instance.LineMap = linemap;
860 lockScriptsForWrite(true);
861 m_Scripts[itemID] = instance;
862 lockScriptsForWrite(false);
863 }
864 else
865 {
866 lockScriptsForRead(false);
867 }
797 lock (m_PrimObjects) 868 lock (m_PrimObjects)
798 { 869 {
799 if (!m_PrimObjects.ContainsKey(localID)) 870 if (!m_PrimObjects.ContainsKey(localID))
@@ -812,9 +883,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
812 m_AddingAssemblies[assembly]--; 883 m_AddingAssemblies[assembly]--;
813 } 884 }
814 885
815 if (instance != null) 886 if (instance!=null)
816 instance.Init(); 887 instance.Init();
817 888
818 return true; 889 return true;
819 } 890 }
820 891
@@ -827,20 +898,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
827 m_CompileDict.Remove(itemID); 898 m_CompileDict.Remove(itemID);
828 } 899 }
829 900
830 IScriptInstance instance = null; 901 lockScriptsForRead(true);
831 902 // Do we even have it?
832 lock (m_Scripts) 903 if (!m_Scripts.ContainsKey(itemID))
833 { 904 {
834 // Do we even have it? 905 lockScriptsForRead(false);
835 if (!m_Scripts.ContainsKey(itemID)) 906 return;
836 return;
837
838 instance=m_Scripts[itemID];
839 m_Scripts.Remove(itemID);
840 } 907 }
908
841 909
910 IScriptInstance instance=m_Scripts[itemID];
911 lockScriptsForRead(false);
912 lockScriptsForWrite(true);
913 m_Scripts.Remove(itemID);
914 lockScriptsForWrite(false);
842 instance.ClearQueue(); 915 instance.ClearQueue();
843 instance.Stop(0); 916 instance.Stop(0);
917
844// bool objectRemoved = false; 918// bool objectRemoved = false;
845 919
846 lock (m_PrimObjects) 920 lock (m_PrimObjects)
@@ -876,11 +950,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
876 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 950 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
877 if (handlerObjectRemoved != null) 951 if (handlerObjectRemoved != null)
878 { 952 {
879 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 953 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
880 handlerObjectRemoved(part.UUID); 954 handlerObjectRemoved(part.UUID);
881 } 955 }
882 956
883 957 CleanAssemblies();
958
884 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 959 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
885 if (handlerScriptRemoved != null) 960 if (handlerScriptRemoved != null)
886 handlerScriptRemoved(itemID); 961 handlerScriptRemoved(itemID);
@@ -1022,7 +1097,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1022 return false; 1097 return false;
1023 1098
1024 uuids = m_PrimObjects[localID]; 1099 uuids = m_PrimObjects[localID];
1025 } 1100
1026 1101
1027 foreach (UUID itemID in uuids) 1102 foreach (UUID itemID in uuids)
1028 { 1103 {
@@ -1040,6 +1115,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1040 result = true; 1115 result = true;
1041 } 1116 }
1042 } 1117 }
1118 }
1043 1119
1044 return result; 1120 return result;
1045 } 1121 }
@@ -1139,12 +1215,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1139 private IScriptInstance GetInstance(UUID itemID) 1215 private IScriptInstance GetInstance(UUID itemID)
1140 { 1216 {
1141 IScriptInstance instance; 1217 IScriptInstance instance;
1142 lock (m_Scripts) 1218 lockScriptsForRead(true);
1219 if (!m_Scripts.ContainsKey(itemID))
1143 { 1220 {
1144 if (!m_Scripts.ContainsKey(itemID)) 1221 lockScriptsForRead(false);
1145 return null; 1222 return null;
1146 instance = m_Scripts[itemID];
1147 } 1223 }
1224 instance = m_Scripts[itemID];
1225 lockScriptsForRead(false);
1148 return instance; 1226 return instance;
1149 } 1227 }
1150 1228
@@ -1168,6 +1246,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1168 return false; 1246 return false;
1169 } 1247 }
1170 1248
1249 [DebuggerNonUserCode]
1171 public void ApiResetScript(UUID itemID) 1250 public void ApiResetScript(UUID itemID)
1172 { 1251 {
1173 IScriptInstance instance = GetInstance(itemID); 1252 IScriptInstance instance = GetInstance(itemID);
@@ -1219,6 +1298,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1219 return UUID.Zero; 1298 return UUID.Zero;
1220 } 1299 }
1221 1300
1301 [DebuggerNonUserCode]
1222 public void SetState(UUID itemID, string newState) 1302 public void SetState(UUID itemID, string newState)
1223 { 1303 {
1224 IScriptInstance instance = GetInstance(itemID); 1304 IScriptInstance instance = GetInstance(itemID);
@@ -1239,11 +1319,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1239 { 1319 {
1240 List<IScriptInstance> instances = new List<IScriptInstance>(); 1320 List<IScriptInstance> instances = new List<IScriptInstance>();
1241 1321
1242 lock (m_Scripts) 1322 lockScriptsForRead(true);
1243 { 1323 foreach (IScriptInstance instance in m_Scripts.Values)
1244 foreach (IScriptInstance instance in m_Scripts.Values)
1245 instances.Add(instance); 1324 instances.Add(instance);
1246 } 1325 lockScriptsForRead(false);
1247 1326
1248 foreach (IScriptInstance i in instances) 1327 foreach (IScriptInstance i in instances)
1249 { 1328 {
@@ -1615,5 +1694,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1615 1694
1616 instance.Resume(); 1695 instance.Resume();
1617 } 1696 }
1697
1698 public bool HasScript(UUID itemID, out bool running)
1699 {
1700 running = true;
1701
1702 IScriptInstance instance = GetInstance(itemID);
1703 if (instance == null)
1704 return false;
1705
1706 running = instance.Running;
1707 return true;
1708 }
1618 } 1709 }
1619} 1710}