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.cs1749
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs36
-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.cs338
15 files changed, 1461 insertions, 822 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 417cef4..1d4c235 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;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 /// </summary> 74 /// </summary>
74 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 75 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
75 { 76 {
76 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 protected IScriptEngine m_ScriptEngine; 78 protected IScriptEngine m_ScriptEngine;
78 protected SceneObjectPart m_host; 79 protected SceneObjectPart m_host;
79 protected uint m_localID; 80 protected uint m_localID;
@@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 get { return m_ScriptEngine.World; } 152 get { return m_ScriptEngine.World; }
152 } 153 }
153 154
155 [DebuggerNonUserCode]
154 public void state(string newState) 156 public void state(string newState)
155 { 157 {
156 m_ScriptEngine.SetState(m_itemID, newState); 158 m_ScriptEngine.SetState(m_itemID, newState);
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
160 /// Reset the named script. The script must be present 162 /// Reset the named script. The script must be present
161 /// in the same prim. 163 /// in the same prim.
162 /// </summary> 164 /// </summary>
165 [DebuggerNonUserCode]
163 public void llResetScript() 166 public void llResetScript()
164 { 167 {
165 m_host.AddScriptLPS(1); 168 m_host.AddScriptLPS(1);
@@ -216,9 +219,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
216 } 219 }
217 } 220 }
218 221
222 public List<ScenePresence> GetLinkAvatars(int linkType)
223 {
224 List<ScenePresence> ret = new List<ScenePresence>();
225 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
226 return ret;
227
228 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
229
230 switch (linkType)
231 {
232 case ScriptBaseClass.LINK_SET:
233 return avs;
234
235 case ScriptBaseClass.LINK_ROOT:
236 return ret;
237
238 case ScriptBaseClass.LINK_ALL_OTHERS:
239 return avs;
240
241 case ScriptBaseClass.LINK_ALL_CHILDREN:
242 return avs;
243
244 case ScriptBaseClass.LINK_THIS:
245 return ret;
246
247 default:
248 if (linkType < 0)
249 return ret;
250
251 int partCount = m_host.ParentGroup.GetPartCount();
252
253 if (linkType <= partCount)
254 {
255 return ret;
256 }
257 else
258 {
259 linkType = linkType - partCount;
260 if (linkType > avs.Count)
261 {
262 return ret;
263 }
264 else
265 {
266 ret.Add(avs[linkType-1]);
267 return ret;
268 }
269 }
270 }
271 }
272
219 public List<SceneObjectPart> GetLinkParts(int linkType) 273 public List<SceneObjectPart> GetLinkParts(int linkType)
220 { 274 {
221 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 275 List<SceneObjectPart> ret = new List<SceneObjectPart>();
276 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
277 return ret;
222 ret.Add(m_host); 278 ret.Add(m_host);
223 279
224 switch (linkType) 280 switch (linkType)
@@ -272,40 +328,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 328 protected UUID InventorySelf()
273 { 329 {
274 UUID invItemID = new UUID(); 330 UUID invItemID = new UUID();
275 331 bool unlock = false;
276 lock (m_host.TaskInventory) 332 if (!m_host.TaskInventory.IsReadLockedByMe())
333 {
334 m_host.TaskInventory.LockItemsForRead(true);
335 unlock = true;
336 }
337 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
277 { 338 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 339 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 340 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 341 invItemID = inv.Key;
281 { 342 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 343 }
286 } 344 }
287 345 if (unlock)
346 {
347 m_host.TaskInventory.LockItemsForRead(false);
348 }
288 return invItemID; 349 return invItemID;
289 } 350 }
290 351
291 protected UUID InventoryKey(string name, int type) 352 protected UUID InventoryKey(string name, int type)
292 { 353 {
293 m_host.AddScriptLPS(1); 354 m_host.AddScriptLPS(1);
294 355 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 356
357 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 358 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 359 if (inv.Value.Name == name)
298 { 360 {
299 if (inv.Value.Name == name) 361 m_host.TaskInventory.LockItemsForRead(false);
362
363 if (inv.Value.Type != type)
300 { 364 {
301 if (inv.Value.Type != type) 365 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 366 }
367
368 return inv.Value.AssetID;
306 } 369 }
307 } 370 }
308 371
372 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 373 return UUID.Zero;
310 } 374 }
311 375
@@ -313,17 +377,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 377 {
314 m_host.AddScriptLPS(1); 378 m_host.AddScriptLPS(1);
315 379
316 lock (m_host.TaskInventory) 380
381 m_host.TaskInventory.LockItemsForRead(true);
382
383 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 384 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 385 if (inv.Value.Name == name)
319 { 386 {
320 if (inv.Value.Name == name) 387 m_host.TaskInventory.LockItemsForRead(false);
321 { 388 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 389 }
325 } 390 }
326 391
392 m_host.TaskInventory.LockItemsForRead(false);
393
394
327 return UUID.Zero; 395 return UUID.Zero;
328 } 396 }
329 397
@@ -465,26 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 533
466 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
467 535
468 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 536 // Utility function for llRot2Euler
469 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 537
538 // normalize an angle between -PI and PI (-180 to +180 degrees)
539 protected double NormalizeAngle(double angle)
540 {
541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
543
544 int numPis = (int)(Math.PI / angle);
545 double remainder = angle - Math.PI * numPis;
546 if (numPis % 2 == 1)
547 return Math.PI - angle;
548 return remainder;
549 }
470 550
471 public LSL_Vector llRot2Euler(LSL_Rotation r) 551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
472 { 552 {
473 m_host.AddScriptLPS(1); 553 m_host.AddScriptLPS(1);
474 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 554 LSL_Vector eul = new LSL_Vector();
475 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 555
476 double m = (t.x + t.y + t.z + t.s); 556 double sqw = q1.s*q1.s;
477 if (m == 0) return new LSL_Vector(); 557 double sqx = q1.x*q1.x;
478 double n = 2 * (r.y * r.s + r.x * r.z); 558 double sqy = q1.z*q1.z;
479 double p = m * m - n * n; 559 double sqz = q1.y*q1.y;
480 if (p > 0) 560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
481 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 561 double test = q1.x*q1.z + q1.y*q1.s;
482 Math.Atan2(n, Math.Sqrt(p)), 562 if (test > 0.4999*unit) { // singularity at north pole
483 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
484 else if (n > 0) 564 eul.y = Math.PI/2;
485 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)); 565 eul.x = 0;
486 else 566 return eul;
487 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)); 567 }
568 if (test < -0.4999*unit) { // singularity at south pole
569 eul.z = -2 * Math.Atan2(q1.x,q1.s);
570 eul.y = -Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
488 } 578 }
489 579
490 /* From wiki: 580 /* From wiki:
@@ -686,77 +776,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
686 { 776 {
687 //A and B should both be normalized 777 //A and B should both be normalized
688 m_host.AddScriptLPS(1); 778 m_host.AddScriptLPS(1);
689 LSL_Rotation rotBetween; 779 /* This method is more accurate than the SL one, and thus causes problems
690 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 780 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
691 // continue calculation. 781
692 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 782 double dotProduct = LSL_Vector.Dot(a, b);
783 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
784 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
785 double angle = Math.Acos(dotProduct / magProduct);
786 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
787 double s = Math.Sin(angle / 2);
788
789 double x = axis.x * s;
790 double y = axis.y * s;
791 double z = axis.z * s;
792 double w = Math.Cos(angle / 2);
793
794 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
795 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
796
797 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
798 */
799
800 // This method mimics the 180 errors found in SL
801 // See www.euclideanspace.com... angleBetween
802 LSL_Vector vec_a = a;
803 LSL_Vector vec_b = b;
804
805 // Eliminate zero length
806 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
807 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
808 if (vec_a_mag < 0.00001 ||
809 vec_b_mag < 0.00001)
693 { 810 {
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
695 } 812 }
696 else 813
814 // Normalize
815 vec_a = llVecNorm(vec_a);
816 vec_b = llVecNorm(vec_b);
817
818 // Calculate axis and rotation angle
819 LSL_Vector axis = vec_a % vec_b;
820 LSL_Float cos_theta = vec_a * vec_b;
821
822 // Check if parallel
823 if (cos_theta > 0.99999)
697 { 824 {
698 a = LSL_Vector.Norm(a); 825 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
699 b = LSL_Vector.Norm(b); 826 }
700 double dotProduct = LSL_Vector.Dot(a, b); 827
701 // There are two degenerate cases possible. These are for vectors 180 or 828 // Check if anti-parallel
702 // 0 degrees apart. These have to be detected and handled individually. 829 else if (cos_theta < -0.99999)
703 // 830 {
704 // Check for vectors 180 degrees apart. 831 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
705 // A dot product of -1 would mean the angle between vectors is 180 degrees. 832 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
706 if (dotProduct < -0.9999999f) 833 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
707 { 834 }
708 // First assume X axis is orthogonal to the vectors. 835 else // other rotation
709 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 836 {
710 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 837 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
711 // Check for near zero vector. A very small non-zero number here will create 838 axis = llVecNorm(axis);
712 // a rotation in an undesired direction. 839 double x, y, z, s, t;
713 if (LSL_Vector.Mag(orthoVector) > 0.0001) 840 s = Math.Cos(theta);
714 { 841 t = Math.Sin(theta);
715 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 842 x = axis.x * t;
716 } 843 y = axis.y * t;
717 // If the magnitude of the vector was near zero, then assume the X axis is not 844 z = axis.z * t;
718 // orthogonal and use the Z axis instead. 845 return new LSL_Rotation(x,y,z,s);
719 else
720 {
721 // Set 180 z rotation.
722 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
723 }
724 }
725 // Check for parallel vectors.
726 // A dot product of 1 would mean the angle between vectors is 0 degrees.
727 else if (dotProduct > 0.9999999f)
728 {
729 // Set zero rotation.
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 else
733 {
734 // All special checks have been performed so get the axis of rotation.
735 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
736 // Quarternion s value is the length of the unit vector + dot product.
737 double qs = 1.0 + dotProduct;
738 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
739 // Normalize the rotation.
740 double mag = LSL_Rotation.Mag(rotBetween);
741 // We shouldn't have to worry about a divide by zero here. The qs value will be
742 // non-zero because we already know if we're here, then the dotProduct is not -1 so
743 // qs will not be zero. Also, we've already handled the input vectors being zero so the
744 // crossProduct vector should also not be zero.
745 rotBetween.x = rotBetween.x / mag;
746 rotBetween.y = rotBetween.y / mag;
747 rotBetween.z = rotBetween.z / mag;
748 rotBetween.s = rotBetween.s / mag;
749 // Check for undefined values and set zero rotation if any found. This code might not actually be required
750 // any longer since zero vectors are checked for at the top.
751 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
752 {
753 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
754 }
755 }
756 } 846 }
757 return rotBetween;
758 } 847 }
759 848
760 public void llWhisper(int channelID, string text) 849 public void llWhisper(int channelID, string text)
761 { 850 {
762 m_host.AddScriptLPS(1); 851 m_host.AddScriptLPS(1);
@@ -1080,10 +1169,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1169 return detectedParams.TouchUV;
1081 } 1170 }
1082 1171
1172 [DebuggerNonUserCode]
1083 public virtual void llDie() 1173 public virtual void llDie()
1084 { 1174 {
1085 m_host.AddScriptLPS(1); 1175 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1176 if (!m_host.IsAttachment) throw new SelfDeleteException();
1087 } 1177 }
1088 1178
1089 public LSL_Float llGround(LSL_Vector offset) 1179 public LSL_Float llGround(LSL_Vector offset)
@@ -1156,6 +1246,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 1246
1157 public void llSetStatus(int status, int value) 1247 public void llSetStatus(int status, int value)
1158 { 1248 {
1249 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1250 return;
1159 m_host.AddScriptLPS(1); 1251 m_host.AddScriptLPS(1);
1160 1252
1161 int statusrotationaxis = 0; 1253 int statusrotationaxis = 0;
@@ -1385,6 +1477,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1477 {
1386 m_host.AddScriptLPS(1); 1478 m_host.AddScriptLPS(1);
1387 1479
1480 SetColor(m_host, color, face);
1481 }
1482
1483 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1484 {
1485 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1486 return;
1487
1488 Primitive.TextureEntry tex = part.Shape.Textures;
1489 Color4 texcolor;
1490 if (face >= 0 && face < GetNumberOfSides(part))
1491 {
1492 texcolor = tex.CreateFace((uint)face).RGBA;
1493 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1494 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1495 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1496 tex.FaceTextures[face].RGBA = texcolor;
1497 part.UpdateTexture(tex);
1498 return;
1499 }
1500 else if (face == ScriptBaseClass.ALL_SIDES)
1501 {
1502 for (uint i = 0; i < GetNumberOfSides(part); i++)
1503 {
1504 if (tex.FaceTextures[i] != null)
1505 {
1506 texcolor = tex.FaceTextures[i].RGBA;
1507 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1508 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1509 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1510 tex.FaceTextures[i].RGBA = texcolor;
1511 }
1512 texcolor = tex.DefaultTexture.RGBA;
1513 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1514 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1515 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1516 tex.DefaultTexture.RGBA = texcolor;
1517 }
1518 part.UpdateTexture(tex);
1519 return;
1520 }
1521
1388 if (face == ScriptBaseClass.ALL_SIDES) 1522 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1523 face = SceneObjectPart.ALL_SIDES;
1390 1524
@@ -1393,6 +1527,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1527
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1528 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1529 {
1530 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1531 return;
1532
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1533 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1534 MappingType textype;
1398 textype = MappingType.Default; 1535 textype = MappingType.Default;
@@ -1423,6 +1560,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1560
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1561 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1562 {
1563 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1564 return;
1565
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1566 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1567 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1568 {
@@ -1448,6 +1588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1588
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1589 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1590 {
1591 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1592 return;
1451 1593
1452 Shininess sval = new Shininess(); 1594 Shininess sval = new Shininess();
1453 1595
@@ -1498,6 +1640,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1640
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1641 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1642 {
1643 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return;
1645
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1646 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1647 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1648 {
@@ -1558,13 +1703,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1703 m_host.AddScriptLPS(1);
1559 1704
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1705 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1706 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1707 {
1563 SetAlpha(part, alpha, face); 1708 try
1709 {
1710 parts[0].ParentGroup.areUpdatesSuspended = true;
1711 foreach (SceneObjectPart part in parts)
1712 SetAlpha(part, alpha, face);
1713 }
1714 finally
1715 {
1716 parts[0].ParentGroup.areUpdatesSuspended = false;
1717 }
1718 }
1564 } 1719 }
1565 1720
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1721 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1722 {
1723 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1724 return;
1725
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1726 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1727 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1728 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1610,7 +1768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1610 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1768 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1611 float wind, float tension, LSL_Vector Force) 1769 float wind, float tension, LSL_Vector Force)
1612 { 1770 {
1613 if (part == null) 1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1614 return; 1772 return;
1615 1773
1616 if (flexi) 1774 if (flexi)
@@ -1645,7 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1803 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1804 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1805 {
1648 if (part == null) 1806 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1807 return;
1650 1808
1651 if (light) 1809 if (light)
@@ -1722,15 +1880,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 m_host.AddScriptLPS(1); 1880 m_host.AddScriptLPS(1);
1723 1881
1724 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1882 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1725 1883 if (parts.Count > 0)
1726 foreach (SceneObjectPart part in parts) 1884 {
1727 SetTexture(part, texture, face); 1885 try
1728 1886 {
1887 parts[0].ParentGroup.areUpdatesSuspended = true;
1888 foreach (SceneObjectPart part in parts)
1889 SetTexture(part, texture, face);
1890 }
1891 finally
1892 {
1893 parts[0].ParentGroup.areUpdatesSuspended = false;
1894 }
1895 }
1729 ScriptSleep(200); 1896 ScriptSleep(200);
1730 } 1897 }
1731 1898
1732 protected void SetTexture(SceneObjectPart part, string texture, int face) 1899 protected void SetTexture(SceneObjectPart part, string texture, int face)
1733 { 1900 {
1901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1902 return;
1903
1734 UUID textureID=new UUID(); 1904 UUID textureID=new UUID();
1735 1905
1736 if (!UUID.TryParse(texture, out textureID)) 1906 if (!UUID.TryParse(texture, out textureID))
@@ -1776,6 +1946,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1776 1946
1777 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1778 { 1948 {
1949 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1950 return;
1951
1779 Primitive.TextureEntry tex = part.Shape.Textures; 1952 Primitive.TextureEntry tex = part.Shape.Textures;
1780 if (face >= 0 && face < GetNumberOfSides(part)) 1953 if (face >= 0 && face < GetNumberOfSides(part))
1781 { 1954 {
@@ -1812,6 +1985,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1812 1985
1813 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1986 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1814 { 1987 {
1988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1989 return;
1990
1815 Primitive.TextureEntry tex = part.Shape.Textures; 1991 Primitive.TextureEntry tex = part.Shape.Textures;
1816 if (face >= 0 && face < GetNumberOfSides(part)) 1992 if (face >= 0 && face < GetNumberOfSides(part))
1817 { 1993 {
@@ -1848,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 2024
1849 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2025 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1850 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1851 Primitive.TextureEntry tex = part.Shape.Textures; 2030 Primitive.TextureEntry tex = part.Shape.Textures;
1852 if (face >= 0 && face < GetNumberOfSides(part)) 2031 if (face >= 0 && face < GetNumberOfSides(part))
1853 { 2032 {
@@ -1918,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1918 2097
1919 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2098 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1920 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1921 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2103 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1922 LSL_Vector currentPos = llGetLocalPos(); 2104 LSL_Vector currentPos = llGetLocalPos();
1923 2105
@@ -1954,6 +2136,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1954 public LSL_Vector llGetLocalPos() 2136 public LSL_Vector llGetLocalPos()
1955 { 2137 {
1956 m_host.AddScriptLPS(1); 2138 m_host.AddScriptLPS(1);
2139 if (m_host.IsAttachment == true) {
2140 if (m_host.IsRoot == true)
2141 {
2142 return new LSL_Vector(m_host.AbsolutePosition.X,
2143 m_host.AbsolutePosition.Y,
2144 m_host.AbsolutePosition.Z);
2145
2146 }
2147 else
2148 {
2149 return new LSL_Vector(m_host.OffsetPosition.X,
2150 m_host.OffsetPosition.Y,
2151 m_host.OffsetPosition.Z);
2152 }
2153 }
2154
1957 if (m_host.ParentID != 0) 2155 if (m_host.ParentID != 0)
1958 { 2156 {
1959 return new LSL_Vector(m_host.OffsetPosition.X, 2157 return new LSL_Vector(m_host.OffsetPosition.X,
@@ -2004,6 +2202,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2004 2202
2005 protected void SetRot(SceneObjectPart part, Quaternion rot) 2203 protected void SetRot(SceneObjectPart part, Quaternion rot)
2006 { 2204 {
2205 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2206 return;
2207
2007 part.UpdateRotation(rot); 2208 part.UpdateRotation(rot);
2008 // Update rotation does not move the object in the physics scene if it's a linkset. 2209 // Update rotation does not move the object in the physics scene if it's a linkset.
2009 2210
@@ -2623,12 +2824,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2623 2824
2624 m_host.AddScriptLPS(1); 2825 m_host.AddScriptLPS(1);
2625 2826
2827 m_host.TaskInventory.LockItemsForRead(true);
2626 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2828 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2627 2829 m_host.TaskInventory.LockItemsForRead(false);
2628 lock (m_host.TaskInventory)
2629 {
2630 item = m_host.TaskInventory[invItemID];
2631 }
2632 2830
2633 if (item.PermsGranter == UUID.Zero) 2831 if (item.PermsGranter == UUID.Zero)
2634 return 0; 2832 return 0;
@@ -2703,6 +2901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 if (dist > m_ScriptDistanceFactor * 10.0f) 2901 if (dist > m_ScriptDistanceFactor * 10.0f)
2704 return; 2902 return;
2705 2903
2904 //Clone is thread-safe
2706 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2905 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2707 2906
2708 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2765,6 +2964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2765 2964
2766 public void llLookAt(LSL_Vector target, double strength, double damping) 2965 public void llLookAt(LSL_Vector target, double strength, double damping)
2767 { 2966 {
2967 /*
2768 m_host.AddScriptLPS(1); 2968 m_host.AddScriptLPS(1);
2769 // Determine where we are looking from 2969 // Determine where we are looking from
2770 LSL_Vector from = llGetPos(); 2970 LSL_Vector from = llGetPos();
@@ -2784,10 +2984,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2784 // the angles of rotation in radians into rotation value 2984 // the angles of rotation in radians into rotation value
2785 2985
2786 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2986 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2787 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2987
2788 m_host.startLookAt(rotation, (float)damping, (float)strength); 2988 // This would only work if your physics system contains an APID controller:
2989 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2990 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2991
2789 // Orient the object to the angle calculated 2992 // Orient the object to the angle calculated
2790 //llSetRot(rot); 2993 llSetRot(rot);
2994 */
2995
2996 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2997 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2998 // http://bugs.meta7.com/view.php?id=28
2999 // - Tom
3000
3001 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3002 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3003
3004 }
3005
3006 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3007 {
3008 m_host.AddScriptLPS(1);
3009// NotImplemented("llRotLookAt");
3010 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3011
2791 } 3012 }
2792 3013
2793 public void llStopLookAt() 3014 public void llStopLookAt()
@@ -2836,13 +3057,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2836 { 3057 {
2837 TaskInventoryItem item; 3058 TaskInventoryItem item;
2838 3059
2839 lock (m_host.TaskInventory) 3060 m_host.TaskInventory.LockItemsForRead(true);
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2840 { 3062 {
2841 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3063 m_host.TaskInventory.LockItemsForRead(false);
2842 return; 3064 return;
2843 else 3065 }
2844 item = m_host.TaskInventory[InventorySelf()]; 3066 else
3067 {
3068 item = m_host.TaskInventory[InventorySelf()];
2845 } 3069 }
3070 m_host.TaskInventory.LockItemsForRead(false);
2846 3071
2847 if (item.PermsGranter != UUID.Zero) 3072 if (item.PermsGranter != UUID.Zero)
2848 { 3073 {
@@ -2864,13 +3089,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2864 { 3089 {
2865 TaskInventoryItem item; 3090 TaskInventoryItem item;
2866 3091
3092 m_host.TaskInventory.LockItemsForRead(true);
2867 lock (m_host.TaskInventory) 3093 lock (m_host.TaskInventory)
2868 { 3094 {
3095
2869 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3096 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3097 {
3098 m_host.TaskInventory.LockItemsForRead(false);
2870 return; 3099 return;
3100 }
2871 else 3101 else
3102 {
2872 item = m_host.TaskInventory[InventorySelf()]; 3103 item = m_host.TaskInventory[InventorySelf()];
3104 }
2873 } 3105 }
3106 m_host.TaskInventory.LockItemsForRead(false);
2874 3107
2875 m_host.AddScriptLPS(1); 3108 m_host.AddScriptLPS(1);
2876 3109
@@ -2902,19 +3135,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2902 { 3135 {
2903 m_host.AddScriptLPS(1); 3136 m_host.AddScriptLPS(1);
2904 3137
2905 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2906 return;
2907
2908 TaskInventoryItem item; 3138 TaskInventoryItem item;
2909 3139
2910 lock (m_host.TaskInventory) 3140 m_host.TaskInventory.LockItemsForRead(true);
3141
3142 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2911 { 3143 {
2912 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3144 m_host.TaskInventory.LockItemsForRead(false);
2913 return; 3145 return;
2914 else 3146 }
2915 item = m_host.TaskInventory[InventorySelf()]; 3147 else
3148 {
3149 item = m_host.TaskInventory[InventorySelf()];
2916 } 3150 }
2917 3151
3152 m_host.TaskInventory.LockItemsForRead(false);
3153
2918 if (item.PermsGranter != m_host.OwnerID) 3154 if (item.PermsGranter != m_host.OwnerID)
2919 return; 3155 return;
2920 3156
@@ -2924,10 +3160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2924 3160
2925 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3161 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2926 3162
2927 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3163 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2928 if (attachmentsModule != null)
2929 attachmentsModule.AttachObject(presence.ControllingClient,
2930 grp, (uint)attachment, false);
2931 } 3164 }
2932 } 3165 }
2933 3166
@@ -2940,13 +3173,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2940 3173
2941 TaskInventoryItem item; 3174 TaskInventoryItem item;
2942 3175
2943 lock (m_host.TaskInventory) 3176 m_host.TaskInventory.LockItemsForRead(true);
3177
3178 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2944 { 3179 {
2945 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3180 m_host.TaskInventory.LockItemsForRead(false);
2946 return; 3181 return;
2947 else 3182 }
2948 item = m_host.TaskInventory[InventorySelf()]; 3183 else
3184 {
3185 item = m_host.TaskInventory[InventorySelf()];
2949 } 3186 }
3187 m_host.TaskInventory.LockItemsForRead(false);
3188
2950 3189
2951 if (item.PermsGranter != m_host.OwnerID) 3190 if (item.PermsGranter != m_host.OwnerID)
2952 return; 3191 return;
@@ -2983,8 +3222,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2983 return m_host.OwnerID.ToString(); 3222 return m_host.OwnerID.ToString();
2984 } 3223 }
2985 3224
3225 [DebuggerNonUserCode]
2986 public void llInstantMessage(string user, string message) 3226 public void llInstantMessage(string user, string message)
2987 { 3227 {
3228 UUID result;
3229 if (!UUID.TryParse(user, out result))
3230 {
3231 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3232 return;
3233 }
3234
3235
2988 m_host.AddScriptLPS(1); 3236 m_host.AddScriptLPS(1);
2989 3237
2990 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3238 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2999,14 +3247,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2999 UUID friendTransactionID = UUID.Random(); 3247 UUID friendTransactionID = UUID.Random();
3000 3248
3001 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3249 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3002 3250
3003 GridInstantMessage msg = new GridInstantMessage(); 3251 GridInstantMessage msg = new GridInstantMessage();
3004 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3252 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3005 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3253 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3006 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3254 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3007// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3255// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3008// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3256// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3009 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3257 DateTime dt = DateTime.UtcNow;
3258
3259 // Ticks from UtcNow, but make it look like local. Evil, huh?
3260 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3261
3262 try
3263 {
3264 // Convert that to the PST timezone
3265 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3266 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3267 }
3268 catch
3269 {
3270 // No logging here, as it could be VERY spammy
3271 }
3272
3273 // And make it look local again to fool the unix time util
3274 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3275
3276 msg.timestamp = (uint)Util.ToUnixTime(dt);
3277
3010 //if (client != null) 3278 //if (client != null)
3011 //{ 3279 //{
3012 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3280 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3020,13 +3288,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3020 msg.message = message.Substring(0, 1024); 3288 msg.message = message.Substring(0, 1024);
3021 else 3289 else
3022 msg.message = message; 3290 msg.message = message;
3023 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3291 msg.dialog = (byte)19; // MessageFromObject
3024 msg.fromGroup = false;// fromGroup; 3292 msg.fromGroup = false;// fromGroup;
3025 msg.offline = (byte)0; //offline; 3293 msg.offline = (byte)0; //offline;
3026 msg.ParentEstateID = 0; //ParentEstateID; 3294 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3027 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3295 msg.Position = new Vector3(m_host.AbsolutePosition);
3028 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3296 msg.RegionID = World.RegionInfo.RegionID.Guid;
3029 msg.binaryBucket = new byte[0];// binaryBucket; 3297 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3030 3298
3031 if (m_TransferModule != null) 3299 if (m_TransferModule != null)
3032 { 3300 {
@@ -3046,7 +3314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3046 } 3314 }
3047 3315
3048 emailModule.SendEmail(m_host.UUID, address, subject, message); 3316 emailModule.SendEmail(m_host.UUID, address, subject, message);
3049 ScriptSleep(20000); 3317 ScriptSleep(15000);
3050 } 3318 }
3051 3319
3052 public void llGetNextEmail(string address, string subject) 3320 public void llGetNextEmail(string address, string subject)
@@ -3148,13 +3416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3148 m_host.AddScriptLPS(1); 3416 m_host.AddScriptLPS(1);
3149 } 3417 }
3150 3418
3151 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3152 {
3153 m_host.AddScriptLPS(1);
3154 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3155 m_host.RotLookAt(rot, (float)strength, (float)damping);
3156 }
3157
3158 public LSL_Integer llStringLength(string str) 3419 public LSL_Integer llStringLength(string str)
3159 { 3420 {
3160 m_host.AddScriptLPS(1); 3421 m_host.AddScriptLPS(1);
@@ -3178,14 +3439,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3178 3439
3179 TaskInventoryItem item; 3440 TaskInventoryItem item;
3180 3441
3181 lock (m_host.TaskInventory) 3442 m_host.TaskInventory.LockItemsForRead(true);
3443 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3182 { 3444 {
3183 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3445 m_host.TaskInventory.LockItemsForRead(false);
3184 return; 3446 return;
3185 else
3186 item = m_host.TaskInventory[InventorySelf()];
3187 } 3447 }
3188 3448 else
3449 {
3450 item = m_host.TaskInventory[InventorySelf()];
3451 }
3452 m_host.TaskInventory.LockItemsForRead(false);
3189 if (item.PermsGranter == UUID.Zero) 3453 if (item.PermsGranter == UUID.Zero)
3190 return; 3454 return;
3191 3455
@@ -3215,13 +3479,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3215 3479
3216 TaskInventoryItem item; 3480 TaskInventoryItem item;
3217 3481
3218 lock (m_host.TaskInventory) 3482 m_host.TaskInventory.LockItemsForRead(true);
3483 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3219 { 3484 {
3220 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3485 m_host.TaskInventory.LockItemsForRead(false);
3221 return; 3486 return;
3222 else 3487 }
3223 item = m_host.TaskInventory[InventorySelf()]; 3488 else
3489 {
3490 item = m_host.TaskInventory[InventorySelf()];
3224 } 3491 }
3492 m_host.TaskInventory.LockItemsForRead(false);
3493
3225 3494
3226 if (item.PermsGranter == UUID.Zero) 3495 if (item.PermsGranter == UUID.Zero)
3227 return; 3496 return;
@@ -3298,10 +3567,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3298 3567
3299 TaskInventoryItem item; 3568 TaskInventoryItem item;
3300 3569
3301 lock (m_host.TaskInventory) 3570
3571 m_host.TaskInventory.LockItemsForRead(true);
3572 if (!m_host.TaskInventory.ContainsKey(invItemID))
3573 {
3574 m_host.TaskInventory.LockItemsForRead(false);
3575 return;
3576 }
3577 else
3302 { 3578 {
3303 item = m_host.TaskInventory[invItemID]; 3579 item = m_host.TaskInventory[invItemID];
3304 } 3580 }
3581 m_host.TaskInventory.LockItemsForRead(false);
3305 3582
3306 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3583 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3307 { 3584 {
@@ -3333,11 +3610,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3333 3610
3334 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3611 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3335 { 3612 {
3336 lock (m_host.TaskInventory) 3613 m_host.TaskInventory.LockItemsForWrite(true);
3337 { 3614 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3338 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3615 m_host.TaskInventory[invItemID].PermsMask = perm;
3339 m_host.TaskInventory[invItemID].PermsMask = perm; 3616 m_host.TaskInventory.LockItemsForWrite(false);
3340 }
3341 3617
3342 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3618 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3343 "run_time_permissions", new Object[] { 3619 "run_time_permissions", new Object[] {
@@ -3357,11 +3633,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3357 3633
3358 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3634 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3359 { 3635 {
3360 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForWrite(true);
3361 { 3637 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3362 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3638 m_host.TaskInventory[invItemID].PermsMask = perm;
3363 m_host.TaskInventory[invItemID].PermsMask = perm; 3639 m_host.TaskInventory.LockItemsForWrite(false);
3364 }
3365 3640
3366 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3641 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3367 "run_time_permissions", new Object[] { 3642 "run_time_permissions", new Object[] {
@@ -3382,11 +3657,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3382 3657
3383 if (!m_waitingForScriptAnswer) 3658 if (!m_waitingForScriptAnswer)
3384 { 3659 {
3385 lock (m_host.TaskInventory) 3660 m_host.TaskInventory.LockItemsForWrite(true);
3386 { 3661 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3387 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3662 m_host.TaskInventory[invItemID].PermsMask = 0;
3388 m_host.TaskInventory[invItemID].PermsMask = 0; 3663 m_host.TaskInventory.LockItemsForWrite(false);
3389 }
3390 3664
3391 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3665 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3392 m_waitingForScriptAnswer=true; 3666 m_waitingForScriptAnswer=true;
@@ -3421,10 +3695,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3421 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3695 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3422 llReleaseControls(); 3696 llReleaseControls();
3423 3697
3424 lock (m_host.TaskInventory) 3698
3425 { 3699 m_host.TaskInventory.LockItemsForWrite(true);
3426 m_host.TaskInventory[invItemID].PermsMask = answer; 3700 m_host.TaskInventory[invItemID].PermsMask = answer;
3427 } 3701 m_host.TaskInventory.LockItemsForWrite(false);
3702
3428 3703
3429 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3704 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3430 "run_time_permissions", new Object[] { 3705 "run_time_permissions", new Object[] {
@@ -3436,16 +3711,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3436 { 3711 {
3437 m_host.AddScriptLPS(1); 3712 m_host.AddScriptLPS(1);
3438 3713
3439 lock (m_host.TaskInventory) 3714 m_host.TaskInventory.LockItemsForRead(true);
3715
3716 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3440 { 3717 {
3441 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3718 if (item.Type == 10 && item.ItemID == m_itemID)
3442 { 3719 {
3443 if (item.Type == 10 && item.ItemID == m_itemID) 3720 m_host.TaskInventory.LockItemsForRead(false);
3444 { 3721 return item.PermsGranter.ToString();
3445 return item.PermsGranter.ToString();
3446 }
3447 } 3722 }
3448 } 3723 }
3724 m_host.TaskInventory.LockItemsForRead(false);
3449 3725
3450 return UUID.Zero.ToString(); 3726 return UUID.Zero.ToString();
3451 } 3727 }
@@ -3454,19 +3730,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3454 { 3730 {
3455 m_host.AddScriptLPS(1); 3731 m_host.AddScriptLPS(1);
3456 3732
3457 lock (m_host.TaskInventory) 3733 m_host.TaskInventory.LockItemsForRead(true);
3734
3735 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3458 { 3736 {
3459 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3737 if (item.Type == 10 && item.ItemID == m_itemID)
3460 { 3738 {
3461 if (item.Type == 10 && item.ItemID == m_itemID) 3739 int perms = item.PermsMask;
3462 { 3740 if (m_automaticLinkPermission)
3463 int perms = item.PermsMask; 3741 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3464 if (m_automaticLinkPermission) 3742 m_host.TaskInventory.LockItemsForRead(false);
3465 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3743 return perms;
3466 return perms;
3467 }
3468 } 3744 }
3469 } 3745 }
3746 m_host.TaskInventory.LockItemsForRead(false);
3470 3747
3471 return 0; 3748 return 0;
3472 } 3749 }
@@ -3488,9 +3765,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3488 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3765 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3489 { 3766 {
3490 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3767 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3491 3768 if (parts.Count > 0)
3492 foreach (SceneObjectPart part in parts) 3769 {
3493 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3770 try
3771 {
3772 parts[0].ParentGroup.areUpdatesSuspended = true;
3773 foreach (SceneObjectPart part in parts)
3774 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3775 }
3776 finally
3777 {
3778 parts[0].ParentGroup.areUpdatesSuspended = false;
3779 }
3780 }
3494 } 3781 }
3495 3782
3496 public void llCreateLink(string target, int parent) 3783 public void llCreateLink(string target, int parent)
@@ -3499,11 +3786,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3499 UUID invItemID = InventorySelf(); 3786 UUID invItemID = InventorySelf();
3500 3787
3501 TaskInventoryItem item; 3788 TaskInventoryItem item;
3502 lock (m_host.TaskInventory) 3789 m_host.TaskInventory.LockItemsForRead(true);
3503 { 3790 item = m_host.TaskInventory[invItemID];
3504 item = m_host.TaskInventory[invItemID]; 3791 m_host.TaskInventory.LockItemsForRead(false);
3505 } 3792
3506
3507 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3793 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3508 && !m_automaticLinkPermission) 3794 && !m_automaticLinkPermission)
3509 { 3795 {
@@ -3556,16 +3842,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 m_host.AddScriptLPS(1); 3842 m_host.AddScriptLPS(1);
3557 UUID invItemID = InventorySelf(); 3843 UUID invItemID = InventorySelf();
3558 3844
3559 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3560 {
3561 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3846 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3562 && !m_automaticLinkPermission) 3847 && !m_automaticLinkPermission)
3563 { 3848 {
3564 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3849 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3850 m_host.TaskInventory.LockItemsForRead(false);
3565 return; 3851 return;
3566 } 3852 }
3567 } 3853 m_host.TaskInventory.LockItemsForRead(false);
3568 3854
3569 if (linknum < ScriptBaseClass.LINK_THIS) 3855 if (linknum < ScriptBaseClass.LINK_THIS)
3570 return; 3856 return;
3571 3857
@@ -3604,10 +3890,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3604 // Restructuring Multiple Prims. 3890 // Restructuring Multiple Prims.
3605 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3891 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3606 parts.Remove(parentPrim.RootPart); 3892 parts.Remove(parentPrim.RootPart);
3607 foreach (SceneObjectPart part in parts) 3893 if (parts.Count > 0)
3608 { 3894 {
3609 parentPrim.DelinkFromGroup(part.LocalId, true); 3895 try
3896 {
3897 parts[0].ParentGroup.areUpdatesSuspended = true;
3898 foreach (SceneObjectPart part in parts)
3899 {
3900 parentPrim.DelinkFromGroup(part.LocalId, true);
3901 }
3902 }
3903 finally
3904 {
3905 parts[0].ParentGroup.areUpdatesSuspended = false;
3906 }
3610 } 3907 }
3908
3611 parentPrim.HasGroupChanged = true; 3909 parentPrim.HasGroupChanged = true;
3612 parentPrim.ScheduleGroupForFullUpdate(); 3910 parentPrim.ScheduleGroupForFullUpdate();
3613 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3911 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3616,11 +3914,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3616 { 3914 {
3617 SceneObjectPart newRoot = parts[0]; 3915 SceneObjectPart newRoot = parts[0];
3618 parts.Remove(newRoot); 3916 parts.Remove(newRoot);
3619 foreach (SceneObjectPart part in parts) 3917
3918 try
3620 { 3919 {
3621 part.UpdateFlag = 0; 3920 parts[0].ParentGroup.areUpdatesSuspended = true;
3622 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3921 foreach (SceneObjectPart part in parts)
3922 {
3923 part.UpdateFlag = 0;
3924 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3925 }
3623 } 3926 }
3927 finally
3928 {
3929 parts[0].ParentGroup.areUpdatesSuspended = false;
3930 }
3931
3932
3624 newRoot.ParentGroup.HasGroupChanged = true; 3933 newRoot.ParentGroup.HasGroupChanged = true;
3625 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3934 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3626 } 3935 }
@@ -3646,11 +3955,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 3955
3647 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3956 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3648 parts.Remove(parentPrim.RootPart); 3957 parts.Remove(parentPrim.RootPart);
3649 3958 if (parts.Count > 0)
3650 foreach (SceneObjectPart part in parts)
3651 { 3959 {
3652 parentPrim.DelinkFromGroup(part.LocalId, true); 3960 try
3653 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3961 {
3962 parts[0].ParentGroup.areUpdatesSuspended = true;
3963 foreach (SceneObjectPart part in parts)
3964 {
3965 parentPrim.DelinkFromGroup(part.LocalId, true);
3966 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3967 }
3968 }
3969 finally
3970 {
3971 parts[0].ParentGroup.areUpdatesSuspended = false;
3972 }
3654 } 3973 }
3655 parentPrim.HasGroupChanged = true; 3974 parentPrim.HasGroupChanged = true;
3656 parentPrim.ScheduleGroupForFullUpdate(); 3975 parentPrim.ScheduleGroupForFullUpdate();
@@ -3742,17 +4061,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 m_host.AddScriptLPS(1); 4061 m_host.AddScriptLPS(1);
3743 int count = 0; 4062 int count = 0;
3744 4063
3745 lock (m_host.TaskInventory) 4064 m_host.TaskInventory.LockItemsForRead(true);
4065 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3746 { 4066 {
3747 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4067 if (inv.Value.Type == type || type == -1)
3748 { 4068 {
3749 if (inv.Value.Type == type || type == -1) 4069 count = count + 1;
3750 {
3751 count = count + 1;
3752 }
3753 } 4070 }
3754 } 4071 }
3755 4072
4073 m_host.TaskInventory.LockItemsForRead(false);
3756 return count; 4074 return count;
3757 } 4075 }
3758 4076
@@ -3761,16 +4079,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3761 m_host.AddScriptLPS(1); 4079 m_host.AddScriptLPS(1);
3762 ArrayList keys = new ArrayList(); 4080 ArrayList keys = new ArrayList();
3763 4081
3764 lock (m_host.TaskInventory) 4082 m_host.TaskInventory.LockItemsForRead(true);
4083 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3765 { 4084 {
3766 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4085 if (inv.Value.Type == type || type == -1)
3767 { 4086 {
3768 if (inv.Value.Type == type || type == -1) 4087 keys.Add(inv.Value.Name);
3769 {
3770 keys.Add(inv.Value.Name);
3771 }
3772 } 4088 }
3773 } 4089 }
4090 m_host.TaskInventory.LockItemsForRead(false);
3774 4091
3775 if (keys.Count == 0) 4092 if (keys.Count == 0)
3776 { 4093 {
@@ -3807,20 +4124,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3807 } 4124 }
3808 4125
3809 // move the first object found with this inventory name 4126 // move the first object found with this inventory name
3810 lock (m_host.TaskInventory) 4127 m_host.TaskInventory.LockItemsForRead(true);
4128 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3811 { 4129 {
3812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4130 if (inv.Value.Name == inventory)
3813 { 4131 {
3814 if (inv.Value.Name == inventory) 4132 found = true;
3815 { 4133 objId = inv.Key;
3816 found = true; 4134 assetType = inv.Value.Type;
3817 objId = inv.Key; 4135 objName = inv.Value.Name;
3818 assetType = inv.Value.Type; 4136 break;
3819 objName = inv.Value.Name;
3820 break;
3821 }
3822 } 4137 }
3823 } 4138 }
4139 m_host.TaskInventory.LockItemsForRead(false);
3824 4140
3825 if (!found) 4141 if (!found)
3826 { 4142 {
@@ -3828,9 +4144,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3828 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4144 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3829 } 4145 }
3830 4146
3831 // check if destination is an avatar 4147 // check if destination is an object
3832 if (World.GetScenePresence(destId) != null) 4148 if (World.GetSceneObjectPart(destId) != null)
4149 {
4150 // destination is an object
4151 World.MoveTaskInventoryItem(destId, m_host, objId);
4152 }
4153 else
3833 { 4154 {
4155 ScenePresence presence = World.GetScenePresence(destId);
4156
4157 if (presence == null)
4158 {
4159 UserAccount account =
4160 World.UserAccountService.GetUserAccount(
4161 World.RegionInfo.ScopeID,
4162 destId);
4163
4164 if (account == null)
4165 {
4166 llSay(0, "Can't find destination "+destId.ToString());
4167 return;
4168 }
4169 }
4170
3834 // destination is an avatar 4171 // destination is an avatar
3835 InventoryItemBase agentItem = 4172 InventoryItemBase agentItem =
3836 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4173 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3840,7 +4177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3840 4177
3841 byte[] bucket = new byte[17]; 4178 byte[] bucket = new byte[17];
3842 bucket[0] = (byte)assetType; 4179 bucket[0] = (byte)assetType;
3843 byte[] objBytes = objId.GetBytes(); 4180 byte[] objBytes = agentItem.ID.GetBytes();
3844 Array.Copy(objBytes, 0, bucket, 1, 16); 4181 Array.Copy(objBytes, 0, bucket, 1, 16);
3845 4182
3846 Console.WriteLine("Giving inventory"); 4183 Console.WriteLine("Giving inventory");
@@ -3856,33 +4193,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 4193
3857 if (m_TransferModule != null) 4194 if (m_TransferModule != null)
3858 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4195 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4196
4197 //This delay should only occur when giving inventory to avatars.
4198 ScriptSleep(3000);
3859 } 4199 }
3860 else
3861 {
3862 // destination is an object
3863 World.MoveTaskInventoryItem(destId, m_host, objId);
3864 }
3865 ScriptSleep(3000);
3866 } 4200 }
3867 4201
4202 [DebuggerNonUserCode]
3868 public void llRemoveInventory(string name) 4203 public void llRemoveInventory(string name)
3869 { 4204 {
3870 m_host.AddScriptLPS(1); 4205 m_host.AddScriptLPS(1);
3871 4206
3872 lock (m_host.TaskInventory) 4207 m_host.TaskInventory.LockItemsForRead(true);
4208 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3873 { 4209 {
3874 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4210 if (item.Name == name)
3875 { 4211 {
3876 if (item.Name == name) 4212 if (item.ItemID == m_itemID)
3877 { 4213 throw new ScriptDeleteException();
3878 if (item.ItemID == m_itemID) 4214 else
3879 throw new ScriptDeleteException(); 4215 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3880 else 4216
3881 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4217 m_host.TaskInventory.LockItemsForRead(false);
3882 return; 4218 return;
3883 }
3884 } 4219 }
3885 } 4220 }
4221 m_host.TaskInventory.LockItemsForRead(false);
3886 } 4222 }
3887 4223
3888 public void llSetText(string text, LSL_Vector color, double alpha) 4224 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3918,22 +4254,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3918 UUID uuid = (UUID)id; 4254 UUID uuid = (UUID)id;
3919 4255
3920 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4256 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4257 if (account == null)
4258 return UUID.Zero.ToString();
4259
3921 4260
3922 PresenceInfo pinfo = null; 4261 PresenceInfo pinfo = null;
3923 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4262 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3924 if (pinfos != null && pinfos.Length > 0) 4263 if (pinfos != null && pinfos.Length > 0)
3925 pinfo = pinfos[0]; 4264 pinfo = pinfos[0];
3926 4265
3927 if (pinfo == null)
3928 return UUID.Zero.ToString();
3929
3930 string reply = String.Empty; 4266 string reply = String.Empty;
3931 4267
3932 switch (data) 4268 switch (data)
3933 { 4269 {
3934 case 1: // DATA_ONLINE (0|1) 4270 case 1: // DATA_ONLINE (0|1)
3935 // TODO: implement fetching of this information 4271 if (pinfo != null && pinfo.RegionID != UUID.Zero)
3936 if (pinfo != null)
3937 reply = "1"; 4272 reply = "1";
3938 else 4273 else
3939 reply = "0"; 4274 reply = "0";
@@ -3973,6 +4308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3973 { 4308 {
3974 m_host.AddScriptLPS(1); 4309 m_host.AddScriptLPS(1);
3975 4310
4311 //Clone is thread safe
3976 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4312 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3977 4313
3978 foreach (TaskInventoryItem item in itemDictionary.Values) 4314 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4026,6 +4362,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4026 ScenePresence presence = World.GetScenePresence(agentId); 4362 ScenePresence presence = World.GetScenePresence(agentId);
4027 if (presence != null) 4363 if (presence != null)
4028 { 4364 {
4365 // agent must not be a god
4366 if (presence.GodLevel >= 200) return;
4367
4029 // agent must be over the owners land 4368 // agent must be over the owners land
4030 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4369 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4031 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4370 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4086,17 +4425,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4086 UUID soundId = UUID.Zero; 4425 UUID soundId = UUID.Zero;
4087 if (!UUID.TryParse(impact_sound, out soundId)) 4426 if (!UUID.TryParse(impact_sound, out soundId))
4088 { 4427 {
4089 lock (m_host.TaskInventory) 4428 m_host.TaskInventory.LockItemsForRead(true);
4429 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4090 { 4430 {
4091 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4431 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4092 { 4432 {
4093 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4433 soundId = item.AssetID;
4094 { 4434 break;
4095 soundId = item.AssetID;
4096 break;
4097 }
4098 } 4435 }
4099 } 4436 }
4437 m_host.TaskInventory.LockItemsForRead(false);
4100 } 4438 }
4101 m_host.CollisionSound = soundId; 4439 m_host.CollisionSound = soundId;
4102 m_host.CollisionSoundVolume = (float)impact_volume; 4440 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4142,6 +4480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4142 UUID partItemID; 4480 UUID partItemID;
4143 foreach (SceneObjectPart part in parts) 4481 foreach (SceneObjectPart part in parts)
4144 { 4482 {
4483 //Clone is thread safe
4145 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4484 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4146 4485
4147 foreach (TaskInventoryItem item in itemsDictionary.Values) 4486 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4356,17 +4695,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4356 4695
4357 m_host.AddScriptLPS(1); 4696 m_host.AddScriptLPS(1);
4358 4697
4359 lock (m_host.TaskInventory) 4698 m_host.TaskInventory.LockItemsForRead(true);
4699 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4360 { 4700 {
4361 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4701 if (item.Type == 10 && item.ItemID == m_itemID)
4362 { 4702 {
4363 if (item.Type == 10 && item.ItemID == m_itemID) 4703 result = item.Name!=null?item.Name:String.Empty;
4364 { 4704 break;
4365 result = item.Name != null ? item.Name : String.Empty;
4366 break;
4367 }
4368 } 4705 }
4369 } 4706 }
4707 m_host.TaskInventory.LockItemsForRead(false);
4370 4708
4371 return result; 4709 return result;
4372 } 4710 }
@@ -4519,23 +4857,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4519 { 4857 {
4520 m_host.AddScriptLPS(1); 4858 m_host.AddScriptLPS(1);
4521 4859
4522 lock (m_host.TaskInventory) 4860 m_host.TaskInventory.LockItemsForRead(true);
4861 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4523 { 4862 {
4524 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4863 if (inv.Value.Name == name)
4525 { 4864 {
4526 if (inv.Value.Name == name) 4865 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4527 { 4866 {
4528 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4867 m_host.TaskInventory.LockItemsForRead(false);
4529 { 4868 return inv.Value.AssetID.ToString();
4530 return inv.Value.AssetID.ToString(); 4869 }
4531 } 4870 else
4532 else 4871 {
4533 { 4872 m_host.TaskInventory.LockItemsForRead(false);
4534 return UUID.Zero.ToString(); 4873 return UUID.Zero.ToString();
4535 }
4536 } 4874 }
4537 } 4875 }
4538 } 4876 }
4877 m_host.TaskInventory.LockItemsForRead(false);
4539 4878
4540 return UUID.Zero.ToString(); 4879 return UUID.Zero.ToString();
4541 } 4880 }
@@ -4688,14 +5027,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4688 { 5027 {
4689 m_host.AddScriptLPS(1); 5028 m_host.AddScriptLPS(1);
4690 5029
4691 if (src == null) 5030 return src.Length;
4692 {
4693 return 0;
4694 }
4695 else
4696 {
4697 return src.Length;
4698 }
4699 } 5031 }
4700 5032
4701 public LSL_Integer llList2Integer(LSL_List src, int index) 5033 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5471,10 +5803,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5471 m_host.AddScriptLPS(1); 5803 m_host.AddScriptLPS(1);
5472 5804
5473 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5805 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5474 5806 if (parts.Count > 0)
5475 foreach (var part in parts)
5476 { 5807 {
5477 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5808 try
5809 {
5810 parts[0].ParentGroup.areUpdatesSuspended = true;
5811 foreach (var part in parts)
5812 {
5813 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5814 }
5815 }
5816 finally
5817 {
5818 parts[0].ParentGroup.areUpdatesSuspended = false;
5819 }
5478 } 5820 }
5479 } 5821 }
5480 5822
@@ -5530,74 +5872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5530 5872
5531 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5873 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5532 { 5874 {
5533 m_host.AddScriptLPS(1); 5875 return ParseString2List(str, separators, in_spacers, false);
5534 LSL_List ret = new LSL_List();
5535 LSL_List spacers = new LSL_List();
5536 if (in_spacers.Length > 0 && separators.Length > 0)
5537 {
5538 for (int i = 0; i < in_spacers.Length; i++)
5539 {
5540 object s = in_spacers.Data[i];
5541 for (int j = 0; j < separators.Length; j++)
5542 {
5543 if (separators.Data[j].ToString() == s.ToString())
5544 {
5545 s = null;
5546 break;
5547 }
5548 }
5549 if (s != null)
5550 {
5551 spacers.Add(s);
5552 }
5553 }
5554 }
5555 object[] delimiters = new object[separators.Length + spacers.Length];
5556 separators.Data.CopyTo(delimiters, 0);
5557 spacers.Data.CopyTo(delimiters, separators.Length);
5558 bool dfound = false;
5559 do
5560 {
5561 dfound = false;
5562 int cindex = -1;
5563 string cdeli = "";
5564 for (int i = 0; i < delimiters.Length; i++)
5565 {
5566 int index = str.IndexOf(delimiters[i].ToString());
5567 bool found = index != -1;
5568 if (found && String.Empty != delimiters[i].ToString())
5569 {
5570 if ((cindex > index) || (cindex == -1))
5571 {
5572 cindex = index;
5573 cdeli = delimiters[i].ToString();
5574 }
5575 dfound = dfound || found;
5576 }
5577 }
5578 if (cindex != -1)
5579 {
5580 if (cindex > 0)
5581 {
5582 ret.Add(new LSL_String(str.Substring(0, cindex)));
5583 }
5584 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5585 for (int j = 0; j < spacers.Length; j++)
5586 {
5587 if (spacers.Data[j].ToString() == cdeli)
5588 {
5589 ret.Add(new LSL_String(cdeli));
5590 break;
5591 }
5592 }
5593 str = str.Substring(cindex + cdeli.Length);
5594 }
5595 } while (dfound);
5596 if (str != "")
5597 {
5598 ret.Add(new LSL_String(str));
5599 }
5600 return ret;
5601 } 5876 }
5602 5877
5603 public LSL_Integer llOverMyLand(string id) 5878 public LSL_Integer llOverMyLand(string id)
@@ -6073,6 +6348,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6073 prules.OuterAngle = (float)tempf; 6348 prules.OuterAngle = (float)tempf;
6074 prules.PartFlags |= 0x02; // Set new angle format. 6349 prules.PartFlags |= 0x02; // Set new angle format.
6075 break; 6350 break;
6351
6352 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6353 tempf = (float)rules.GetLSLFloatItem(i + 1);
6354 prules.InnerAngle = (float)tempf;
6355 break;
6356
6357 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6358 tempf = (float)rules.GetLSLFloatItem(i + 1);
6359 prules.OuterAngle = (float)tempf;
6360 break;
6076 } 6361 }
6077 6362
6078 } 6363 }
@@ -6111,14 +6396,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6111 6396
6112 protected UUID GetTaskInventoryItem(string name) 6397 protected UUID GetTaskInventoryItem(string name)
6113 { 6398 {
6114 lock (m_host.TaskInventory) 6399 m_host.TaskInventory.LockItemsForRead(true);
6400 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6115 { 6401 {
6116 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6402 if (inv.Value.Name == name)
6117 { 6403 {
6118 if (inv.Value.Name == name) 6404 m_host.TaskInventory.LockItemsForRead(false);
6119 return inv.Key; 6405 return inv.Key;
6120 } 6406 }
6121 } 6407 }
6408 m_host.TaskInventory.LockItemsForRead(false);
6122 6409
6123 return UUID.Zero; 6410 return UUID.Zero;
6124 } 6411 }
@@ -6446,22 +6733,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6446 } 6733 }
6447 6734
6448 // copy the first script found with this inventory name 6735 // copy the first script found with this inventory name
6449 lock (m_host.TaskInventory) 6736 m_host.TaskInventory.LockItemsForRead(true);
6737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6450 { 6738 {
6451 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6739 if (inv.Value.Name == name)
6452 { 6740 {
6453 if (inv.Value.Name == name) 6741 // make sure the object is a script
6742 if (10 == inv.Value.Type)
6454 { 6743 {
6455 // make sure the object is a script 6744 found = true;
6456 if (10 == inv.Value.Type) 6745 srcId = inv.Key;
6457 { 6746 break;
6458 found = true;
6459 srcId = inv.Key;
6460 break;
6461 }
6462 } 6747 }
6463 } 6748 }
6464 } 6749 }
6750 m_host.TaskInventory.LockItemsForRead(false);
6465 6751
6466 if (!found) 6752 if (!found)
6467 { 6753 {
@@ -6545,6 +6831,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6545 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6831 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6546 { 6832 {
6547 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6833 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6834 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6835 return shapeBlock;
6548 6836
6549 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6837 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6550 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6838 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6620,6 +6908,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6620 6908
6621 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6909 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6622 { 6910 {
6911 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6912 return;
6913
6623 ObjectShapePacket.ObjectDataBlock shapeBlock; 6914 ObjectShapePacket.ObjectDataBlock shapeBlock;
6624 6915
6625 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6916 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6669,6 +6960,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6669 6960
6670 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6961 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6671 { 6962 {
6963 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6964 return;
6965
6672 ObjectShapePacket.ObjectDataBlock shapeBlock; 6966 ObjectShapePacket.ObjectDataBlock shapeBlock;
6673 6967
6674 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6968 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6711,6 +7005,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6711 7005
6712 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) 7006 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)
6713 { 7007 {
7008 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7009 return;
7010
6714 ObjectShapePacket.ObjectDataBlock shapeBlock; 7011 ObjectShapePacket.ObjectDataBlock shapeBlock;
6715 7012
6716 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7013 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6837,6 +7134,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6837 7134
6838 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7135 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6839 { 7136 {
7137 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7138 return;
7139
6840 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7140 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6841 UUID sculptId; 7141 UUID sculptId;
6842 7142
@@ -6852,13 +7152,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6852 shapeBlock.PathScaleX = 100; 7152 shapeBlock.PathScaleX = 100;
6853 shapeBlock.PathScaleY = 150; 7153 shapeBlock.PathScaleY = 150;
6854 7154
6855 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7155 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6856 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7156 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6857 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7157 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6858 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7158 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6859 { 7159 {
6860 // default 7160 // default
6861 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7161 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6862 } 7162 }
6863 7163
6864 // retain pathcurve 7164 // retain pathcurve
@@ -6877,12 +7177,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 7177
6878 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7178 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6879 { 7179 {
6880 m_host.AddScriptLPS(1); 7180 m_host.AddScriptLPS(1);
6881 7181
6882 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7182 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6883 7183 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
6884 foreach (SceneObjectPart part in parts) 7184 if (parts.Count>0)
6885 SetPrimParams(part, rules); 7185 {
7186 try
7187 {
7188 parts[0].ParentGroup.areUpdatesSuspended = true;
7189 foreach (SceneObjectPart part in parts)
7190 SetPrimParams(part, rules);
7191 }
7192 finally
7193 {
7194 parts[0].ParentGroup.areUpdatesSuspended = false;
7195 }
7196 }
7197 if (avatars.Count > 0)
7198 {
7199 foreach (ScenePresence avatar in avatars)
7200 SetPrimParams(avatar, rules);
7201 }
6886 } 7202 }
6887 7203
6888 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7204 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
@@ -6890,8 +7206,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6890 llSetLinkPrimitiveParams(linknumber, rules); 7206 llSetLinkPrimitiveParams(linknumber, rules);
6891 } 7207 }
6892 7208
7209 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7210 {
7211 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7212 //We only support PRIM_POSITION and PRIM_ROTATION
7213
7214 int idx = 0;
7215
7216 while (idx < rules.Length)
7217 {
7218 int code = rules.GetLSLIntegerItem(idx++);
7219
7220 int remain = rules.Length - idx;
7221
7222
7223
7224 switch (code)
7225 {
7226 case (int)ScriptBaseClass.PRIM_POSITION:
7227 if (remain < 1)
7228 return;
7229 LSL_Vector v;
7230 v = rules.GetVector3Item(idx++);
7231 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7232 av.SendFullUpdateToAllClients();
7233
7234 break;
7235
7236 case (int)ScriptBaseClass.PRIM_ROTATION:
7237 if (remain < 1)
7238 return;
7239 LSL_Rotation r;
7240 r = rules.GetQuaternionItem(idx++);
7241 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7242 av.SendFullUpdateToAllClients();
7243 break;
7244 }
7245 }
7246
7247 }
7248
6893 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7249 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6894 { 7250 {
7251 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7252 return;
7253
6895 int idx = 0; 7254 int idx = 0;
6896 7255
6897 while (idx < rules.Length) 7256 while (idx < rules.Length)
@@ -7723,24 +8082,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7723 break; 8082 break;
7724 8083
7725 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8084 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7726 // TODO--------------
7727 if (remain < 1) 8085 if (remain < 1)
7728 return res; 8086 return res;
8087 face = (int)rules.GetLSLIntegerItem(idx++);
7729 8088
7730 face=(int)rules.GetLSLIntegerItem(idx++); 8089 tex = part.Shape.Textures;
7731 8090 int shiny;
7732 res.Add(new LSL_Integer(0)); 8091 if (face == ScriptBaseClass.ALL_SIDES)
7733 res.Add(new LSL_Integer(0)); 8092 {
8093 for (face = 0; face < GetNumberOfSides(part); face++)
8094 {
8095 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8096 if (shinyness == Shininess.High)
8097 {
8098 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8099 }
8100 else if (shinyness == Shininess.Medium)
8101 {
8102 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8103 }
8104 else if (shinyness == Shininess.Low)
8105 {
8106 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8107 }
8108 else
8109 {
8110 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8111 }
8112 res.Add(new LSL_Integer(shiny));
8113 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8114 }
8115 }
8116 else
8117 {
8118 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8119 if (shinyness == Shininess.High)
8120 {
8121 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8122 }
8123 else if (shinyness == Shininess.Medium)
8124 {
8125 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8126 }
8127 else if (shinyness == Shininess.Low)
8128 {
8129 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8130 }
8131 else
8132 {
8133 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8134 }
8135 res.Add(new LSL_Integer(shiny));
8136 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8137 }
7734 break; 8138 break;
7735 8139
7736 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8140 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7737 // TODO--------------
7738 if (remain < 1) 8141 if (remain < 1)
7739 return res; 8142 return res;
8143 face = (int)rules.GetLSLIntegerItem(idx++);
7740 8144
7741 face=(int)rules.GetLSLIntegerItem(idx++); 8145 tex = part.Shape.Textures;
7742 8146 int fullbright;
7743 res.Add(new LSL_Integer(0)); 8147 if (face == ScriptBaseClass.ALL_SIDES)
8148 {
8149 for (face = 0; face < GetNumberOfSides(part); face++)
8150 {
8151 if (tex.GetFace((uint)face).Fullbright == true)
8152 {
8153 fullbright = ScriptBaseClass.TRUE;
8154 }
8155 else
8156 {
8157 fullbright = ScriptBaseClass.FALSE;
8158 }
8159 res.Add(new LSL_Integer(fullbright));
8160 }
8161 }
8162 else
8163 {
8164 if (tex.GetFace((uint)face).Fullbright == true)
8165 {
8166 fullbright = ScriptBaseClass.TRUE;
8167 }
8168 else
8169 {
8170 fullbright = ScriptBaseClass.FALSE;
8171 }
8172 res.Add(new LSL_Integer(fullbright));
8173 }
7744 break; 8174 break;
7745 8175
7746 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8176 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7761,14 +8191,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7761 break; 8191 break;
7762 8192
7763 case (int)ScriptBaseClass.PRIM_TEXGEN: 8193 case (int)ScriptBaseClass.PRIM_TEXGEN:
7764 // TODO--------------
7765 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8194 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7766 if (remain < 1) 8195 if (remain < 1)
7767 return res; 8196 return res;
8197 face = (int)rules.GetLSLIntegerItem(idx++);
7768 8198
7769 face=(int)rules.GetLSLIntegerItem(idx++); 8199 tex = part.Shape.Textures;
7770 8200 if (face == ScriptBaseClass.ALL_SIDES)
7771 res.Add(new LSL_Integer(0)); 8201 {
8202 for (face = 0; face < GetNumberOfSides(part); face++)
8203 {
8204 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8205 {
8206 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8207 }
8208 else
8209 {
8210 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8211 }
8212 }
8213 }
8214 else
8215 {
8216 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8217 {
8218 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8219 }
8220 else
8221 {
8222 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8223 }
8224 }
7772 break; 8225 break;
7773 8226
7774 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8227 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7787,13 +8240,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7787 break; 8240 break;
7788 8241
7789 case (int)ScriptBaseClass.PRIM_GLOW: 8242 case (int)ScriptBaseClass.PRIM_GLOW:
7790 // TODO--------------
7791 if (remain < 1) 8243 if (remain < 1)
7792 return res; 8244 return res;
8245 face = (int)rules.GetLSLIntegerItem(idx++);
7793 8246
7794 face=(int)rules.GetLSLIntegerItem(idx++); 8247 tex = part.Shape.Textures;
7795 8248 float primglow;
7796 res.Add(new LSL_Float(0)); 8249 if (face == ScriptBaseClass.ALL_SIDES)
8250 {
8251 for (face = 0; face < GetNumberOfSides(part); face++)
8252 {
8253 primglow = tex.GetFace((uint)face).Glow;
8254 res.Add(new LSL_Float(primglow));
8255 }
8256 }
8257 else
8258 {
8259 primglow = tex.GetFace((uint)face).Glow;
8260 res.Add(new LSL_Float(primglow));
8261 }
7797 break; 8262 break;
7798 case (int)ScriptBaseClass.PRIM_TEXT: 8263 case (int)ScriptBaseClass.PRIM_TEXT:
7799 Color4 textColor = part.GetTextColor(); 8264 Color4 textColor = part.GetTextColor();
@@ -8099,8 +8564,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8099 // The function returns an ordered list 8564 // The function returns an ordered list
8100 // representing the tokens found in the supplied 8565 // representing the tokens found in the supplied
8101 // sources string. If two successive tokenizers 8566 // sources string. If two successive tokenizers
8102 // are encountered, then a NULL entry is added 8567 // are encountered, then a null-string entry is
8103 // to the list. 8568 // added to the list.
8104 // 8569 //
8105 // It is a precondition that the source and 8570 // It is a precondition that the source and
8106 // toekizer lisst are non-null. If they are null, 8571 // toekizer lisst are non-null. If they are null,
@@ -8108,7 +8573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8108 // while their lengths are being determined. 8573 // while their lengths are being determined.
8109 // 8574 //
8110 // A small amount of working memoryis required 8575 // A small amount of working memoryis required
8111 // of approximately 8*#tokenizers. 8576 // of approximately 8*#tokenizers + 8*srcstrlen.
8112 // 8577 //
8113 // There are many ways in which this function 8578 // There are many ways in which this function
8114 // can be implemented, this implementation is 8579 // can be implemented, this implementation is
@@ -8124,136 +8589,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8124 // and eliminates redundant tokenizers as soon 8589 // and eliminates redundant tokenizers as soon
8125 // as is possible. 8590 // as is possible.
8126 // 8591 //
8127 // The implementation tries to avoid any copying 8592 // The implementation tries to minimize temporary
8128 // of arrays or other objects. 8593 // garbage generation.
8129 // </remarks> 8594 // </remarks>
8130 8595
8131 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8596 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8132 { 8597 {
8133 int beginning = 0; 8598 return ParseString2List(src, separators, spacers, true);
8134 int srclen = src.Length; 8599 }
8135 int seplen = separators.Length;
8136 object[] separray = separators.Data;
8137 int spclen = spacers.Length;
8138 object[] spcarray = spacers.Data;
8139 int mlen = seplen+spclen;
8140
8141 int[] offset = new int[mlen+1];
8142 bool[] active = new bool[mlen];
8143 8600
8144 int best; 8601 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8145 int j; 8602 {
8603 int srclen = src.Length;
8604 int seplen = separators.Length;
8605 object[] separray = separators.Data;
8606 int spclen = spacers.Length;
8607 object[] spcarray = spacers.Data;
8608 int dellen = 0;
8609 string[] delarray = new string[seplen+spclen];
8146 8610
8147 // Initial capacity reduces resize cost 8611 int outlen = 0;
8612 string[] outarray = new string[srclen*2+1];
8148 8613
8149 LSL_List tokens = new LSL_List(); 8614 int i, j;
8615 string d;
8150 8616
8151 m_host.AddScriptLPS(1); 8617 m_host.AddScriptLPS(1);
8152 8618
8153 // All entries are initially valid 8619 /*
8154 8620 * Convert separator and spacer lists to C# strings.
8155 for (int i = 0; i < mlen; i++) 8621 * Also filter out null strings so we don't hang.
8156 active[i] = true; 8622 */
8157 8623 for (i = 0; i < seplen; i ++) {
8158 offset[mlen] = srclen; 8624 d = separray[i].ToString();
8159 8625 if (d.Length > 0) {
8160 while (beginning < srclen) 8626 delarray[dellen++] = d;
8161 { 8627 }
8162 8628 }
8163 best = mlen; // as bad as it gets 8629 seplen = dellen;
8164
8165 // Scan for separators
8166 8630
8167 for (j = 0; j < seplen; j++) 8631 for (i = 0; i < spclen; i ++) {
8168 { 8632 d = spcarray[i].ToString();
8169 if (active[j]) 8633 if (d.Length > 0) {
8170 { 8634 delarray[dellen++] = d;
8171 // scan all of the markers
8172 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8173 {
8174 // not present at all
8175 active[j] = false;
8176 }
8177 else
8178 {
8179 // present and correct
8180 if (offset[j] < offset[best])
8181 {
8182 // closest so far
8183 best = j;
8184 if (offset[best] == beginning)
8185 break;
8186 }
8187 }
8188 }
8189 } 8635 }
8636 }
8190 8637
8191 // Scan for spacers 8638 /*
8639 * Scan through source string from beginning to end.
8640 */
8641 for (i = 0;;) {
8192 8642
8193 if (offset[best] != beginning) 8643 /*
8194 { 8644 * Find earliest delimeter in src starting at i (if any).
8195 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8645 */
8196 { 8646 int earliestDel = -1;
8197 if (active[j]) 8647 int earliestSrc = srclen;
8198 { 8648 string earliestStr = null;
8199 // scan all of the markers 8649 for (j = 0; j < dellen; j ++) {
8200 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8650 d = delarray[j];
8201 { 8651 if (d != null) {
8202 // not present at all 8652 int index = src.IndexOf(d, i);
8203 active[j] = false; 8653 if (index < 0) {
8204 } 8654 delarray[j] = null; // delim nowhere in src, don't check it anymore
8205 else 8655 } else if (index < earliestSrc) {
8206 { 8656 earliestSrc = index; // where delimeter starts in source string
8207 // present and correct 8657 earliestDel = j; // where delimeter is in delarray[]
8208 if (offset[j] < offset[best]) 8658 earliestStr = d; // the delimeter string from delarray[]
8209 { 8659 if (index == i) break; // can't do any better than found at beg of string
8210 // closest so far
8211 best = j;
8212 }
8213 }
8214 } 8660 }
8215 } 8661 }
8216 } 8662 }
8217 8663
8218 // This is the normal exit from the scanning loop 8664 /*
8219 8665 * Output source string starting at i through start of earliest delimeter.
8220 if (best == mlen) 8666 */
8221 { 8667 if (keepNulls || (earliestSrc > i)) {
8222 // no markers were found on this pass 8668 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8223 // so we're pretty much done
8224 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8225 break;
8226 } 8669 }
8227 8670
8228 // Otherwise we just add the newly delimited token 8671 /*
8229 // and recalculate where the search should continue. 8672 * If no delimeter found at or after i, we're done scanning.
8230 8673 */
8231 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8674 if (earliestDel < 0) break;
8232 8675
8233 if (best < seplen) 8676 /*
8234 { 8677 * If delimeter was a spacer, output the spacer.
8235 beginning = offset[best] + (separray[best].ToString()).Length; 8678 */
8236 } 8679 if (earliestDel >= seplen) {
8237 else 8680 outarray[outlen++] = earliestStr;
8238 {
8239 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8240 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8241 } 8681 }
8242 }
8243
8244 // This an awkward an not very intuitive boundary case. If the
8245 // last substring is a tokenizer, then there is an implied trailing
8246 // null list entry. Hopefully the single comparison will not be too
8247 // arduous. Alternatively the 'break' could be replced with a return
8248 // but that's shabby programming.
8249 8682
8250 if (beginning == srclen) 8683 /*
8251 { 8684 * Look at rest of src string following delimeter.
8252 if (srclen != 0) 8685 */
8253 tokens.Add(new LSL_String("")); 8686 i = earliestSrc + earliestStr.Length;
8254 } 8687 }
8255 8688
8256 return tokens; 8689 /*
8690 * Make up an exact-sized output array suitable for an LSL_List object.
8691 */
8692 object[] outlist = new object[outlen];
8693 for (i = 0; i < outlen; i ++) {
8694 outlist[i] = new LSL_String(outarray[i]);
8695 }
8696 return new LSL_List(outlist);
8257 } 8697 }
8258 8698
8259 public LSL_Integer llGetObjectPermMask(int mask) 8699 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8330,28 +8770,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8330 { 8770 {
8331 m_host.AddScriptLPS(1); 8771 m_host.AddScriptLPS(1);
8332 8772
8333 lock (m_host.TaskInventory) 8773 m_host.TaskInventory.LockItemsForRead(true);
8774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8334 { 8775 {
8335 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8776 if (inv.Value.Name == item)
8336 { 8777 {
8337 if (inv.Value.Name == item) 8778 m_host.TaskInventory.LockItemsForRead(false);
8779 switch (mask)
8338 { 8780 {
8339 switch (mask) 8781 case 0:
8340 { 8782 return (int)inv.Value.BasePermissions;
8341 case 0: 8783 case 1:
8342 return (int)inv.Value.BasePermissions; 8784 return (int)inv.Value.CurrentPermissions;
8343 case 1: 8785 case 2:
8344 return (int)inv.Value.CurrentPermissions; 8786 return (int)inv.Value.GroupPermissions;
8345 case 2: 8787 case 3:
8346 return (int)inv.Value.GroupPermissions; 8788 return (int)inv.Value.EveryonePermissions;
8347 case 3: 8789 case 4:
8348 return (int)inv.Value.EveryonePermissions; 8790 return (int)inv.Value.NextPermissions;
8349 case 4:
8350 return (int)inv.Value.NextPermissions;
8351 }
8352 } 8791 }
8353 } 8792 }
8354 } 8793 }
8794 m_host.TaskInventory.LockItemsForRead(false);
8355 8795
8356 return -1; 8796 return -1;
8357 } 8797 }
@@ -8398,16 +8838,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8398 { 8838 {
8399 m_host.AddScriptLPS(1); 8839 m_host.AddScriptLPS(1);
8400 8840
8401 lock (m_host.TaskInventory) 8841 m_host.TaskInventory.LockItemsForRead(true);
8842 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8402 { 8843 {
8403 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8844 if (inv.Value.Name == item)
8404 { 8845 {
8405 if (inv.Value.Name == item) 8846 m_host.TaskInventory.LockItemsForRead(false);
8406 { 8847 return inv.Value.CreatorID.ToString();
8407 return inv.Value.CreatorID.ToString();
8408 }
8409 } 8848 }
8410 } 8849 }
8850 m_host.TaskInventory.LockItemsForRead(false);
8411 8851
8412 llSay(0, "No item name '" + item + "'"); 8852 llSay(0, "No item name '" + item + "'");
8413 8853
@@ -8667,17 +9107,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8667 int width = 0; 9107 int width = 0;
8668 int height = 0; 9108 int height = 0;
8669 9109
8670 ParcelMediaCommandEnum? commandToSend = null; 9110 uint commandToSend = 0;
8671 float time = 0.0f; // default is from start 9111 float time = 0.0f; // default is from start
8672 9112
8673 ScenePresence presence = null; 9113 ScenePresence presence = null;
8674 9114
8675 for (int i = 0; i < commandList.Data.Length; i++) 9115 for (int i = 0; i < commandList.Data.Length; i++)
8676 { 9116 {
8677 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9117 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8678 switch (command) 9118 switch (command)
8679 { 9119 {
8680 case ParcelMediaCommandEnum.Agent: 9120 case (uint)ParcelMediaCommandEnum.Agent:
8681 // we send only to one agent 9121 // we send only to one agent
8682 if ((i + 1) < commandList.Length) 9122 if ((i + 1) < commandList.Length)
8683 { 9123 {
@@ -8694,25 +9134,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8694 } 9134 }
8695 break; 9135 break;
8696 9136
8697 case ParcelMediaCommandEnum.Loop: 9137 case (uint)ParcelMediaCommandEnum.Loop:
8698 loop = 1; 9138 loop = 1;
8699 commandToSend = command; 9139 commandToSend = command;
8700 update = true; //need to send the media update packet to set looping 9140 update = true; //need to send the media update packet to set looping
8701 break; 9141 break;
8702 9142
8703 case ParcelMediaCommandEnum.Play: 9143 case (uint)ParcelMediaCommandEnum.Play:
8704 loop = 0; 9144 loop = 0;
8705 commandToSend = command; 9145 commandToSend = command;
8706 update = true; //need to send the media update packet to make sure it doesn't loop 9146 update = true; //need to send the media update packet to make sure it doesn't loop
8707 break; 9147 break;
8708 9148
8709 case ParcelMediaCommandEnum.Pause: 9149 case (uint)ParcelMediaCommandEnum.Pause:
8710 case ParcelMediaCommandEnum.Stop: 9150 case (uint)ParcelMediaCommandEnum.Stop:
8711 case ParcelMediaCommandEnum.Unload: 9151 case (uint)ParcelMediaCommandEnum.Unload:
8712 commandToSend = command; 9152 commandToSend = command;
8713 break; 9153 break;
8714 9154
8715 case ParcelMediaCommandEnum.Url: 9155 case (uint)ParcelMediaCommandEnum.Url:
8716 if ((i + 1) < commandList.Length) 9156 if ((i + 1) < commandList.Length)
8717 { 9157 {
8718 if (commandList.Data[i + 1] is LSL_String) 9158 if (commandList.Data[i + 1] is LSL_String)
@@ -8725,7 +9165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8725 } 9165 }
8726 break; 9166 break;
8727 9167
8728 case ParcelMediaCommandEnum.Texture: 9168 case (uint)ParcelMediaCommandEnum.Texture:
8729 if ((i + 1) < commandList.Length) 9169 if ((i + 1) < commandList.Length)
8730 { 9170 {
8731 if (commandList.Data[i + 1] is LSL_String) 9171 if (commandList.Data[i + 1] is LSL_String)
@@ -8738,7 +9178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8738 } 9178 }
8739 break; 9179 break;
8740 9180
8741 case ParcelMediaCommandEnum.Time: 9181 case (uint)ParcelMediaCommandEnum.Time:
8742 if ((i + 1) < commandList.Length) 9182 if ((i + 1) < commandList.Length)
8743 { 9183 {
8744 if (commandList.Data[i + 1] is LSL_Float) 9184 if (commandList.Data[i + 1] is LSL_Float)
@@ -8750,7 +9190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8750 } 9190 }
8751 break; 9191 break;
8752 9192
8753 case ParcelMediaCommandEnum.AutoAlign: 9193 case (uint)ParcelMediaCommandEnum.AutoAlign:
8754 if ((i + 1) < commandList.Length) 9194 if ((i + 1) < commandList.Length)
8755 { 9195 {
8756 if (commandList.Data[i + 1] is LSL_Integer) 9196 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8764,7 +9204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8764 } 9204 }
8765 break; 9205 break;
8766 9206
8767 case ParcelMediaCommandEnum.Type: 9207 case (uint)ParcelMediaCommandEnum.Type:
8768 if ((i + 1) < commandList.Length) 9208 if ((i + 1) < commandList.Length)
8769 { 9209 {
8770 if (commandList.Data[i + 1] is LSL_String) 9210 if (commandList.Data[i + 1] is LSL_String)
@@ -8777,7 +9217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8777 } 9217 }
8778 break; 9218 break;
8779 9219
8780 case ParcelMediaCommandEnum.Desc: 9220 case (uint)ParcelMediaCommandEnum.Desc:
8781 if ((i + 1) < commandList.Length) 9221 if ((i + 1) < commandList.Length)
8782 { 9222 {
8783 if (commandList.Data[i + 1] is LSL_String) 9223 if (commandList.Data[i + 1] is LSL_String)
@@ -8790,7 +9230,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8790 } 9230 }
8791 break; 9231 break;
8792 9232
8793 case ParcelMediaCommandEnum.Size: 9233 case (uint)ParcelMediaCommandEnum.Size:
8794 if ((i + 2) < commandList.Length) 9234 if ((i + 2) < commandList.Length)
8795 { 9235 {
8796 if (commandList.Data[i + 1] is LSL_Integer) 9236 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8860,7 +9300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8860 } 9300 }
8861 } 9301 }
8862 9302
8863 if (commandToSend != null) 9303 if (commandToSend != 0)
8864 { 9304 {
8865 // the commandList contained a start/stop/... command, too 9305 // the commandList contained a start/stop/... command, too
8866 if (presence == null) 9306 if (presence == null)
@@ -8897,7 +9337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8897 9337
8898 if (aList.Data[i] != null) 9338 if (aList.Data[i] != null)
8899 { 9339 {
8900 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9340 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
8901 { 9341 {
8902 case ParcelMediaCommandEnum.Url: 9342 case ParcelMediaCommandEnum.Url:
8903 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9343 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -8940,16 +9380,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8940 { 9380 {
8941 m_host.AddScriptLPS(1); 9381 m_host.AddScriptLPS(1);
8942 9382
8943 lock (m_host.TaskInventory) 9383 m_host.TaskInventory.LockItemsForRead(true);
9384 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8944 { 9385 {
8945 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9386 if (inv.Value.Name == name)
8946 { 9387 {
8947 if (inv.Value.Name == name) 9388 m_host.TaskInventory.LockItemsForRead(false);
8948 { 9389 return inv.Value.Type;
8949 return inv.Value.Type;
8950 }
8951 } 9390 }
8952 } 9391 }
9392 m_host.TaskInventory.LockItemsForRead(false);
8953 9393
8954 return -1; 9394 return -1;
8955 } 9395 }
@@ -8960,15 +9400,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8960 9400
8961 if (quick_pay_buttons.Data.Length < 4) 9401 if (quick_pay_buttons.Data.Length < 4)
8962 { 9402 {
8963 LSLError("List must have at least 4 elements"); 9403 int x;
8964 return; 9404 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9405 {
9406 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9407 }
8965 } 9408 }
8966 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9409 int[] nPrice = new int[5];
8967 9410 nPrice[0]=price;
8968 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9411 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8969 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9412 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8970 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9413 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8971 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9414 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9415 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8972 m_host.ParentGroup.HasGroupChanged = true; 9416 m_host.ParentGroup.HasGroupChanged = true;
8973 } 9417 }
8974 9418
@@ -8980,17 +9424,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8980 if (invItemID == UUID.Zero) 9424 if (invItemID == UUID.Zero)
8981 return new LSL_Vector(); 9425 return new LSL_Vector();
8982 9426
8983 lock (m_host.TaskInventory) 9427 m_host.TaskInventory.LockItemsForRead(true);
9428 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8984 { 9429 {
8985 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9430 m_host.TaskInventory.LockItemsForRead(false);
8986 return new LSL_Vector(); 9431 return new LSL_Vector();
9432 }
8987 9433
8988 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9434 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8989 { 9435 {
8990 ShoutError("No permissions to track the camera"); 9436 ShoutError("No permissions to track the camera");
8991 return new LSL_Vector(); 9437 m_host.TaskInventory.LockItemsForRead(false);
8992 } 9438 return new LSL_Vector();
8993 } 9439 }
9440 m_host.TaskInventory.LockItemsForRead(false);
8994 9441
8995 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9442 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8996 if (presence != null) 9443 if (presence != null)
@@ -9008,17 +9455,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9008 if (invItemID == UUID.Zero) 9455 if (invItemID == UUID.Zero)
9009 return new LSL_Rotation(); 9456 return new LSL_Rotation();
9010 9457
9011 lock (m_host.TaskInventory) 9458 m_host.TaskInventory.LockItemsForRead(true);
9459 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9012 { 9460 {
9013 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9461 m_host.TaskInventory.LockItemsForRead(false);
9014 return new LSL_Rotation(); 9462 return new LSL_Rotation();
9015 9463 }
9016 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9464 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9017 { 9465 {
9018 ShoutError("No permissions to track the camera"); 9466 ShoutError("No permissions to track the camera");
9019 return new LSL_Rotation(); 9467 m_host.TaskInventory.LockItemsForRead(false);
9020 } 9468 return new LSL_Rotation();
9021 } 9469 }
9470 m_host.TaskInventory.LockItemsForRead(false);
9022 9471
9023 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9472 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9024 if (presence != null) 9473 if (presence != null)
@@ -9080,8 +9529,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9080 { 9529 {
9081 m_host.AddScriptLPS(1); 9530 m_host.AddScriptLPS(1);
9082 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9531 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9083 if (detectedParams == null) return; // only works on the first detected avatar 9532 if (detectedParams == null)
9084 9533 {
9534 if (m_host.IsAttachment == true)
9535 {
9536 detectedParams = new DetectParams();
9537 detectedParams.Key = m_host.OwnerID;
9538 }
9539 else
9540 {
9541 return;
9542 }
9543 }
9544
9085 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9545 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9086 if (avatar != null) 9546 if (avatar != null)
9087 { 9547 {
@@ -9089,6 +9549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9089 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9549 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9090 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9550 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9091 } 9551 }
9552
9092 ScriptSleep(1000); 9553 ScriptSleep(1000);
9093 } 9554 }
9094 9555
@@ -9168,14 +9629,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9168 if (objectID == UUID.Zero) return; 9629 if (objectID == UUID.Zero) return;
9169 9630
9170 UUID agentID; 9631 UUID agentID;
9171 lock (m_host.TaskInventory) 9632 m_host.TaskInventory.LockItemsForRead(true);
9172 { 9633 // we need the permission first, to know which avatar we want to set the camera for
9173 // we need the permission first, to know which avatar we want to set the camera for 9634 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9174 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9175 9635
9176 if (agentID == UUID.Zero) return; 9636 if (agentID == UUID.Zero)
9177 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9637 {
9638 m_host.TaskInventory.LockItemsForRead(false);
9639 return;
9178 } 9640 }
9641 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9642 {
9643 m_host.TaskInventory.LockItemsForRead(false);
9644 return;
9645 }
9646 m_host.TaskInventory.LockItemsForRead(false);
9179 9647
9180 ScenePresence presence = World.GetScenePresence(agentID); 9648 ScenePresence presence = World.GetScenePresence(agentID);
9181 9649
@@ -9225,12 +9693,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9225 9693
9226 // we need the permission first, to know which avatar we want to clear the camera for 9694 // we need the permission first, to know which avatar we want to clear the camera for
9227 UUID agentID; 9695 UUID agentID;
9228 lock (m_host.TaskInventory) 9696 m_host.TaskInventory.LockItemsForRead(true);
9697 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9698 if (agentID == UUID.Zero)
9699 {
9700 m_host.TaskInventory.LockItemsForRead(false);
9701 return;
9702 }
9703 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9229 { 9704 {
9230 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9705 m_host.TaskInventory.LockItemsForRead(false);
9231 if (agentID == UUID.Zero) return; 9706 return;
9232 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9233 } 9707 }
9708 m_host.TaskInventory.LockItemsForRead(false);
9234 9709
9235 ScenePresence presence = World.GetScenePresence(agentID); 9710 ScenePresence presence = World.GetScenePresence(agentID);
9236 9711
@@ -9297,19 +9772,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9297 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 9772 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9298 { 9773 {
9299 m_host.AddScriptLPS(1); 9774 m_host.AddScriptLPS(1);
9300 string ret = String.Empty; 9775
9301 string src1 = llBase64ToString(str1); 9776 if (str1 == String.Empty)
9302 string src2 = llBase64ToString(str2); 9777 return String.Empty;
9303 int c = 0; 9778 if (str2 == String.Empty)
9304 for (int i = 0; i < src1.Length; i++) 9779 return str1;
9780
9781 byte[] data1 = Convert.FromBase64String(str1);
9782 byte[] data2 = Convert.FromBase64String(str2);
9783
9784 byte[] d2 = new Byte[data1.Length];
9785 int pos = 0;
9786
9787 if (data1.Length <= data2.Length)
9305 { 9788 {
9306 ret += (char) (src1[i] ^ src2[c]); 9789 Array.Copy(data2, 0, d2, 0, data1.Length);
9790 }
9791 else
9792 {
9793 while (pos < data1.Length)
9794 {
9795 int len = data1.Length - pos;
9796 if (len > data2.Length)
9797 len = data2.Length;
9307 9798
9308 c++; 9799 Array.Copy(data2, 0, d2, pos, len);
9309 if (c >= src2.Length) 9800 pos += len;
9310 c = 0; 9801 }
9311 } 9802 }
9312 return llStringToBase64(ret); 9803
9804 for (pos = 0 ; pos < data1.Length ; pos++ )
9805 data1[pos] ^= d2[pos];
9806
9807 return Convert.ToBase64String(data1);
9313 } 9808 }
9314 9809
9315 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 9810 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9687,15 +10182,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9687 10182
9688 internal UUID ScriptByName(string name) 10183 internal UUID ScriptByName(string name)
9689 { 10184 {
9690 lock (m_host.TaskInventory) 10185 m_host.TaskInventory.LockItemsForRead(true);
10186
10187 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9691 { 10188 {
9692 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10189 if (item.Type == 10 && item.Name == name)
9693 { 10190 {
9694 if (item.Type == 10 && item.Name == name) 10191 m_host.TaskInventory.LockItemsForRead(false);
9695 return item.ItemID; 10192 return item.ItemID;
9696 } 10193 }
9697 } 10194 }
9698 10195
10196 m_host.TaskInventory.LockItemsForRead(false);
10197
9699 return UUID.Zero; 10198 return UUID.Zero;
9700 } 10199 }
9701 10200
@@ -9736,6 +10235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9736 { 10235 {
9737 m_host.AddScriptLPS(1); 10236 m_host.AddScriptLPS(1);
9738 10237
10238 //Clone is thread safe
9739 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10239 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9740 10240
9741 UUID assetID = UUID.Zero; 10241 UUID assetID = UUID.Zero;
@@ -9798,6 +10298,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9798 { 10298 {
9799 m_host.AddScriptLPS(1); 10299 m_host.AddScriptLPS(1);
9800 10300
10301 //Clone is thread safe
9801 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10302 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9802 10303
9803 UUID assetID = UUID.Zero; 10304 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index fe71ed5..1fa8c30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -73,6 +73,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 74 m_LSFunctionsEnabled = true;
75 75
76 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
77 m_LSFunctionsEnabled = true;
78
76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); 79 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
77 if (m_comms == null) 80 if (m_comms == null)
78 m_LSFunctionsEnabled = false; 81 m_LSFunctionsEnabled = false;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 01b64eb..db43902 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -769,18 +769,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
769 if (target != null) 769 if (target != null)
770 { 770 {
771 UUID animID=UUID.Zero; 771 UUID animID=UUID.Zero;
772 lock (m_host.TaskInventory) 772 m_host.TaskInventory.LockItemsForRead(true);
773 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
773 { 774 {
774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 775 if (inv.Value.Name == animation)
775 { 776 {
776 if (inv.Value.Name == animation) 777 if (inv.Value.Type == (int)AssetType.Animation)
777 { 778 animID = inv.Value.AssetID;
778 if (inv.Value.Type == (int)AssetType.Animation) 779 continue;
779 animID = inv.Value.AssetID;
780 continue;
781 }
782 } 780 }
783 } 781 }
782 m_host.TaskInventory.LockItemsForRead(false);
784 if (animID == UUID.Zero) 783 if (animID == UUID.Zero)
785 target.Animator.AddAnimation(animation, m_host.UUID); 784 target.Animator.AddAnimation(animation, m_host.UUID);
786 else 785 else
@@ -802,18 +801,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
802 if (target != null) 801 if (target != null)
803 { 802 {
804 UUID animID=UUID.Zero; 803 UUID animID=UUID.Zero;
805 lock (m_host.TaskInventory) 804 m_host.TaskInventory.LockItemsForRead(true);
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
806 { 806 {
807 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 807 if (inv.Value.Name == animation)
808 { 808 {
809 if (inv.Value.Name == animation) 809 if (inv.Value.Type == (int)AssetType.Animation)
810 { 810 animID = inv.Value.AssetID;
811 if (inv.Value.Type == (int)AssetType.Animation) 811 continue;
812 animID = inv.Value.AssetID;
813 continue;
814 }
815 } 812 }
816 } 813 }
814 m_host.TaskInventory.LockItemsForRead(false);
817 815
818 if (animID == UUID.Zero) 816 if (animID == UUID.Zero)
819 target.Animator.RemoveAnimation(animation); 817 target.Animator.RemoveAnimation(animation);
@@ -1664,6 +1662,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1664 1662
1665 if (!UUID.TryParse(name, out assetID)) 1663 if (!UUID.TryParse(name, out assetID))
1666 { 1664 {
1665 m_host.TaskInventory.LockItemsForRead(true);
1667 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1666 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1668 { 1667 {
1669 if (item.Type == 7 && item.Name == name) 1668 if (item.Type == 7 && item.Name == name)
@@ -1671,6 +1670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1671 assetID = item.AssetID; 1670 assetID = item.AssetID;
1672 } 1671 }
1673 } 1672 }
1673 m_host.TaskInventory.LockItemsForRead(false);
1674 } 1674 }
1675 1675
1676 if (assetID == UUID.Zero) 1676 if (assetID == UUID.Zero)
@@ -1717,6 +1717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1717 1717
1718 if (!UUID.TryParse(name, out assetID)) 1718 if (!UUID.TryParse(name, out assetID))
1719 { 1719 {
1720 m_host.TaskInventory.LockItemsForRead(true);
1720 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1721 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1721 { 1722 {
1722 if (item.Type == 7 && item.Name == name) 1723 if (item.Type == 7 && item.Name == name)
@@ -1724,6 +1725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 assetID = item.AssetID; 1725 assetID = item.AssetID;
1725 } 1726 }
1726 } 1727 }
1728 m_host.TaskInventory.LockItemsForRead(false);
1727 } 1729 }
1728 1730
1729 if (assetID == UUID.Zero) 1731 if (assetID == UUID.Zero)
@@ -1774,6 +1776,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1776
1775 if (!UUID.TryParse(name, out assetID)) 1777 if (!UUID.TryParse(name, out assetID))
1776 { 1778 {
1779 m_host.TaskInventory.LockItemsForRead(true);
1777 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1780 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1778 { 1781 {
1779 if (item.Type == 7 && item.Name == name) 1782 if (item.Type == 7 && item.Name == name)
@@ -1781,6 +1784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1781 assetID = item.AssetID; 1784 assetID = item.AssetID;
1782 } 1785 }
1783 } 1786 }
1787 m_host.TaskInventory.LockItemsForRead(false);
1784 } 1788 }
1785 1789
1786 if (assetID == UUID.Zero) 1790 if (assetID == UUID.Zero)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c2abd5..a5b1124 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 dba6502..96f6486 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -274,6 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
274 public const int CHANGED_ALLOWED_DROP = 64; 274 public const int CHANGED_ALLOWED_DROP = 64;
275 public const int CHANGED_OWNER = 128; 275 public const int CHANGED_OWNER = 128;
276 public const int CHANGED_REGION_RESTART = 256; 276 public const int CHANGED_REGION_RESTART = 256;
277 public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART
277 public const int CHANGED_REGION = 512; 278 public const int CHANGED_REGION = 512;
278 public const int CHANGED_TELEPORT = 1024; 279 public const int CHANGED_TELEPORT = 1024;
279 public const int CHANGED_ANIMATION = 16384; 280 public const int CHANGED_ANIMATION = 16384;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3339995..e86d08c 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 3dd381d..b348403 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 b050349..916e27f 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);
@@ -1133,12 +1208,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 private IScriptInstance GetInstance(UUID itemID) 1208 private IScriptInstance GetInstance(UUID itemID)
1134 { 1209 {
1135 IScriptInstance instance; 1210 IScriptInstance instance;
1136 lock (m_Scripts) 1211 lockScriptsForRead(true);
1212 if (!m_Scripts.ContainsKey(itemID))
1137 { 1213 {
1138 if (!m_Scripts.ContainsKey(itemID)) 1214 lockScriptsForRead(false);
1139 return null; 1215 return null;
1140 instance = m_Scripts[itemID];
1141 } 1216 }
1217 instance = m_Scripts[itemID];
1218 lockScriptsForRead(false);
1142 return instance; 1219 return instance;
1143 } 1220 }
1144 1221
@@ -1162,6 +1239,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1162 return false; 1239 return false;
1163 } 1240 }
1164 1241
1242 [DebuggerNonUserCode]
1165 public void ApiResetScript(UUID itemID) 1243 public void ApiResetScript(UUID itemID)
1166 { 1244 {
1167 IScriptInstance instance = GetInstance(itemID); 1245 IScriptInstance instance = GetInstance(itemID);
@@ -1213,6 +1291,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return UUID.Zero; 1291 return UUID.Zero;
1214 } 1292 }
1215 1293
1294 [DebuggerNonUserCode]
1216 public void SetState(UUID itemID, string newState) 1295 public void SetState(UUID itemID, string newState)
1217 { 1296 {
1218 IScriptInstance instance = GetInstance(itemID); 1297 IScriptInstance instance = GetInstance(itemID);
@@ -1233,11 +1312,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1233 { 1312 {
1234 List<IScriptInstance> instances = new List<IScriptInstance>(); 1313 List<IScriptInstance> instances = new List<IScriptInstance>();
1235 1314
1236 lock (m_Scripts) 1315 lockScriptsForRead(true);
1237 { 1316 foreach (IScriptInstance instance in m_Scripts.Values)
1238 foreach (IScriptInstance instance in m_Scripts.Values)
1239 instances.Add(instance); 1317 instances.Add(instance);
1240 } 1318 lockScriptsForRead(false);
1241 1319
1242 foreach (IScriptInstance i in instances) 1320 foreach (IScriptInstance i in instances)
1243 { 1321 {