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/LSL_Api.cs1720
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs341
14 files changed, 1517 insertions, 754 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/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index a6ca171..cd8353f 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())
293 { 351 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
356 {
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). 555
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 }
486 568
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 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 if (!UUID.TryParse(texture, out textureID)) 1925 if (!UUID.TryParse(texture, out textureID))
@@ -1793,6 +1965,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1793 1965
1794 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1966 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1795 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1796 Primitive.TextureEntry tex = part.Shape.Textures; 1971 Primitive.TextureEntry tex = part.Shape.Textures;
1797 if (face >= 0 && face < GetNumberOfSides(part)) 1972 if (face >= 0 && face < GetNumberOfSides(part))
1798 { 1973 {
@@ -1829,6 +2004,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1829 2004
1830 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2005 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1831 { 2006 {
2007 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2008 return;
2009
1832 Primitive.TextureEntry tex = part.Shape.Textures; 2010 Primitive.TextureEntry tex = part.Shape.Textures;
1833 if (face >= 0 && face < GetNumberOfSides(part)) 2011 if (face >= 0 && face < GetNumberOfSides(part))
1834 { 2012 {
@@ -1865,6 +2043,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 2043
1866 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2044 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1867 { 2045 {
2046 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2047 return;
2048
1868 Primitive.TextureEntry tex = part.Shape.Textures; 2049 Primitive.TextureEntry tex = part.Shape.Textures;
1869 if (face >= 0 && face < GetNumberOfSides(part)) 2050 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2051 {
@@ -1935,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1935 2116
1936 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2117 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1937 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1938 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2122 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1939 LSL_Vector currentPos = GetPartLocalPos(part); 2123 LSL_Vector currentPos = GetPartLocalPos(part);
1940 2124
@@ -1951,7 +2135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 } 2135 }
1952 else 2136 else
1953 { 2137 {
1954 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2138 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1955 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2139 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1956 SceneObjectGroup parent = part.ParentGroup; 2140 SceneObjectGroup parent = part.ParentGroup;
1957 parent.HasGroupChanged = true; 2141 parent.HasGroupChanged = true;
@@ -2034,6 +2218,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2034 2218
2035 protected void SetRot(SceneObjectPart part, Quaternion rot) 2219 protected void SetRot(SceneObjectPart part, Quaternion rot)
2036 { 2220 {
2221 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2222 return;
2223
2037 part.UpdateRotation(rot); 2224 part.UpdateRotation(rot);
2038 // Update rotation does not move the object in the physics scene if it's a linkset. 2225 // Update rotation does not move the object in the physics scene if it's a linkset.
2039 2226
@@ -2653,12 +2840,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2653 2840
2654 m_host.AddScriptLPS(1); 2841 m_host.AddScriptLPS(1);
2655 2842
2843 m_host.TaskInventory.LockItemsForRead(true);
2656 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2844 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2657 2845 m_host.TaskInventory.LockItemsForRead(false);
2658 lock (m_host.TaskInventory)
2659 {
2660 item = m_host.TaskInventory[invItemID];
2661 }
2662 2846
2663 if (item.PermsGranter == UUID.Zero) 2847 if (item.PermsGranter == UUID.Zero)
2664 return 0; 2848 return 0;
@@ -2733,6 +2917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2733 if (dist > m_ScriptDistanceFactor * 10.0f) 2917 if (dist > m_ScriptDistanceFactor * 10.0f)
2734 return; 2918 return;
2735 2919
2920 //Clone is thread-safe
2736 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2921 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2737 2922
2738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2795,6 +2980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 2980
2796 public void llLookAt(LSL_Vector target, double strength, double damping) 2981 public void llLookAt(LSL_Vector target, double strength, double damping)
2797 { 2982 {
2983 /*
2798 m_host.AddScriptLPS(1); 2984 m_host.AddScriptLPS(1);
2799 // Determine where we are looking from 2985 // Determine where we are looking from
2800 LSL_Vector from = llGetPos(); 2986 LSL_Vector from = llGetPos();
@@ -2814,10 +3000,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 // the angles of rotation in radians into rotation value 3000 // the angles of rotation in radians into rotation value
2815 3001
2816 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3002 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2817 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3003
2818 m_host.startLookAt(rotation, (float)damping, (float)strength); 3004 // This would only work if your physics system contains an APID controller:
3005 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3006 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3007
2819 // Orient the object to the angle calculated 3008 // Orient the object to the angle calculated
2820 //llSetRot(rot); 3009 llSetRot(rot);
3010 */
3011
3012 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3013 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3014 // http://bugs.meta7.com/view.php?id=28
3015 // - Tom
3016
3017 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3018 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3019
3020 }
3021
3022 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3023 {
3024 m_host.AddScriptLPS(1);
3025// NotImplemented("llRotLookAt");
3026 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3027
2821 } 3028 }
2822 3029
2823 public void llStopLookAt() 3030 public void llStopLookAt()
@@ -2866,13 +3073,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2866 { 3073 {
2867 TaskInventoryItem item; 3074 TaskInventoryItem item;
2868 3075
2869 lock (m_host.TaskInventory) 3076 m_host.TaskInventory.LockItemsForRead(true);
3077 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2870 { 3078 {
2871 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3079 m_host.TaskInventory.LockItemsForRead(false);
2872 return; 3080 return;
2873 else
2874 item = m_host.TaskInventory[InventorySelf()];
2875 } 3081 }
3082 else
3083 {
3084 item = m_host.TaskInventory[InventorySelf()];
3085 }
3086 m_host.TaskInventory.LockItemsForRead(false);
2876 3087
2877 if (item.PermsGranter != UUID.Zero) 3088 if (item.PermsGranter != UUID.Zero)
2878 { 3089 {
@@ -2894,13 +3105,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 { 3105 {
2895 TaskInventoryItem item; 3106 TaskInventoryItem item;
2896 3107
3108 m_host.TaskInventory.LockItemsForRead(true);
2897 lock (m_host.TaskInventory) 3109 lock (m_host.TaskInventory)
2898 { 3110 {
3111
2899 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3112 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3113 {
3114 m_host.TaskInventory.LockItemsForRead(false);
2900 return; 3115 return;
3116 }
2901 else 3117 else
3118 {
2902 item = m_host.TaskInventory[InventorySelf()]; 3119 item = m_host.TaskInventory[InventorySelf()];
3120 }
2903 } 3121 }
3122 m_host.TaskInventory.LockItemsForRead(false);
2904 3123
2905 m_host.AddScriptLPS(1); 3124 m_host.AddScriptLPS(1);
2906 3125
@@ -2932,18 +3151,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 { 3151 {
2933 m_host.AddScriptLPS(1); 3152 m_host.AddScriptLPS(1);
2934 3153
2935 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2936 return;
2937
2938 TaskInventoryItem item; 3154 TaskInventoryItem item;
2939 3155
2940 lock (m_host.TaskInventory) 3156 m_host.TaskInventory.LockItemsForRead(true);
3157
3158 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2941 { 3159 {
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3160 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3161 return;
2944 else
2945 item = m_host.TaskInventory[InventorySelf()];
2946 } 3162 }
3163 else
3164 {
3165 item = m_host.TaskInventory[InventorySelf()];
3166 }
3167
3168 m_host.TaskInventory.LockItemsForRead(false);
2947 3169
2948 if (item.PermsGranter != m_host.OwnerID) 3170 if (item.PermsGranter != m_host.OwnerID)
2949 return; 3171 return;
@@ -2954,10 +3176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3176
2955 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3177 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2956 3178
2957 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3179 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2958 if (attachmentsModule != null)
2959 attachmentsModule.AttachObject(presence.ControllingClient,
2960 grp, (uint)attachment, false);
2961 } 3180 }
2962 } 3181 }
2963 3182
@@ -2970,13 +3189,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2970 3189
2971 TaskInventoryItem item; 3190 TaskInventoryItem item;
2972 3191
2973 lock (m_host.TaskInventory) 3192 m_host.TaskInventory.LockItemsForRead(true);
3193
3194 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2974 { 3195 {
2975 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3196 m_host.TaskInventory.LockItemsForRead(false);
2976 return; 3197 return;
2977 else 3198 }
2978 item = m_host.TaskInventory[InventorySelf()]; 3199 else
3200 {
3201 item = m_host.TaskInventory[InventorySelf()];
2979 } 3202 }
3203 m_host.TaskInventory.LockItemsForRead(false);
3204
2980 3205
2981 if (item.PermsGranter != m_host.OwnerID) 3206 if (item.PermsGranter != m_host.OwnerID)
2982 return; 3207 return;
@@ -3015,6 +3240,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 3240
3016 public void llInstantMessage(string user, string message) 3241 public void llInstantMessage(string user, string message)
3017 { 3242 {
3243 UUID result;
3244 if (!UUID.TryParse(user, out result))
3245 {
3246 ShoutError("An invalid key was passed to llInstantMessage");
3247 ScriptSleep(2000);
3248 return;
3249 }
3250
3251
3018 m_host.AddScriptLPS(1); 3252 m_host.AddScriptLPS(1);
3019 3253
3020 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3254 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3029,14 +3263,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3029 UUID friendTransactionID = UUID.Random(); 3263 UUID friendTransactionID = UUID.Random();
3030 3264
3031 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3265 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3032 3266
3033 GridInstantMessage msg = new GridInstantMessage(); 3267 GridInstantMessage msg = new GridInstantMessage();
3034 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3268 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3035 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3269 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3036 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3270 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3037// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3271// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3038// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3272// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3039 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3273 DateTime dt = DateTime.UtcNow;
3274
3275 // Ticks from UtcNow, but make it look like local. Evil, huh?
3276 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3277
3278 try
3279 {
3280 // Convert that to the PST timezone
3281 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3282 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3283 }
3284 catch
3285 {
3286 // No logging here, as it could be VERY spammy
3287 }
3288
3289 // And make it look local again to fool the unix time util
3290 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3291
3292 msg.timestamp = (uint)Util.ToUnixTime(dt);
3293
3040 //if (client != null) 3294 //if (client != null)
3041 //{ 3295 //{
3042 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3296 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3050,13 +3304,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 msg.message = message.Substring(0, 1024); 3304 msg.message = message.Substring(0, 1024);
3051 else 3305 else
3052 msg.message = message; 3306 msg.message = message;
3053 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3307 msg.dialog = (byte)19; // MessageFromObject
3054 msg.fromGroup = false;// fromGroup; 3308 msg.fromGroup = false;// fromGroup;
3055 msg.offline = (byte)0; //offline; 3309 msg.offline = (byte)0; //offline;
3056 msg.ParentEstateID = 0; //ParentEstateID; 3310 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3057 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3311 msg.Position = new Vector3(m_host.AbsolutePosition);
3058 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3312 msg.RegionID = World.RegionInfo.RegionID.Guid;
3059 msg.binaryBucket = new byte[0];// binaryBucket; 3313 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3060 3314
3061 if (m_TransferModule != null) 3315 if (m_TransferModule != null)
3062 { 3316 {
@@ -3076,7 +3330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3076 } 3330 }
3077 3331
3078 emailModule.SendEmail(m_host.UUID, address, subject, message); 3332 emailModule.SendEmail(m_host.UUID, address, subject, message);
3079 ScriptSleep(20000); 3333 ScriptSleep(15000);
3080 } 3334 }
3081 3335
3082 public void llGetNextEmail(string address, string subject) 3336 public void llGetNextEmail(string address, string subject)
@@ -3178,13 +3432,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3178 m_host.AddScriptLPS(1); 3432 m_host.AddScriptLPS(1);
3179 } 3433 }
3180 3434
3181 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3182 {
3183 m_host.AddScriptLPS(1);
3184 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3185 m_host.RotLookAt(rot, (float)strength, (float)damping);
3186 }
3187
3188 public LSL_Integer llStringLength(string str) 3435 public LSL_Integer llStringLength(string str)
3189 { 3436 {
3190 m_host.AddScriptLPS(1); 3437 m_host.AddScriptLPS(1);
@@ -3208,14 +3455,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3208 3455
3209 TaskInventoryItem item; 3456 TaskInventoryItem item;
3210 3457
3211 lock (m_host.TaskInventory) 3458 m_host.TaskInventory.LockItemsForRead(true);
3459 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3212 { 3460 {
3213 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3461 m_host.TaskInventory.LockItemsForRead(false);
3214 return; 3462 return;
3215 else
3216 item = m_host.TaskInventory[InventorySelf()];
3217 } 3463 }
3218 3464 else
3465 {
3466 item = m_host.TaskInventory[InventorySelf()];
3467 }
3468 m_host.TaskInventory.LockItemsForRead(false);
3219 if (item.PermsGranter == UUID.Zero) 3469 if (item.PermsGranter == UUID.Zero)
3220 return; 3470 return;
3221 3471
@@ -3245,13 +3495,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3245 3495
3246 TaskInventoryItem item; 3496 TaskInventoryItem item;
3247 3497
3248 lock (m_host.TaskInventory) 3498 m_host.TaskInventory.LockItemsForRead(true);
3499 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3249 { 3500 {
3250 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3501 m_host.TaskInventory.LockItemsForRead(false);
3251 return; 3502 return;
3252 else 3503 }
3253 item = m_host.TaskInventory[InventorySelf()]; 3504 else
3505 {
3506 item = m_host.TaskInventory[InventorySelf()];
3254 } 3507 }
3508 m_host.TaskInventory.LockItemsForRead(false);
3509
3255 3510
3256 if (item.PermsGranter == UUID.Zero) 3511 if (item.PermsGranter == UUID.Zero)
3257 return; 3512 return;
@@ -3322,10 +3577,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 3577
3323 TaskInventoryItem item; 3578 TaskInventoryItem item;
3324 3579
3325 lock (m_host.TaskInventory) 3580
3581 m_host.TaskInventory.LockItemsForRead(true);
3582 if (!m_host.TaskInventory.ContainsKey(invItemID))
3583 {
3584 m_host.TaskInventory.LockItemsForRead(false);
3585 return;
3586 }
3587 else
3326 { 3588 {
3327 item = m_host.TaskInventory[invItemID]; 3589 item = m_host.TaskInventory[invItemID];
3328 } 3590 }
3591 m_host.TaskInventory.LockItemsForRead(false);
3329 3592
3330 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3593 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3331 { 3594 {
@@ -3357,11 +3620,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3357 3620
3358 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3621 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3359 { 3622 {
3360 lock (m_host.TaskInventory) 3623 m_host.TaskInventory.LockItemsForWrite(true);
3361 { 3624 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3362 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3625 m_host.TaskInventory[invItemID].PermsMask = perm;
3363 m_host.TaskInventory[invItemID].PermsMask = perm; 3626 m_host.TaskInventory.LockItemsForWrite(false);
3364 }
3365 3627
3366 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3628 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3367 "run_time_permissions", new Object[] { 3629 "run_time_permissions", new Object[] {
@@ -3381,11 +3643,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3381 3643
3382 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3644 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3383 { 3645 {
3384 lock (m_host.TaskInventory) 3646 m_host.TaskInventory.LockItemsForWrite(true);
3385 { 3647 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3386 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3648 m_host.TaskInventory[invItemID].PermsMask = perm;
3387 m_host.TaskInventory[invItemID].PermsMask = perm; 3649 m_host.TaskInventory.LockItemsForWrite(false);
3388 }
3389 3650
3390 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3651 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3391 "run_time_permissions", new Object[] { 3652 "run_time_permissions", new Object[] {
@@ -3406,11 +3667,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 3667
3407 if (!m_waitingForScriptAnswer) 3668 if (!m_waitingForScriptAnswer)
3408 { 3669 {
3409 lock (m_host.TaskInventory) 3670 m_host.TaskInventory.LockItemsForWrite(true);
3410 { 3671 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3411 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3672 m_host.TaskInventory[invItemID].PermsMask = 0;
3412 m_host.TaskInventory[invItemID].PermsMask = 0; 3673 m_host.TaskInventory.LockItemsForWrite(false);
3413 }
3414 3674
3415 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3675 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3416 m_waitingForScriptAnswer=true; 3676 m_waitingForScriptAnswer=true;
@@ -3445,10 +3705,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3445 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3705 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3446 llReleaseControls(); 3706 llReleaseControls();
3447 3707
3448 lock (m_host.TaskInventory) 3708
3449 { 3709 m_host.TaskInventory.LockItemsForWrite(true);
3450 m_host.TaskInventory[invItemID].PermsMask = answer; 3710 m_host.TaskInventory[invItemID].PermsMask = answer;
3451 } 3711 m_host.TaskInventory.LockItemsForWrite(false);
3712
3452 3713
3453 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3714 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3454 "run_time_permissions", new Object[] { 3715 "run_time_permissions", new Object[] {
@@ -3460,16 +3721,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 { 3721 {
3461 m_host.AddScriptLPS(1); 3722 m_host.AddScriptLPS(1);
3462 3723
3463 lock (m_host.TaskInventory) 3724 m_host.TaskInventory.LockItemsForRead(true);
3725
3726 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3464 { 3727 {
3465 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3728 if (item.Type == 10 && item.ItemID == m_itemID)
3466 { 3729 {
3467 if (item.Type == 10 && item.ItemID == m_itemID) 3730 m_host.TaskInventory.LockItemsForRead(false);
3468 { 3731 return item.PermsGranter.ToString();
3469 return item.PermsGranter.ToString();
3470 }
3471 } 3732 }
3472 } 3733 }
3734 m_host.TaskInventory.LockItemsForRead(false);
3473 3735
3474 return UUID.Zero.ToString(); 3736 return UUID.Zero.ToString();
3475 } 3737 }
@@ -3478,19 +3740,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 { 3740 {
3479 m_host.AddScriptLPS(1); 3741 m_host.AddScriptLPS(1);
3480 3742
3481 lock (m_host.TaskInventory) 3743 m_host.TaskInventory.LockItemsForRead(true);
3744
3745 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3482 { 3746 {
3483 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3747 if (item.Type == 10 && item.ItemID == m_itemID)
3484 { 3748 {
3485 if (item.Type == 10 && item.ItemID == m_itemID) 3749 int perms = item.PermsMask;
3486 { 3750 if (m_automaticLinkPermission)
3487 int perms = item.PermsMask; 3751 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3488 if (m_automaticLinkPermission) 3752 m_host.TaskInventory.LockItemsForRead(false);
3489 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3753 return perms;
3490 return perms;
3491 }
3492 } 3754 }
3493 } 3755 }
3756 m_host.TaskInventory.LockItemsForRead(false);
3494 3757
3495 return 0; 3758 return 0;
3496 } 3759 }
@@ -3512,9 +3775,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3775 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3513 { 3776 {
3514 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3777 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3515 3778 if (parts.Count > 0)
3516 foreach (SceneObjectPart part in parts) 3779 {
3517 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3780 try
3781 {
3782 parts[0].ParentGroup.areUpdatesSuspended = true;
3783 foreach (SceneObjectPart part in parts)
3784 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3785 }
3786 finally
3787 {
3788 parts[0].ParentGroup.areUpdatesSuspended = false;
3789 }
3790 }
3518 } 3791 }
3519 3792
3520 public void llCreateLink(string target, int parent) 3793 public void llCreateLink(string target, int parent)
@@ -3527,11 +3800,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 return; 3800 return;
3528 3801
3529 TaskInventoryItem item; 3802 TaskInventoryItem item;
3530 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForRead(true);
3531 { 3804 item = m_host.TaskInventory[invItemID];
3532 item = m_host.TaskInventory[invItemID]; 3805 m_host.TaskInventory.LockItemsForRead(false);
3533 } 3806
3534
3535 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3807 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3536 && !m_automaticLinkPermission) 3808 && !m_automaticLinkPermission)
3537 { 3809 {
@@ -3584,16 +3856,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3584 m_host.AddScriptLPS(1); 3856 m_host.AddScriptLPS(1);
3585 UUID invItemID = InventorySelf(); 3857 UUID invItemID = InventorySelf();
3586 3858
3587 lock (m_host.TaskInventory) 3859 m_host.TaskInventory.LockItemsForRead(true);
3588 {
3589 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3860 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3590 && !m_automaticLinkPermission) 3861 && !m_automaticLinkPermission)
3591 { 3862 {
3592 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3863 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3864 m_host.TaskInventory.LockItemsForRead(false);
3593 return; 3865 return;
3594 } 3866 }
3595 } 3867 m_host.TaskInventory.LockItemsForRead(false);
3596 3868
3597 if (linknum < ScriptBaseClass.LINK_THIS) 3869 if (linknum < ScriptBaseClass.LINK_THIS)
3598 return; 3870 return;
3599 3871
@@ -3632,10 +3904,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3632 // Restructuring Multiple Prims. 3904 // Restructuring Multiple Prims.
3633 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3905 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3634 parts.Remove(parentPrim.RootPart); 3906 parts.Remove(parentPrim.RootPart);
3635 foreach (SceneObjectPart part in parts) 3907 if (parts.Count > 0)
3636 { 3908 {
3637 parentPrim.DelinkFromGroup(part.LocalId, true); 3909 try
3910 {
3911 parts[0].ParentGroup.areUpdatesSuspended = true;
3912 foreach (SceneObjectPart part in parts)
3913 {
3914 parentPrim.DelinkFromGroup(part.LocalId, true);
3915 }
3916 }
3917 finally
3918 {
3919 parts[0].ParentGroup.areUpdatesSuspended = false;
3920 }
3638 } 3921 }
3922
3639 parentPrim.HasGroupChanged = true; 3923 parentPrim.HasGroupChanged = true;
3640 parentPrim.ScheduleGroupForFullUpdate(); 3924 parentPrim.ScheduleGroupForFullUpdate();
3641 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3925 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3644,11 +3928,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3644 { 3928 {
3645 SceneObjectPart newRoot = parts[0]; 3929 SceneObjectPart newRoot = parts[0];
3646 parts.Remove(newRoot); 3930 parts.Remove(newRoot);
3647 foreach (SceneObjectPart part in parts) 3931
3932 try
3648 { 3933 {
3649 part.UpdateFlag = 0; 3934 parts[0].ParentGroup.areUpdatesSuspended = true;
3650 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3935 foreach (SceneObjectPart part in parts)
3936 {
3937 part.UpdateFlag = 0;
3938 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3939 }
3651 } 3940 }
3941 finally
3942 {
3943 parts[0].ParentGroup.areUpdatesSuspended = false;
3944 }
3945
3946
3652 newRoot.ParentGroup.HasGroupChanged = true; 3947 newRoot.ParentGroup.HasGroupChanged = true;
3653 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3948 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3654 } 3949 }
@@ -3694,6 +3989,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 } 3989 }
3695 else 3990 else
3696 { 3991 {
3992 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
3993 {
3994 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3995
3996 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3997 if (avatars.Count > linknum)
3998 {
3999 return avatars[linknum].UUID.ToString();
4000 }
4001 }
3697 return UUID.Zero.ToString(); 4002 return UUID.Zero.ToString();
3698 } 4003 }
3699 } 4004 }
@@ -3770,17 +4075,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 m_host.AddScriptLPS(1); 4075 m_host.AddScriptLPS(1);
3771 int count = 0; 4076 int count = 0;
3772 4077
3773 lock (m_host.TaskInventory) 4078 m_host.TaskInventory.LockItemsForRead(true);
4079 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3774 { 4080 {
3775 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4081 if (inv.Value.Type == type || type == -1)
3776 { 4082 {
3777 if (inv.Value.Type == type || type == -1) 4083 count = count + 1;
3778 {
3779 count = count + 1;
3780 }
3781 } 4084 }
3782 } 4085 }
3783 4086
4087 m_host.TaskInventory.LockItemsForRead(false);
3784 return count; 4088 return count;
3785 } 4089 }
3786 4090
@@ -3789,16 +4093,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3789 m_host.AddScriptLPS(1); 4093 m_host.AddScriptLPS(1);
3790 ArrayList keys = new ArrayList(); 4094 ArrayList keys = new ArrayList();
3791 4095
3792 lock (m_host.TaskInventory) 4096 m_host.TaskInventory.LockItemsForRead(true);
4097 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3793 { 4098 {
3794 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4099 if (inv.Value.Type == type || type == -1)
3795 { 4100 {
3796 if (inv.Value.Type == type || type == -1) 4101 keys.Add(inv.Value.Name);
3797 {
3798 keys.Add(inv.Value.Name);
3799 }
3800 } 4102 }
3801 } 4103 }
4104 m_host.TaskInventory.LockItemsForRead(false);
3802 4105
3803 if (keys.Count == 0) 4106 if (keys.Count == 0)
3804 { 4107 {
@@ -3835,20 +4138,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3835 } 4138 }
3836 4139
3837 // move the first object found with this inventory name 4140 // move the first object found with this inventory name
3838 lock (m_host.TaskInventory) 4141 m_host.TaskInventory.LockItemsForRead(true);
4142 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3839 { 4143 {
3840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4144 if (inv.Value.Name == inventory)
3841 { 4145 {
3842 if (inv.Value.Name == inventory) 4146 found = true;
3843 { 4147 objId = inv.Key;
3844 found = true; 4148 assetType = inv.Value.Type;
3845 objId = inv.Key; 4149 objName = inv.Value.Name;
3846 assetType = inv.Value.Type; 4150 break;
3847 objName = inv.Value.Name;
3848 break;
3849 }
3850 } 4151 }
3851 } 4152 }
4153 m_host.TaskInventory.LockItemsForRead(false);
3852 4154
3853 if (!found) 4155 if (!found)
3854 { 4156 {
@@ -3856,9 +4158,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4158 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3857 } 4159 }
3858 4160
3859 // check if destination is an avatar 4161 // check if destination is an object
3860 if (World.GetScenePresence(destId) != null) 4162 if (World.GetSceneObjectPart(destId) != null)
3861 { 4163 {
4164 // destination is an object
4165 World.MoveTaskInventoryItem(destId, m_host, objId);
4166 }
4167 else
4168 {
4169 ScenePresence presence = World.GetScenePresence(destId);
4170
4171 if (presence == null)
4172 {
4173 UserAccount account =
4174 World.UserAccountService.GetUserAccount(
4175 World.RegionInfo.ScopeID,
4176 destId);
4177
4178 if (account == null)
4179 {
4180 llSay(0, "Can't find destination "+destId.ToString());
4181 return;
4182 }
4183 }
4184
3862 // destination is an avatar 4185 // destination is an avatar
3863 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4186 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3864 4187
@@ -3882,31 +4205,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3882 4205
3883 if (m_TransferModule != null) 4206 if (m_TransferModule != null)
3884 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4207 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4208
4209 //This delay should only occur when giving inventory to avatars.
4210 ScriptSleep(3000);
3885 } 4211 }
3886 else
3887 {
3888 // destination is an object
3889 World.MoveTaskInventoryItem(destId, m_host, objId);
3890 }
3891 ScriptSleep(3000);
3892 } 4212 }
3893 4213
4214 [DebuggerNonUserCode]
3894 public void llRemoveInventory(string name) 4215 public void llRemoveInventory(string name)
3895 { 4216 {
3896 m_host.AddScriptLPS(1); 4217 m_host.AddScriptLPS(1);
3897 4218
3898 lock (m_host.TaskInventory) 4219 List<TaskInventoryItem> inv;
4220 try
3899 { 4221 {
3900 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4222 m_host.TaskInventory.LockItemsForRead(true);
4223 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4224 }
4225 finally
4226 {
4227 m_host.TaskInventory.LockItemsForRead(false);
4228 }
4229 foreach (TaskInventoryItem item in inv)
4230 {
4231 if (item.Name == name)
3901 { 4232 {
3902 if (item.Name == name) 4233 if (item.ItemID == m_itemID)
3903 { 4234 throw new ScriptDeleteException();
3904 if (item.ItemID == m_itemID) 4235 else
3905 throw new ScriptDeleteException(); 4236 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3906 else 4237 return;
3907 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3908 return;
3909 }
3910 } 4238 }
3911 } 4239 }
3912 } 4240 }
@@ -3972,6 +4300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 ce.time = Util.EnvironmentTickCount(); 4300 ce.time = Util.EnvironmentTickCount();
3973 ce.account = account; 4301 ce.account = account;
3974 ce.pinfo = pinfo; 4302 ce.pinfo = pinfo;
4303 m_userInfoCache[uuid] = ce;
3975 } 4304 }
3976 else 4305 else
3977 { 4306 {
@@ -4047,6 +4376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4047 { 4376 {
4048 m_host.AddScriptLPS(1); 4377 m_host.AddScriptLPS(1);
4049 4378
4379 //Clone is thread safe
4050 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4380 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4051 4381
4052 foreach (TaskInventoryItem item in itemDictionary.Values) 4382 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4100,6 +4430,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4100 ScenePresence presence = World.GetScenePresence(agentId); 4430 ScenePresence presence = World.GetScenePresence(agentId);
4101 if (presence != null) 4431 if (presence != null)
4102 { 4432 {
4433 // agent must not be a god
4434 if (presence.GodLevel >= 200) return;
4435
4103 // agent must be over the owners land 4436 // agent must be over the owners land
4104 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4437 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4105 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4438 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4159,17 +4492,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4159 UUID soundId = UUID.Zero; 4492 UUID soundId = UUID.Zero;
4160 if (!UUID.TryParse(impact_sound, out soundId)) 4493 if (!UUID.TryParse(impact_sound, out soundId))
4161 { 4494 {
4162 lock (m_host.TaskInventory) 4495 m_host.TaskInventory.LockItemsForRead(true);
4496 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4163 { 4497 {
4164 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4498 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4165 { 4499 {
4166 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4500 soundId = item.AssetID;
4167 { 4501 break;
4168 soundId = item.AssetID;
4169 break;
4170 }
4171 } 4502 }
4172 } 4503 }
4504 m_host.TaskInventory.LockItemsForRead(false);
4173 } 4505 }
4174 m_host.CollisionSound = soundId; 4506 m_host.CollisionSound = soundId;
4175 m_host.CollisionSoundVolume = (float)impact_volume; 4507 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4215,6 +4547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4215 UUID partItemID; 4547 UUID partItemID;
4216 foreach (SceneObjectPart part in parts) 4548 foreach (SceneObjectPart part in parts)
4217 { 4549 {
4550 //Clone is thread safe
4218 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4551 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4219 4552
4220 foreach (TaskInventoryItem item in itemsDictionary.Values) 4553 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4429,17 +4762,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4429 4762
4430 m_host.AddScriptLPS(1); 4763 m_host.AddScriptLPS(1);
4431 4764
4432 lock (m_host.TaskInventory) 4765 m_host.TaskInventory.LockItemsForRead(true);
4766 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4433 { 4767 {
4434 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4768 if (item.Type == 10 && item.ItemID == m_itemID)
4435 { 4769 {
4436 if (item.Type == 10 && item.ItemID == m_itemID) 4770 result = item.Name!=null?item.Name:String.Empty;
4437 { 4771 break;
4438 result = item.Name != null ? item.Name : String.Empty;
4439 break;
4440 }
4441 } 4772 }
4442 } 4773 }
4774 m_host.TaskInventory.LockItemsForRead(false);
4443 4775
4444 return result; 4776 return result;
4445 } 4777 }
@@ -4592,23 +4924,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4592 { 4924 {
4593 m_host.AddScriptLPS(1); 4925 m_host.AddScriptLPS(1);
4594 4926
4595 lock (m_host.TaskInventory) 4927 m_host.TaskInventory.LockItemsForRead(true);
4928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4596 { 4929 {
4597 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4930 if (inv.Value.Name == name)
4598 { 4931 {
4599 if (inv.Value.Name == name) 4932 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4600 { 4933 {
4601 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4934 m_host.TaskInventory.LockItemsForRead(false);
4602 { 4935 return inv.Value.AssetID.ToString();
4603 return inv.Value.AssetID.ToString(); 4936 }
4604 } 4937 else
4605 else 4938 {
4606 { 4939 m_host.TaskInventory.LockItemsForRead(false);
4607 return UUID.Zero.ToString(); 4940 return UUID.Zero.ToString();
4608 }
4609 } 4941 }
4610 } 4942 }
4611 } 4943 }
4944 m_host.TaskInventory.LockItemsForRead(false);
4612 4945
4613 return UUID.Zero.ToString(); 4946 return UUID.Zero.ToString();
4614 } 4947 }
@@ -4761,14 +5094,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5094 {
4762 m_host.AddScriptLPS(1); 5095 m_host.AddScriptLPS(1);
4763 5096
4764 if (src == null) 5097 return src.Length;
4765 {
4766 return 0;
4767 }
4768 else
4769 {
4770 return src.Length;
4771 }
4772 } 5098 }
4773 5099
4774 public LSL_Integer llList2Integer(LSL_List src, int index) 5100 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4814,7 +5140,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4814 else if (src.Data[index] is LSL_Float) 5140 else if (src.Data[index] is LSL_Float)
4815 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5141 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4816 else if (src.Data[index] is LSL_String) 5142 else if (src.Data[index] is LSL_String)
4817 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5143 {
5144 string str = ((LSL_String) src.Data[index]).m_string;
5145 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5146 if (m != Match.Empty)
5147 {
5148 str = m.Value;
5149 double d = 0.0;
5150 if (!Double.TryParse(str, out d))
5151 return 0.0;
5152
5153 return d;
5154 }
5155 return 0.0;
5156 }
4818 return Convert.ToDouble(src.Data[index]); 5157 return Convert.ToDouble(src.Data[index]);
4819 } 5158 }
4820 catch (FormatException) 5159 catch (FormatException)
@@ -5499,7 +5838,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5499 public void llSetSoundQueueing(int queue) 5838 public void llSetSoundQueueing(int queue)
5500 { 5839 {
5501 m_host.AddScriptLPS(1); 5840 m_host.AddScriptLPS(1);
5502 NotImplemented("llSetSoundQueueing");
5503 } 5841 }
5504 5842
5505 public void llSetSoundRadius(double radius) 5843 public void llSetSoundRadius(double radius)
@@ -5544,10 +5882,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5544 m_host.AddScriptLPS(1); 5882 m_host.AddScriptLPS(1);
5545 5883
5546 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5884 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5547 5885 if (parts.Count > 0)
5548 foreach (var part in parts)
5549 { 5886 {
5550 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5887 try
5888 {
5889 parts[0].ParentGroup.areUpdatesSuspended = true;
5890 foreach (var part in parts)
5891 {
5892 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5893 }
5894 }
5895 finally
5896 {
5897 parts[0].ParentGroup.areUpdatesSuspended = false;
5898 }
5551 } 5899 }
5552 } 5900 }
5553 5901
@@ -5801,7 +6149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5801 return m_host.ParentGroup.RootPart.AttachmentPoint; 6149 return m_host.ParentGroup.RootPart.AttachmentPoint;
5802 } 6150 }
5803 6151
5804 public LSL_Integer llGetFreeMemory() 6152 public virtual LSL_Integer llGetFreeMemory()
5805 { 6153 {
5806 m_host.AddScriptLPS(1); 6154 m_host.AddScriptLPS(1);
5807 // Make scripts designed for LSO happy 6155 // Make scripts designed for LSO happy
@@ -6112,14 +6460,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6112 6460
6113 protected UUID GetTaskInventoryItem(string name) 6461 protected UUID GetTaskInventoryItem(string name)
6114 { 6462 {
6115 lock (m_host.TaskInventory) 6463 m_host.TaskInventory.LockItemsForRead(true);
6464 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6116 { 6465 {
6117 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6466 if (inv.Value.Name == name)
6118 { 6467 {
6119 if (inv.Value.Name == name) 6468 m_host.TaskInventory.LockItemsForRead(false);
6120 return inv.Key; 6469 return inv.Key;
6121 } 6470 }
6122 } 6471 }
6472 m_host.TaskInventory.LockItemsForRead(false);
6123 6473
6124 return UUID.Zero; 6474 return UUID.Zero;
6125 } 6475 }
@@ -6447,22 +6797,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6447 } 6797 }
6448 6798
6449 // copy the first script found with this inventory name 6799 // copy the first script found with this inventory name
6450 lock (m_host.TaskInventory) 6800 m_host.TaskInventory.LockItemsForRead(true);
6801 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6451 { 6802 {
6452 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6803 if (inv.Value.Name == name)
6453 { 6804 {
6454 if (inv.Value.Name == name) 6805 // make sure the object is a script
6806 if (10 == inv.Value.Type)
6455 { 6807 {
6456 // make sure the object is a script 6808 found = true;
6457 if (10 == inv.Value.Type) 6809 srcId = inv.Key;
6458 { 6810 break;
6459 found = true;
6460 srcId = inv.Key;
6461 break;
6462 }
6463 } 6811 }
6464 } 6812 }
6465 } 6813 }
6814 m_host.TaskInventory.LockItemsForRead(false);
6466 6815
6467 if (!found) 6816 if (!found)
6468 { 6817 {
@@ -6546,6 +6895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6546 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6895 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6547 { 6896 {
6548 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6897 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6899 return shapeBlock;
6549 6900
6550 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6901 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6551 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6902 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6621,6 +6972,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6621 6972
6622 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6973 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6623 { 6974 {
6975 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6976 return;
6977
6624 ObjectShapePacket.ObjectDataBlock shapeBlock; 6978 ObjectShapePacket.ObjectDataBlock shapeBlock;
6625 6979
6626 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6980 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6670,6 +7024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6670 7024
6671 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7025 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6672 { 7026 {
7027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7028 return;
7029
6673 ObjectShapePacket.ObjectDataBlock shapeBlock; 7030 ObjectShapePacket.ObjectDataBlock shapeBlock;
6674 7031
6675 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7032 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6712,6 +7069,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6712 7069
6713 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) 7070 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)
6714 { 7071 {
7072 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7073 return;
7074
6715 ObjectShapePacket.ObjectDataBlock shapeBlock; 7075 ObjectShapePacket.ObjectDataBlock shapeBlock;
6716 7076
6717 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7077 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6838,6 +7198,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6838 7198
6839 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7199 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6840 { 7200 {
7201 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7202 return;
7203
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7204 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6842 UUID sculptId; 7205 UUID sculptId;
6843 7206
@@ -6853,13 +7216,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6853 shapeBlock.PathScaleX = 100; 7216 shapeBlock.PathScaleX = 100;
6854 shapeBlock.PathScaleY = 150; 7217 shapeBlock.PathScaleY = 150;
6855 7218
6856 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7219 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6857 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7220 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6858 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7221 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6859 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7222 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6860 { 7223 {
6861 // default 7224 // default
6862 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7225 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6863 } 7226 }
6864 7227
6865 // retain pathcurve 7228 // retain pathcurve
@@ -6876,23 +7239,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6876 SetPrimParams(m_host, rules); 7239 SetPrimParams(m_host, rules);
6877 } 7240 }
6878 7241
6879 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7242 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6880 { 7243 {
6881 m_host.AddScriptLPS(1); 7244 m_host.AddScriptLPS(1);
6882 7245
6883 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7246 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7247 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7248 if (parts.Count>0)
7249 {
7250 try
7251 {
7252 parts[0].ParentGroup.areUpdatesSuspended = true;
7253 foreach (SceneObjectPart part in parts)
7254 SetPrimParams(part, rules);
7255 }
7256 finally
7257 {
7258 parts[0].ParentGroup.areUpdatesSuspended = false;
7259 }
7260 }
7261 if (avatars.Count > 0)
7262 {
7263 foreach (ScenePresence avatar in avatars)
7264 SetPrimParams(avatar, rules);
7265 }
7266 }
6884 7267
6885 foreach (SceneObjectPart part in parts) 7268 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6886 SetPrimParams(part, rules); 7269 {
7270 llSetLinkPrimitiveParamsFast(linknumber, rules);
7271 ScriptSleep(200);
6887 } 7272 }
6888 7273
6889 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7274 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6890 { 7275 {
6891 llSetLinkPrimitiveParams(linknumber, rules); 7276 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7277 //We only support PRIM_POSITION and PRIM_ROTATION
7278
7279 int idx = 0;
7280
7281 while (idx < rules.Length)
7282 {
7283 int code = rules.GetLSLIntegerItem(idx++);
7284
7285 int remain = rules.Length - idx;
7286
7287
7288
7289 switch (code)
7290 {
7291 case (int)ScriptBaseClass.PRIM_POSITION:
7292 if (remain < 1)
7293 return;
7294 LSL_Vector v;
7295 v = rules.GetVector3Item(idx++);
7296 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7297 av.SendFullUpdateToAllClients();
7298
7299 break;
7300
7301 case (int)ScriptBaseClass.PRIM_ROTATION:
7302 if (remain < 1)
7303 return;
7304 LSL_Rotation r;
7305 r = rules.GetQuaternionItem(idx++);
7306 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7307 av.SendFullUpdateToAllClients();
7308 break;
7309 }
7310 }
7311
6892 } 7312 }
6893 7313
6894 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7314 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6895 { 7315 {
7316 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7317 return;
7318
6896 int idx = 0; 7319 int idx = 0;
6897 7320
6898 while (idx < rules.Length) 7321 while (idx < rules.Length)
@@ -7409,13 +7832,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7409 public LSL_Integer llGetNumberOfPrims() 7832 public LSL_Integer llGetNumberOfPrims()
7410 { 7833 {
7411 m_host.AddScriptLPS(1); 7834 m_host.AddScriptLPS(1);
7412 int avatarCount = 0; 7835 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7413 World.ForEachScenePresence(delegate(ScenePresence presence) 7836
7414 {
7415 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7416 avatarCount++;
7417 });
7418
7419 return m_host.ParentGroup.PrimCount + avatarCount; 7837 return m_host.ParentGroup.PrimCount + avatarCount;
7420 } 7838 }
7421 7839
@@ -7431,55 +7849,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7431 m_host.AddScriptLPS(1); 7849 m_host.AddScriptLPS(1);
7432 UUID objID = UUID.Zero; 7850 UUID objID = UUID.Zero;
7433 LSL_List result = new LSL_List(); 7851 LSL_List result = new LSL_List();
7852
7853 // If the ID is not valid, return null result
7434 if (!UUID.TryParse(obj, out objID)) 7854 if (!UUID.TryParse(obj, out objID))
7435 { 7855 {
7436 result.Add(new LSL_Vector()); 7856 result.Add(new LSL_Vector());
7437 result.Add(new LSL_Vector()); 7857 result.Add(new LSL_Vector());
7438 return result; 7858 return result;
7439 } 7859 }
7860
7861 // Check if this is an attached prim. If so, replace
7862 // the UUID with the avatar UUID and report it's bounding box
7863 SceneObjectPart part = World.GetSceneObjectPart(objID);
7864 if (part != null && part.ParentGroup.IsAttachment)
7865 objID = part.ParentGroup.RootPart.AttachedAvatar;
7866
7867 // Find out if this is an avatar ID. If so, return it's box
7440 ScenePresence presence = World.GetScenePresence(objID); 7868 ScenePresence presence = World.GetScenePresence(objID);
7441 if (presence != null) 7869 if (presence != null)
7442 { 7870 {
7443 if (presence.ParentID == 0) // not sat on an object 7871 // As per LSL Wiki, there is no difference between sitting
7872 // and standing avatar since server 1.36
7873 LSL_Vector lower;
7874 LSL_Vector upper;
7875 if (presence.Animator.Animations.DefaultAnimation.AnimID
7876 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7444 { 7877 {
7445 LSL_Vector lower; 7878 // This is for ground sitting avatars
7446 LSL_Vector upper; 7879 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7447 if (presence.Animator.Animations.DefaultAnimation.AnimID 7880 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7448 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7881 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7449 {
7450 // This is for ground sitting avatars
7451 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7452 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7453 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7454 }
7455 else
7456 {
7457 // This is for standing/flying avatars
7458 float height = presence.Appearance.AvatarHeight / 2.0f;
7459 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7460 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7461 }
7462 result.Add(lower);
7463 result.Add(upper);
7464 return result;
7465 } 7882 }
7466 else 7883 else
7467 { 7884 {
7468 // sitting on an object so we need the bounding box of that 7885 // This is for standing/flying avatars
7469 // which should include the avatar so set the UUID to the 7886 float height = presence.Appearance.AvatarHeight / 2.0f;
7470 // UUID of the object the avatar is sat on and allow it to fall through 7887 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7471 // to processing an object 7888 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7472 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7473 objID = p.UUID;
7474 } 7889 }
7890
7891 // Adjust to the documented error offsets (see LSL Wiki)
7892 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7893 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7894
7895 if (lower.x > upper.x)
7896 lower.x = upper.x;
7897 if (lower.y > upper.y)
7898 lower.y = upper.y;
7899 if (lower.z > upper.z)
7900 lower.z = upper.z;
7901
7902 result.Add(lower);
7903 result.Add(upper);
7904 return result;
7475 } 7905 }
7476 SceneObjectPart part = World.GetSceneObjectPart(objID); 7906
7907 part = World.GetSceneObjectPart(objID);
7477 // Currently only works for single prims without a sitting avatar 7908 // Currently only works for single prims without a sitting avatar
7478 if (part != null) 7909 if (part != null)
7479 { 7910 {
7480 Vector3 halfSize = part.Scale / 2.0f; 7911 float minX;
7481 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7912 float maxX;
7482 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7913 float minY;
7914 float maxY;
7915 float minZ;
7916 float maxZ;
7917
7918 // This BBox is in sim coordinates, with the offset being
7919 // a contained point.
7920 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7921 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7922
7923 minX -= offsets[0].X;
7924 maxX -= offsets[0].X;
7925 minY -= offsets[0].Y;
7926 maxY -= offsets[0].Y;
7927 minZ -= offsets[0].Z;
7928 maxZ -= offsets[0].Z;
7929
7930 LSL_Vector lower;
7931 LSL_Vector upper;
7932
7933 // Adjust to the documented error offsets (see LSL Wiki)
7934 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7935 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7936
7937 if (lower.x > upper.x)
7938 lower.x = upper.x;
7939 if (lower.y > upper.y)
7940 lower.y = upper.y;
7941 if (lower.z > upper.z)
7942 lower.z = upper.z;
7943
7483 result.Add(lower); 7944 result.Add(lower);
7484 result.Add(upper); 7945 result.Add(upper);
7485 return result; 7946 return result;
@@ -7724,24 +8185,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7724 break; 8185 break;
7725 8186
7726 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8187 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7727 // TODO--------------
7728 if (remain < 1) 8188 if (remain < 1)
7729 return res; 8189 return res;
8190 face = (int)rules.GetLSLIntegerItem(idx++);
7730 8191
7731 face=(int)rules.GetLSLIntegerItem(idx++); 8192 tex = part.Shape.Textures;
7732 8193 int shiny;
7733 res.Add(new LSL_Integer(0)); 8194 if (face == ScriptBaseClass.ALL_SIDES)
7734 res.Add(new LSL_Integer(0)); 8195 {
8196 for (face = 0; face < GetNumberOfSides(part); face++)
8197 {
8198 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8199 if (shinyness == Shininess.High)
8200 {
8201 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8202 }
8203 else if (shinyness == Shininess.Medium)
8204 {
8205 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8206 }
8207 else if (shinyness == Shininess.Low)
8208 {
8209 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8210 }
8211 else
8212 {
8213 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8214 }
8215 res.Add(new LSL_Integer(shiny));
8216 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8217 }
8218 }
8219 else
8220 {
8221 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8222 if (shinyness == Shininess.High)
8223 {
8224 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8225 }
8226 else if (shinyness == Shininess.Medium)
8227 {
8228 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8229 }
8230 else if (shinyness == Shininess.Low)
8231 {
8232 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8233 }
8234 else
8235 {
8236 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8237 }
8238 res.Add(new LSL_Integer(shiny));
8239 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8240 }
7735 break; 8241 break;
7736 8242
7737 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8243 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7738 // TODO--------------
7739 if (remain < 1) 8244 if (remain < 1)
7740 return res; 8245 return res;
8246 face = (int)rules.GetLSLIntegerItem(idx++);
7741 8247
7742 face=(int)rules.GetLSLIntegerItem(idx++); 8248 tex = part.Shape.Textures;
7743 8249 int fullbright;
7744 res.Add(new LSL_Integer(0)); 8250 if (face == ScriptBaseClass.ALL_SIDES)
8251 {
8252 for (face = 0; face < GetNumberOfSides(part); face++)
8253 {
8254 if (tex.GetFace((uint)face).Fullbright == true)
8255 {
8256 fullbright = ScriptBaseClass.TRUE;
8257 }
8258 else
8259 {
8260 fullbright = ScriptBaseClass.FALSE;
8261 }
8262 res.Add(new LSL_Integer(fullbright));
8263 }
8264 }
8265 else
8266 {
8267 if (tex.GetFace((uint)face).Fullbright == true)
8268 {
8269 fullbright = ScriptBaseClass.TRUE;
8270 }
8271 else
8272 {
8273 fullbright = ScriptBaseClass.FALSE;
8274 }
8275 res.Add(new LSL_Integer(fullbright));
8276 }
7745 break; 8277 break;
7746 8278
7747 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8279 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7762,14 +8294,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7762 break; 8294 break;
7763 8295
7764 case (int)ScriptBaseClass.PRIM_TEXGEN: 8296 case (int)ScriptBaseClass.PRIM_TEXGEN:
7765 // TODO--------------
7766 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8297 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7767 if (remain < 1) 8298 if (remain < 1)
7768 return res; 8299 return res;
8300 face = (int)rules.GetLSLIntegerItem(idx++);
7769 8301
7770 face=(int)rules.GetLSLIntegerItem(idx++); 8302 tex = part.Shape.Textures;
7771 8303 if (face == ScriptBaseClass.ALL_SIDES)
7772 res.Add(new LSL_Integer(0)); 8304 {
8305 for (face = 0; face < GetNumberOfSides(part); face++)
8306 {
8307 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8308 {
8309 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8310 }
8311 else
8312 {
8313 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8314 }
8315 }
8316 }
8317 else
8318 {
8319 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8320 {
8321 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8322 }
8323 else
8324 {
8325 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8326 }
8327 }
7773 break; 8328 break;
7774 8329
7775 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8330 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7788,13 +8343,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7788 break; 8343 break;
7789 8344
7790 case (int)ScriptBaseClass.PRIM_GLOW: 8345 case (int)ScriptBaseClass.PRIM_GLOW:
7791 // TODO--------------
7792 if (remain < 1) 8346 if (remain < 1)
7793 return res; 8347 return res;
8348 face = (int)rules.GetLSLIntegerItem(idx++);
7794 8349
7795 face=(int)rules.GetLSLIntegerItem(idx++); 8350 tex = part.Shape.Textures;
7796 8351 float primglow;
7797 res.Add(new LSL_Float(0)); 8352 if (face == ScriptBaseClass.ALL_SIDES)
8353 {
8354 for (face = 0; face < GetNumberOfSides(part); face++)
8355 {
8356 primglow = tex.GetFace((uint)face).Glow;
8357 res.Add(new LSL_Float(primglow));
8358 }
8359 }
8360 else
8361 {
8362 primglow = tex.GetFace((uint)face).Glow;
8363 res.Add(new LSL_Float(primglow));
8364 }
7798 break; 8365 break;
7799 case (int)ScriptBaseClass.PRIM_TEXT: 8366 case (int)ScriptBaseClass.PRIM_TEXT:
7800 Color4 textColor = part.GetTextColor(); 8367 Color4 textColor = part.GetTextColor();
@@ -8335,8 +8902,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8335 // The function returns an ordered list 8902 // The function returns an ordered list
8336 // representing the tokens found in the supplied 8903 // representing the tokens found in the supplied
8337 // sources string. If two successive tokenizers 8904 // sources string. If two successive tokenizers
8338 // are encountered, then a NULL entry is added 8905 // are encountered, then a null-string entry is
8339 // to the list. 8906 // added to the list.
8340 // 8907 //
8341 // It is a precondition that the source and 8908 // It is a precondition that the source and
8342 // toekizer lisst are non-null. If they are null, 8909 // toekizer lisst are non-null. If they are null,
@@ -8344,7 +8911,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8344 // while their lengths are being determined. 8911 // while their lengths are being determined.
8345 // 8912 //
8346 // A small amount of working memoryis required 8913 // A small amount of working memoryis required
8347 // of approximately 8*#tokenizers. 8914 // of approximately 8*#tokenizers + 8*srcstrlen.
8348 // 8915 //
8349 // There are many ways in which this function 8916 // There are many ways in which this function
8350 // can be implemented, this implementation is 8917 // can be implemented, this implementation is
@@ -8360,29 +8927,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8360 // and eliminates redundant tokenizers as soon 8927 // and eliminates redundant tokenizers as soon
8361 // as is possible. 8928 // as is possible.
8362 // 8929 //
8363 // The implementation tries to avoid any copying 8930 // The implementation tries to minimize temporary
8364 // of arrays or other objects. 8931 // garbage generation.
8365 // </remarks> 8932 // </remarks>
8366 8933
8367 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 8934 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8368 { 8935 {
8369 int beginning = 0; 8936 return ParseString2List(src, separators, spacers, true);
8370 int srclen = src.Length; 8937 }
8371 int seplen = separators.Length;
8372 object[] separray = separators.Data;
8373 int spclen = spacers.Length;
8374 object[] spcarray = spacers.Data;
8375 int mlen = seplen+spclen;
8376
8377 int[] offset = new int[mlen+1];
8378 bool[] active = new bool[mlen];
8379 8938
8380 int best; 8939 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8381 int j; 8940 {
8941 int srclen = src.Length;
8942 int seplen = separators.Length;
8943 object[] separray = separators.Data;
8944 int spclen = spacers.Length;
8945 object[] spcarray = spacers.Data;
8946 int dellen = 0;
8947 string[] delarray = new string[seplen+spclen];
8382 8948
8383 // Initial capacity reduces resize cost 8949 int outlen = 0;
8950 string[] outarray = new string[srclen*2+1];
8384 8951
8385 LSL_List tokens = new LSL_List(); 8952 int i, j;
8953 string d;
8386 8954
8387 // All entries are initially valid 8955 // All entries are initially valid
8388 8956
@@ -8398,53 +8966,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8398 8966
8399 // Scan for separators 8967 // Scan for separators
8400 8968
8401 for (j = 0; j < seplen; j++) 8969 for (i = 0; i < spclen; i ++) {
8402 { 8970 d = spcarray[i].ToString();
8403 if (active[j]) 8971 if (d.Length > 0) {
8404 { 8972 delarray[dellen++] = d;
8405 // scan all of the markers 8973 }
8406 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 8974 }
8407 { 8975
8408 // not present at all 8976 /*
8409 active[j] = false; 8977 * Scan through source string from beginning to end.
8410 } 8978 */
8411 else 8979 for (i = 0;;) {
8412 { 8980
8413 // present and correct 8981 /*
8414 if (offset[j] < offset[best]) 8982 * Find earliest delimeter in src starting at i (if any).
8415 { 8983 */
8416 // closest so far 8984 int earliestDel = -1;
8417 best = j; 8985 int earliestSrc = srclen;
8418 if (offset[best] == beginning) 8986 string earliestStr = null;
8419 break; 8987 for (j = 0; j < dellen; j ++) {
8420 } 8988 d = delarray[j];
8421 } 8989 if (d != null) {
8422 } 8990 int index = src.IndexOf(d, i);
8423 } 8991 if (index < 0) {
8424 8992 delarray[j] = null; // delim nowhere in src, don't check it anymore
8425 // Scan for spacers 8993 } else if (index < earliestSrc) {
8426 8994 earliestSrc = index; // where delimeter starts in source string
8427 if (offset[best] != beginning) 8995 earliestDel = j; // where delimeter is in delarray[]
8428 { 8996 earliestStr = d; // the delimeter string from delarray[]
8429 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8997 if (index == i) break; // can't do any better than found at beg of string
8430 {
8431 if (active[j])
8432 {
8433 // scan all of the markers
8434 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8435 {
8436 // not present at all
8437 active[j] = false;
8438 }
8439 else
8440 {
8441 // present and correct
8442 if (offset[j] < offset[best])
8443 {
8444 // closest so far
8445 best = j;
8446 }
8447 }
8448 } 8998 }
8449 } 8999 }
8450 } 9000 }
@@ -8490,7 +9040,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8490 tokens.Add(new LSL_String("")); 9040 tokens.Add(new LSL_String(""));
8491 } 9041 }
8492 9042
8493 return tokens; 9043 /*
9044 * Make up an exact-sized output array suitable for an LSL_List object.
9045 */
9046 object[] outlist = new object[outlen];
9047 for (i = 0; i < outlen; i ++) {
9048 outlist[i] = new LSL_String(outarray[i]);
9049 }
9050 return new LSL_List(outlist);
8494 } 9051 }
8495 9052
8496 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers) 9053 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
@@ -8579,28 +9136,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8579 { 9136 {
8580 m_host.AddScriptLPS(1); 9137 m_host.AddScriptLPS(1);
8581 9138
8582 lock (m_host.TaskInventory) 9139 m_host.TaskInventory.LockItemsForRead(true);
9140 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8583 { 9141 {
8584 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9142 if (inv.Value.Name == item)
8585 { 9143 {
8586 if (inv.Value.Name == item) 9144 m_host.TaskInventory.LockItemsForRead(false);
9145 switch (mask)
8587 { 9146 {
8588 switch (mask) 9147 case 0:
8589 { 9148 return (int)inv.Value.BasePermissions;
8590 case 0: 9149 case 1:
8591 return (int)inv.Value.BasePermissions; 9150 return (int)inv.Value.CurrentPermissions;
8592 case 1: 9151 case 2:
8593 return (int)inv.Value.CurrentPermissions; 9152 return (int)inv.Value.GroupPermissions;
8594 case 2: 9153 case 3:
8595 return (int)inv.Value.GroupPermissions; 9154 return (int)inv.Value.EveryonePermissions;
8596 case 3: 9155 case 4:
8597 return (int)inv.Value.EveryonePermissions; 9156 return (int)inv.Value.NextPermissions;
8598 case 4:
8599 return (int)inv.Value.NextPermissions;
8600 }
8601 } 9157 }
8602 } 9158 }
8603 } 9159 }
9160 m_host.TaskInventory.LockItemsForRead(false);
8604 9161
8605 return -1; 9162 return -1;
8606 } 9163 }
@@ -8647,16 +9204,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8647 { 9204 {
8648 m_host.AddScriptLPS(1); 9205 m_host.AddScriptLPS(1);
8649 9206
8650 lock (m_host.TaskInventory) 9207 m_host.TaskInventory.LockItemsForRead(true);
9208 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8651 { 9209 {
8652 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9210 if (inv.Value.Name == item)
8653 { 9211 {
8654 if (inv.Value.Name == item) 9212 m_host.TaskInventory.LockItemsForRead(false);
8655 { 9213 return inv.Value.CreatorID.ToString();
8656 return inv.Value.CreatorID.ToString();
8657 }
8658 } 9214 }
8659 } 9215 }
9216 m_host.TaskInventory.LockItemsForRead(false);
8660 9217
8661 llSay(0, "No item name '" + item + "'"); 9218 llSay(0, "No item name '" + item + "'");
8662 9219
@@ -8707,8 +9264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8707 return UUID.Zero.ToString(); 9264 return UUID.Zero.ToString();
8708 } 9265 }
8709 reply = new LSL_Vector( 9266 reply = new LSL_Vector(
8710 info.RegionLocX * Constants.RegionSize, 9267 info.RegionLocX,
8711 info.RegionLocY * Constants.RegionSize, 9268 info.RegionLocY,
8712 0).ToString(); 9269 0).ToString();
8713 break; 9270 break;
8714 case 6: // DATA_SIM_STATUS 9271 case 6: // DATA_SIM_STATUS
@@ -8921,17 +9478,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8921 int width = 0; 9478 int width = 0;
8922 int height = 0; 9479 int height = 0;
8923 9480
8924 ParcelMediaCommandEnum? commandToSend = null; 9481 uint commandToSend = 0;
8925 float time = 0.0f; // default is from start 9482 float time = 0.0f; // default is from start
8926 9483
8927 ScenePresence presence = null; 9484 ScenePresence presence = null;
8928 9485
8929 for (int i = 0; i < commandList.Data.Length; i++) 9486 for (int i = 0; i < commandList.Data.Length; i++)
8930 { 9487 {
8931 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9488 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8932 switch (command) 9489 switch (command)
8933 { 9490 {
8934 case ParcelMediaCommandEnum.Agent: 9491 case (uint)ParcelMediaCommandEnum.Agent:
8935 // we send only to one agent 9492 // we send only to one agent
8936 if ((i + 1) < commandList.Length) 9493 if ((i + 1) < commandList.Length)
8937 { 9494 {
@@ -8948,25 +9505,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8948 } 9505 }
8949 break; 9506 break;
8950 9507
8951 case ParcelMediaCommandEnum.Loop: 9508 case (uint)ParcelMediaCommandEnum.Loop:
8952 loop = 1; 9509 loop = 1;
8953 commandToSend = command; 9510 commandToSend = command;
8954 update = true; //need to send the media update packet to set looping 9511 update = true; //need to send the media update packet to set looping
8955 break; 9512 break;
8956 9513
8957 case ParcelMediaCommandEnum.Play: 9514 case (uint)ParcelMediaCommandEnum.Play:
8958 loop = 0; 9515 loop = 0;
8959 commandToSend = command; 9516 commandToSend = command;
8960 update = true; //need to send the media update packet to make sure it doesn't loop 9517 update = true; //need to send the media update packet to make sure it doesn't loop
8961 break; 9518 break;
8962 9519
8963 case ParcelMediaCommandEnum.Pause: 9520 case (uint)ParcelMediaCommandEnum.Pause:
8964 case ParcelMediaCommandEnum.Stop: 9521 case (uint)ParcelMediaCommandEnum.Stop:
8965 case ParcelMediaCommandEnum.Unload: 9522 case (uint)ParcelMediaCommandEnum.Unload:
8966 commandToSend = command; 9523 commandToSend = command;
8967 break; 9524 break;
8968 9525
8969 case ParcelMediaCommandEnum.Url: 9526 case (uint)ParcelMediaCommandEnum.Url:
8970 if ((i + 1) < commandList.Length) 9527 if ((i + 1) < commandList.Length)
8971 { 9528 {
8972 if (commandList.Data[i + 1] is LSL_String) 9529 if (commandList.Data[i + 1] is LSL_String)
@@ -8979,7 +9536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8979 } 9536 }
8980 break; 9537 break;
8981 9538
8982 case ParcelMediaCommandEnum.Texture: 9539 case (uint)ParcelMediaCommandEnum.Texture:
8983 if ((i + 1) < commandList.Length) 9540 if ((i + 1) < commandList.Length)
8984 { 9541 {
8985 if (commandList.Data[i + 1] is LSL_String) 9542 if (commandList.Data[i + 1] is LSL_String)
@@ -8992,7 +9549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8992 } 9549 }
8993 break; 9550 break;
8994 9551
8995 case ParcelMediaCommandEnum.Time: 9552 case (uint)ParcelMediaCommandEnum.Time:
8996 if ((i + 1) < commandList.Length) 9553 if ((i + 1) < commandList.Length)
8997 { 9554 {
8998 if (commandList.Data[i + 1] is LSL_Float) 9555 if (commandList.Data[i + 1] is LSL_Float)
@@ -9004,7 +9561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9004 } 9561 }
9005 break; 9562 break;
9006 9563
9007 case ParcelMediaCommandEnum.AutoAlign: 9564 case (uint)ParcelMediaCommandEnum.AutoAlign:
9008 if ((i + 1) < commandList.Length) 9565 if ((i + 1) < commandList.Length)
9009 { 9566 {
9010 if (commandList.Data[i + 1] is LSL_Integer) 9567 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9018,7 +9575,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9018 } 9575 }
9019 break; 9576 break;
9020 9577
9021 case ParcelMediaCommandEnum.Type: 9578 case (uint)ParcelMediaCommandEnum.Type:
9022 if ((i + 1) < commandList.Length) 9579 if ((i + 1) < commandList.Length)
9023 { 9580 {
9024 if (commandList.Data[i + 1] is LSL_String) 9581 if (commandList.Data[i + 1] is LSL_String)
@@ -9031,7 +9588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9031 } 9588 }
9032 break; 9589 break;
9033 9590
9034 case ParcelMediaCommandEnum.Desc: 9591 case (uint)ParcelMediaCommandEnum.Desc:
9035 if ((i + 1) < commandList.Length) 9592 if ((i + 1) < commandList.Length)
9036 { 9593 {
9037 if (commandList.Data[i + 1] is LSL_String) 9594 if (commandList.Data[i + 1] is LSL_String)
@@ -9044,7 +9601,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9044 } 9601 }
9045 break; 9602 break;
9046 9603
9047 case ParcelMediaCommandEnum.Size: 9604 case (uint)ParcelMediaCommandEnum.Size:
9048 if ((i + 2) < commandList.Length) 9605 if ((i + 2) < commandList.Length)
9049 { 9606 {
9050 if (commandList.Data[i + 1] is LSL_Integer) 9607 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9114,7 +9671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9114 } 9671 }
9115 } 9672 }
9116 9673
9117 if (commandToSend != null) 9674 if (commandToSend != 0)
9118 { 9675 {
9119 // the commandList contained a start/stop/... command, too 9676 // the commandList contained a start/stop/... command, too
9120 if (presence == null) 9677 if (presence == null)
@@ -9151,7 +9708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9151 9708
9152 if (aList.Data[i] != null) 9709 if (aList.Data[i] != null)
9153 { 9710 {
9154 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9711 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9155 { 9712 {
9156 case ParcelMediaCommandEnum.Url: 9713 case ParcelMediaCommandEnum.Url:
9157 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9714 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9194,16 +9751,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9194 { 9751 {
9195 m_host.AddScriptLPS(1); 9752 m_host.AddScriptLPS(1);
9196 9753
9197 lock (m_host.TaskInventory) 9754 m_host.TaskInventory.LockItemsForRead(true);
9755 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9198 { 9756 {
9199 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9757 if (inv.Value.Name == name)
9200 { 9758 {
9201 if (inv.Value.Name == name) 9759 m_host.TaskInventory.LockItemsForRead(false);
9202 { 9760 return inv.Value.Type;
9203 return inv.Value.Type;
9204 }
9205 } 9761 }
9206 } 9762 }
9763 m_host.TaskInventory.LockItemsForRead(false);
9207 9764
9208 return -1; 9765 return -1;
9209 } 9766 }
@@ -9214,15 +9771,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9214 9771
9215 if (quick_pay_buttons.Data.Length < 4) 9772 if (quick_pay_buttons.Data.Length < 4)
9216 { 9773 {
9217 LSLError("List must have at least 4 elements"); 9774 int x;
9218 return; 9775 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9776 {
9777 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9778 }
9219 } 9779 }
9220 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9780 int[] nPrice = new int[5];
9221 9781 nPrice[0]=price;
9222 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9782 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9223 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9783 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9224 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9784 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9225 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9785 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9786 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9226 m_host.ParentGroup.HasGroupChanged = true; 9787 m_host.ParentGroup.HasGroupChanged = true;
9227 } 9788 }
9228 9789
@@ -9234,17 +9795,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9234 if (invItemID == UUID.Zero) 9795 if (invItemID == UUID.Zero)
9235 return new LSL_Vector(); 9796 return new LSL_Vector();
9236 9797
9237 lock (m_host.TaskInventory) 9798 m_host.TaskInventory.LockItemsForRead(true);
9799 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9238 { 9800 {
9239 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9801 m_host.TaskInventory.LockItemsForRead(false);
9240 return new LSL_Vector(); 9802 return new LSL_Vector();
9803 }
9241 9804
9242 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9805 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9243 { 9806 {
9244 ShoutError("No permissions to track the camera"); 9807 ShoutError("No permissions to track the camera");
9245 return new LSL_Vector(); 9808 m_host.TaskInventory.LockItemsForRead(false);
9246 } 9809 return new LSL_Vector();
9247 } 9810 }
9811 m_host.TaskInventory.LockItemsForRead(false);
9248 9812
9249 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9813 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9250 if (presence != null) 9814 if (presence != null)
@@ -9262,17 +9826,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9262 if (invItemID == UUID.Zero) 9826 if (invItemID == UUID.Zero)
9263 return new LSL_Rotation(); 9827 return new LSL_Rotation();
9264 9828
9265 lock (m_host.TaskInventory) 9829 m_host.TaskInventory.LockItemsForRead(true);
9830 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9266 { 9831 {
9267 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9832 m_host.TaskInventory.LockItemsForRead(false);
9268 return new LSL_Rotation(); 9833 return new LSL_Rotation();
9269 9834 }
9270 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9835 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9271 { 9836 {
9272 ShoutError("No permissions to track the camera"); 9837 ShoutError("No permissions to track the camera");
9273 return new LSL_Rotation(); 9838 m_host.TaskInventory.LockItemsForRead(false);
9274 } 9839 return new LSL_Rotation();
9275 } 9840 }
9841 m_host.TaskInventory.LockItemsForRead(false);
9276 9842
9277 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9843 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9278 if (presence != null) 9844 if (presence != null)
@@ -9334,8 +9900,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9334 { 9900 {
9335 m_host.AddScriptLPS(1); 9901 m_host.AddScriptLPS(1);
9336 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9902 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9337 if (detectedParams == null) return; // only works on the first detected avatar 9903 if (detectedParams == null)
9338 9904 {
9905 if (m_host.IsAttachment == true)
9906 {
9907 detectedParams = new DetectParams();
9908 detectedParams.Key = m_host.OwnerID;
9909 }
9910 else
9911 {
9912 return;
9913 }
9914 }
9915
9339 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9916 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9340 if (avatar != null) 9917 if (avatar != null)
9341 { 9918 {
@@ -9343,6 +9920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9343 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9920 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9344 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9921 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9345 } 9922 }
9923
9346 ScriptSleep(1000); 9924 ScriptSleep(1000);
9347 } 9925 }
9348 9926
@@ -9422,14 +10000,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9422 if (objectID == UUID.Zero) return; 10000 if (objectID == UUID.Zero) return;
9423 10001
9424 UUID agentID; 10002 UUID agentID;
9425 lock (m_host.TaskInventory) 10003 m_host.TaskInventory.LockItemsForRead(true);
9426 { 10004 // we need the permission first, to know which avatar we want to set the camera for
9427 // we need the permission first, to know which avatar we want to set the camera for 10005 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9428 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9429 10006
9430 if (agentID == UUID.Zero) return; 10007 if (agentID == UUID.Zero)
9431 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10008 {
10009 m_host.TaskInventory.LockItemsForRead(false);
10010 return;
10011 }
10012 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10013 {
10014 m_host.TaskInventory.LockItemsForRead(false);
10015 return;
9432 } 10016 }
10017 m_host.TaskInventory.LockItemsForRead(false);
9433 10018
9434 ScenePresence presence = World.GetScenePresence(agentID); 10019 ScenePresence presence = World.GetScenePresence(agentID);
9435 10020
@@ -9479,12 +10064,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9479 10064
9480 // we need the permission first, to know which avatar we want to clear the camera for 10065 // we need the permission first, to know which avatar we want to clear the camera for
9481 UUID agentID; 10066 UUID agentID;
9482 lock (m_host.TaskInventory) 10067 m_host.TaskInventory.LockItemsForRead(true);
10068 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10069 if (agentID == UUID.Zero)
10070 {
10071 m_host.TaskInventory.LockItemsForRead(false);
10072 return;
10073 }
10074 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9483 { 10075 {
9484 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10076 m_host.TaskInventory.LockItemsForRead(false);
9485 if (agentID == UUID.Zero) return; 10077 return;
9486 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9487 } 10078 }
10079 m_host.TaskInventory.LockItemsForRead(false);
9488 10080
9489 ScenePresence presence = World.GetScenePresence(agentID); 10081 ScenePresence presence = World.GetScenePresence(agentID);
9490 10082
@@ -9551,19 +10143,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9551 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10143 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9552 { 10144 {
9553 m_host.AddScriptLPS(1); 10145 m_host.AddScriptLPS(1);
9554 string ret = String.Empty; 10146
9555 string src1 = llBase64ToString(str1); 10147 if (str1 == String.Empty)
9556 string src2 = llBase64ToString(str2); 10148 return String.Empty;
9557 int c = 0; 10149 if (str2 == String.Empty)
9558 for (int i = 0; i < src1.Length; i++) 10150 return str1;
10151
10152 byte[] data1 = Convert.FromBase64String(str1);
10153 byte[] data2 = Convert.FromBase64String(str2);
10154
10155 byte[] d2 = new Byte[data1.Length];
10156 int pos = 0;
10157
10158 if (data1.Length <= data2.Length)
9559 { 10159 {
9560 ret += (char) (src1[i] ^ src2[c]); 10160 Array.Copy(data2, 0, d2, 0, data1.Length);
10161 }
10162 else
10163 {
10164 while (pos < data1.Length)
10165 {
10166 int len = data1.Length - pos;
10167 if (len > data2.Length)
10168 len = data2.Length;
9561 10169
9562 c++; 10170 Array.Copy(data2, 0, d2, pos, len);
9563 if (c >= src2.Length) 10171 pos += len;
9564 c = 0; 10172 }
9565 } 10173 }
9566 return llStringToBase64(ret); 10174
10175 for (pos = 0 ; pos < data1.Length ; pos++ )
10176 data1[pos] ^= d2[pos];
10177
10178 return Convert.ToBase64String(data1);
9567 } 10179 }
9568 10180
9569 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10181 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9941,15 +10553,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9941 10553
9942 internal UUID ScriptByName(string name) 10554 internal UUID ScriptByName(string name)
9943 { 10555 {
9944 lock (m_host.TaskInventory) 10556 m_host.TaskInventory.LockItemsForRead(true);
10557
10558 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9945 { 10559 {
9946 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10560 if (item.Type == 10 && item.Name == name)
9947 { 10561 {
9948 if (item.Type == 10 && item.Name == name) 10562 m_host.TaskInventory.LockItemsForRead(false);
9949 return item.ItemID; 10563 return item.ItemID;
9950 } 10564 }
9951 } 10565 }
9952 10566
10567 m_host.TaskInventory.LockItemsForRead(false);
10568
9953 return UUID.Zero; 10569 return UUID.Zero;
9954 } 10570 }
9955 10571
@@ -9990,6 +10606,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9990 { 10606 {
9991 m_host.AddScriptLPS(1); 10607 m_host.AddScriptLPS(1);
9992 10608
10609 //Clone is thread safe
9993 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10610 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9994 10611
9995 UUID assetID = UUID.Zero; 10612 UUID assetID = UUID.Zero;
@@ -10052,6 +10669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10052 { 10669 {
10053 m_host.AddScriptLPS(1); 10670 m_host.AddScriptLPS(1);
10054 10671
10672 //Clone is thread safe
10055 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10673 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10056 10674
10057 UUID assetID = UUID.Zero; 10675 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 477c52d..6827ede 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()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2216,9 +2229,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 { 2229 {
2217 if (avatar.IsChildAgent == false) 2230 if (avatar.IsChildAgent == false)
2218 { 2231 {
2219 result.Add(avatar.UUID); 2232 result.Add(new LSL_Key(avatar.UUID.ToString()));
2220 result.Add(avatar.AbsolutePosition); 2233 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2221 result.Add(avatar.Name); 2234 result.Add(new LSL_String(avatar.Name));
2222 } 2235 }
2223 } 2236 }
2224 }); 2237 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fefbb35..3b7de53 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 309 // in mouselook.
310 310
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
312 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 313 q = avatar.Rotation;
313 } 314 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 423 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 424 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment)
427 {
428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook.
431
432 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
433 fromRegionPos = avatar.AbsolutePosition;
434 q = avatar.Rotation;
435 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 436 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 437 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 438 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/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 78ee43c..c8f3623 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
81 // Avatar Info Commands 81 // Avatar Info Commands
82 string osGetAgentIP(string agent); 82 string osGetAgentIP(string agent);
83 LSL_List osGetAgents(); 83 LSL_List osGetAgents();
84 84
85 // Teleport commands 85 // Teleport commands
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 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/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 5da6bb9..6e8435d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
280 public const int CHANGED_MEDIA = 2048; 280 public const int CHANGED_MEDIA = 2048;
281 public const int CHANGED_ANIMATION = 16384; 281 public const int CHANGED_ANIMATION = 16384;
282 public const int CHANGED_POSITION = 32768;
282 public const int TYPE_INVALID = 0; 283 public const int TYPE_INVALID = 0;
283 public const int TYPE_INTEGER = 1; 284 public const int TYPE_INTEGER = 1;
284 public const int TYPE_FLOAT = 2; 285 public const int TYPE_FLOAT = 2;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..f14967e 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();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index f8dbe03..8280ca5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,5 +72,20 @@ 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
76 public LSL_List cmGetWindlightScene(LSL_List rules)
77 {
78 return m_LS_Functions.lsGetWindlightScene(rules);
79 }
80
81 public int cmSetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsSetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
87 {
88 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
89 }
75 } 90 }
76} 91}
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/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6663aa5..b4da246 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;
@@ -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();
@@ -429,14 +429,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 429 {
430 int permsMask; 430 int permsMask;
431 UUID permsGranter; 431 UUID permsGranter;
432 lock (part.TaskInventory) 432 part.TaskInventory.LockItemsForRead(true);
433 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 434 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 435 part.TaskInventory.LockItemsForRead(false);
435 return; 436 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 437 }
438 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
439 permsMask = part.TaskInventory[m_ItemID].PermsMask;
440 part.TaskInventory.LockItemsForRead(false);
440 441
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 442 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 443 {
@@ -545,6 +546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 546 return true;
546 } 547 }
547 548
549 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 550 public void SetState(string state)
549 { 551 {
550 if (state == State) 552 if (state == State)
@@ -556,7 +558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 558 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 559 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 560 new DetectParams[0]));
559 561
560 throw new EventAbortException(); 562 throw new EventAbortException();
561 } 563 }
562 564
@@ -639,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 641 /// <returns></returns>
640 public object EventProcessor() 642 public object EventProcessor()
641 { 643 {
642 if (m_Suspended) 644 EventParams data = null;
643 return 0;
644 645
645 lock (m_Script) 646 lock (m_EventQueue)
646 { 647 {
647 EventParams data = null; 648 if (m_Suspended)
649 return 0;
648 650
649 lock (m_EventQueue) 651 lock (m_Script)
650 { 652 {
651 data = (EventParams) m_EventQueue.Dequeue(); 653 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 654 if (data == null) // Shouldn't happen
@@ -672,6 +674,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 674 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 675 m_CollisionInQueue = false;
674 } 676 }
677 }
678 lock(m_Script)
679 {
675 680
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 682
@@ -828,6 +833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 833 new Object[0], new DetectParams[0]));
829 } 834 }
830 835
836 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 837 public void ApiResetScript()
832 { 838 {
833 // bool running = Running; 839 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 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
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 427d4e5..e82d297 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"; }
@@ -263,43 +331,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
263 331
264 public void RemoveRegion(Scene scene) 332 public void RemoveRegion(Scene scene)
265 { 333 {
266 lock (m_Scripts) 334 lockScriptsForRead(true);
335 foreach (IScriptInstance instance in m_Scripts.Values)
267 { 336 {
268 foreach (IScriptInstance instance in m_Scripts.Values) 337 // Force a final state save
338 //
339 if (m_Assemblies.ContainsKey(instance.AssetID))
269 { 340 {
270 // Force a final state save 341 string assembly = m_Assemblies[instance.AssetID];
271 // 342 instance.SaveState(assembly);
272 if (m_Assemblies.ContainsKey(instance.AssetID)) 343 }
273 {
274 string assembly = m_Assemblies[instance.AssetID];
275 instance.SaveState(assembly);
276 }
277 344
278 // Clear the event queue and abort the instance thread 345 // Clear the event queue and abort the instance thread
279 // 346 //
280 instance.ClearQueue(); 347 instance.ClearQueue();
281 instance.Stop(0); 348 instance.Stop(0);
282 349
283 // Release events, timer, etc 350 // Release events, timer, etc
284 // 351 //
285 instance.DestroyScriptInstance(); 352 instance.DestroyScriptInstance();
286 353
287 // Unload scripts and app domains 354 // Unload scripts and app domains
288 // Must be done explicitly because they have infinite 355 // Must be done explicitly because they have infinite
289 // lifetime 356 // lifetime
290 // 357 //
291 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 358 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
292 if (m_DomainScripts[instance.AppDomain].Count == 0) 359 if (m_DomainScripts[instance.AppDomain].Count == 0)
293 { 360 {
294 m_DomainScripts.Remove(instance.AppDomain); 361 m_DomainScripts.Remove(instance.AppDomain);
295 UnloadAppDomain(instance.AppDomain); 362 UnloadAppDomain(instance.AppDomain);
296 }
297 } 363 }
298 m_Scripts.Clear();
299 m_PrimObjects.Clear();
300 m_Assemblies.Clear();
301 m_DomainScripts.Clear();
302 } 364 }
365 lockScriptsForRead(false);
366 lockScriptsForWrite(true);
367 m_Scripts.Clear();
368 lockScriptsForWrite(false);
369 m_PrimObjects.Clear();
370 m_Assemblies.Clear();
371 m_DomainScripts.Clear();
372
303 lock (m_ScriptEngines) 373 lock (m_ScriptEngines)
304 { 374 {
305 m_ScriptEngines.Remove(this); 375 m_ScriptEngines.Remove(this);
@@ -358,22 +428,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
358 428
359 List<IScriptInstance> instances = new List<IScriptInstance>(); 429 List<IScriptInstance> instances = new List<IScriptInstance>();
360 430
361 lock (m_Scripts) 431 lockScriptsForRead(true);
362 { 432 foreach (IScriptInstance instance in m_Scripts.Values)
363 foreach (IScriptInstance instance in m_Scripts.Values)
364 instances.Add(instance); 433 instances.Add(instance);
365 } 434 lockScriptsForRead(false);
366 435
367 foreach (IScriptInstance i in instances) 436 foreach (IScriptInstance i in instances)
368 { 437 {
369 string assembly = String.Empty; 438 string assembly = String.Empty;
370 439
371 lock (m_Scripts) 440
372 {
373 if (!m_Assemblies.ContainsKey(i.AssetID)) 441 if (!m_Assemblies.ContainsKey(i.AssetID))
374 continue; 442 continue;
375 assembly = m_Assemblies[i.AssetID]; 443 assembly = m_Assemblies[i.AssetID];
376 } 444
377 445
378 i.SaveState(assembly); 446 i.SaveState(assembly);
379 } 447 }
@@ -702,92 +770,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 } 770 }
703 771
704 ScriptInstance instance = null; 772 ScriptInstance instance = null;
705 lock (m_Scripts) 773 // Create the object record
774 lockScriptsForRead(true);
775 if ((!m_Scripts.ContainsKey(itemID)) ||
776 (m_Scripts[itemID].AssetID != assetID))
706 { 777 {
707 // Create the object record 778 lockScriptsForRead(false);
708 779
709 if ((!m_Scripts.ContainsKey(itemID)) || 780 UUID appDomain = assetID;
710 (m_Scripts[itemID].AssetID != assetID))
711 {
712 UUID appDomain = assetID;
713 781
714 if (part.ParentGroup.IsAttachment) 782 if (part.ParentGroup.IsAttachment)
715 appDomain = part.ParentGroup.RootPart.UUID; 783 appDomain = part.ParentGroup.RootPart.UUID;
716 784
717 if (!m_AppDomains.ContainsKey(appDomain)) 785 if (!m_AppDomains.ContainsKey(appDomain))
786 {
787 try
718 { 788 {
719 try 789 AppDomainSetup appSetup = new AppDomainSetup();
720 { 790 // appSetup.ApplicationBase = Path.Combine(
721 AppDomainSetup appSetup = new AppDomainSetup(); 791 // "ScriptEngines",
722// appSetup.ApplicationBase = Path.Combine( 792 // m_Scene.RegionInfo.RegionID.ToString());
723// "ScriptEngines", 793
724// m_Scene.RegionInfo.RegionID.ToString()); 794 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
725 795 Evidence evidence = new Evidence(baseEvidence);
726 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 796
727 Evidence evidence = new Evidence(baseEvidence); 797 AppDomain sandbox;
728 798 if (m_AppDomainLoading)
729 AppDomain sandbox; 799 sandbox = AppDomain.CreateDomain(
730 if (m_AppDomainLoading) 800 m_Scene.RegionInfo.RegionID.ToString(),
731 sandbox = AppDomain.CreateDomain( 801 evidence, appSetup);
732 m_Scene.RegionInfo.RegionID.ToString(), 802 else
733 evidence, appSetup); 803 sandbox = AppDomain.CurrentDomain;
734 else 804
735 sandbox = AppDomain.CurrentDomain; 805 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
736 806 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
737 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 807 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
738 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 808 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
739 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 809 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
740 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 810 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
741 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 811 //sandbox.SetAppDomainPolicy(sandboxPolicy);
742 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 812
743 //sandbox.SetAppDomainPolicy(sandboxPolicy); 813 m_AppDomains[appDomain] = sandbox;
744 814
745 m_AppDomains[appDomain] = sandbox; 815 m_AppDomains[appDomain].AssemblyResolve +=
746 816 new ResolveEventHandler(
747 m_AppDomains[appDomain].AssemblyResolve += 817 AssemblyResolver.OnAssemblyResolve);
748 new ResolveEventHandler( 818 m_DomainScripts[appDomain] = new List<UUID>();
749 AssemblyResolver.OnAssemblyResolve); 819 }
750 m_DomainScripts[appDomain] = new List<UUID>(); 820 catch (Exception e)
751 } 821 {
752 catch (Exception e) 822 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
823 m_ScriptErrorMessage += "Exception creating app domain:\n";
824 m_ScriptFailCount++;
825 lock (m_AddingAssemblies)
753 { 826 {
754 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 827 m_AddingAssemblies[assembly]--;
755 m_ScriptErrorMessage += "Exception creating app domain:\n";
756 m_ScriptFailCount++;
757 lock (m_AddingAssemblies)
758 {
759 m_AddingAssemblies[assembly]--;
760 }
761 return false;
762 } 828 }
829 return false;
763 } 830 }
764 m_DomainScripts[appDomain].Add(itemID); 831 }
765 832 m_DomainScripts[appDomain].Add(itemID);
766 instance = new ScriptInstance(this, part, 833
767 itemID, assetID, assembly, 834 instance = new ScriptInstance(this, part,
768 m_AppDomains[appDomain], 835 itemID, assetID, assembly,
769 part.ParentGroup.RootPart.Name, 836 m_AppDomains[appDomain],
770 item.Name, startParam, postOnRez, 837 part.ParentGroup.RootPart.Name,
771 stateSource, m_MaxScriptQueue); 838 item.Name, startParam, postOnRez,
772 839 stateSource, m_MaxScriptQueue);
773 m_log.DebugFormat( 840
841 m_log.DebugFormat(
774 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 842 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
775 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 843 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
776 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 844 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
777 845
778 if (presence != null) 846 if (presence != null)
779 { 847 {
780 ShowScriptSaveResponse(item.OwnerID, 848 ShowScriptSaveResponse(item.OwnerID,
781 assetID, "Compile successful", true); 849 assetID, "Compile successful", true);
782 }
783
784 instance.AppDomain = appDomain;
785 instance.LineMap = linemap;
786
787 m_Scripts[itemID] = instance;
788 } 850 }
789 }
790 851
852 instance.AppDomain = appDomain;
853 instance.LineMap = linemap;
854 lockScriptsForWrite(true);
855 m_Scripts[itemID] = instance;
856 lockScriptsForWrite(false);
857 }
858 else
859 {
860 lockScriptsForRead(false);
861 }
791 lock (m_PrimObjects) 862 lock (m_PrimObjects)
792 { 863 {
793 if (!m_PrimObjects.ContainsKey(localID)) 864 if (!m_PrimObjects.ContainsKey(localID))
@@ -806,9 +877,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
806 m_AddingAssemblies[assembly]--; 877 m_AddingAssemblies[assembly]--;
807 } 878 }
808 879
809 if (instance != null) 880 if (instance!=null)
810 instance.Init(); 881 instance.Init();
811 882
812 return true; 883 return true;
813 } 884 }
814 885
@@ -821,20 +892,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
821 m_CompileDict.Remove(itemID); 892 m_CompileDict.Remove(itemID);
822 } 893 }
823 894
824 IScriptInstance instance = null; 895 lockScriptsForRead(true);
825 896 // Do we even have it?
826 lock (m_Scripts) 897 if (!m_Scripts.ContainsKey(itemID))
827 { 898 {
828 // Do we even have it? 899 lockScriptsForRead(false);
829 if (!m_Scripts.ContainsKey(itemID)) 900 return;
830 return;
831
832 instance=m_Scripts[itemID];
833 m_Scripts.Remove(itemID);
834 } 901 }
902
835 903
904 IScriptInstance instance=m_Scripts[itemID];
905 lockScriptsForRead(false);
906 lockScriptsForWrite(true);
907 m_Scripts.Remove(itemID);
908 lockScriptsForWrite(false);
836 instance.ClearQueue(); 909 instance.ClearQueue();
837 instance.Stop(0); 910 instance.Stop(0);
911
838// bool objectRemoved = false; 912// bool objectRemoved = false;
839 913
840 lock (m_PrimObjects) 914 lock (m_PrimObjects)
@@ -870,11 +944,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
870 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 944 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
871 if (handlerObjectRemoved != null) 945 if (handlerObjectRemoved != null)
872 { 946 {
873 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 947 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
874 handlerObjectRemoved(part.UUID); 948 handlerObjectRemoved(part.UUID);
875 } 949 }
876 950
877 951 CleanAssemblies();
952
878 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 953 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
879 if (handlerScriptRemoved != null) 954 if (handlerScriptRemoved != null)
880 handlerScriptRemoved(itemID); 955 handlerScriptRemoved(itemID);
@@ -1016,7 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1016 return false; 1091 return false;
1017 1092
1018 uuids = m_PrimObjects[localID]; 1093 uuids = m_PrimObjects[localID];
1019 } 1094
1020 1095
1021 foreach (UUID itemID in uuids) 1096 foreach (UUID itemID in uuids)
1022 { 1097 {
@@ -1034,6 +1109,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1034 result = true; 1109 result = true;
1035 } 1110 }
1036 } 1111 }
1112 }
1037 1113
1038 return result; 1114 return result;
1039 } 1115 }
@@ -1133,12 +1209,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 private IScriptInstance GetInstance(UUID itemID) 1209 private IScriptInstance GetInstance(UUID itemID)
1134 { 1210 {
1135 IScriptInstance instance; 1211 IScriptInstance instance;
1136 lock (m_Scripts) 1212 lockScriptsForRead(true);
1213 if (!m_Scripts.ContainsKey(itemID))
1137 { 1214 {
1138 if (!m_Scripts.ContainsKey(itemID)) 1215 lockScriptsForRead(false);
1139 return null; 1216 return null;
1140 instance = m_Scripts[itemID];
1141 } 1217 }
1218 instance = m_Scripts[itemID];
1219 lockScriptsForRead(false);
1142 return instance; 1220 return instance;
1143 } 1221 }
1144 1222
@@ -1162,6 +1240,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1162 return false; 1240 return false;
1163 } 1241 }
1164 1242
1243 [DebuggerNonUserCode]
1165 public void ApiResetScript(UUID itemID) 1244 public void ApiResetScript(UUID itemID)
1166 { 1245 {
1167 IScriptInstance instance = GetInstance(itemID); 1246 IScriptInstance instance = GetInstance(itemID);
@@ -1213,6 +1292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return UUID.Zero; 1292 return UUID.Zero;
1214 } 1293 }
1215 1294
1295 [DebuggerNonUserCode]
1216 public void SetState(UUID itemID, string newState) 1296 public void SetState(UUID itemID, string newState)
1217 { 1297 {
1218 IScriptInstance instance = GetInstance(itemID); 1298 IScriptInstance instance = GetInstance(itemID);
@@ -1233,11 +1313,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1233 { 1313 {
1234 List<IScriptInstance> instances = new List<IScriptInstance>(); 1314 List<IScriptInstance> instances = new List<IScriptInstance>();
1235 1315
1236 lock (m_Scripts) 1316 lockScriptsForRead(true);
1237 { 1317 foreach (IScriptInstance instance in m_Scripts.Values)
1238 foreach (IScriptInstance instance in m_Scripts.Values)
1239 instances.Add(instance); 1318 instances.Add(instance);
1240 } 1319 lockScriptsForRead(false);
1241 1320
1242 foreach (IScriptInstance i in instances) 1321 foreach (IScriptInstance i in instances)
1243 { 1322 {