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/LSL_Api.cs1724
-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.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs424
14 files changed, 1470 insertions, 838 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c5226ba..976a9ff 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
@@ -480,25 +548,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
480 return remainder; 548 return remainder;
481 } 549 }
482 550
483 // Old implementation of llRot2Euler, now normalized 551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
484
485 public LSL_Vector llRot2Euler(LSL_Rotation r)
486 { 552 {
487 m_host.AddScriptLPS(1); 553 m_host.AddScriptLPS(1);
488 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 554 LSL_Vector eul = new LSL_Vector();
489 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 555
490 double m = (t.x + t.y + t.z + t.s); 556 double sqw = q1.s*q1.s;
491 if (m == 0) return new LSL_Vector(); 557 double sqx = q1.x*q1.x;
492 double n = 2 * (r.y * r.s + r.x * r.z); 558 double sqy = q1.z*q1.z;
493 double p = m * m - n * n; 559 double sqz = q1.y*q1.y;
494 if (p > 0) 560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
495 return new LSL_Vector(NormalizeAngle(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;
496 NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), 562 if (test > 0.4999*unit) { // singularity at north pole
497 NormalizeAngle(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);
498 else if (n > 0) 564 eul.y = Math.PI/2;
499 return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); 565 eul.x = 0;
500 else 566 return eul;
501 return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(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;
502 } 578 }
503 579
504 /* From wiki: 580 /* From wiki:
@@ -700,77 +776,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
700 { 776 {
701 //A and B should both be normalized 777 //A and B should both be normalized
702 m_host.AddScriptLPS(1); 778 m_host.AddScriptLPS(1);
703 LSL_Rotation rotBetween; 779 /* This method is more accurate than the SL one, and thus causes problems
704 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 780 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
705 // continue calculation. 781
706 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)
707 { 810 {
708 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);
709 } 812 }
710 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)
711 { 824 {
712 a = LSL_Vector.Norm(a); 825 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
713 b = LSL_Vector.Norm(b); 826 }
714 double dotProduct = LSL_Vector.Dot(a, b); 827
715 // There are two degenerate cases possible. These are for vectors 180 or 828 // Check if anti-parallel
716 // 0 degrees apart. These have to be detected and handled individually. 829 else if (cos_theta < -0.99999)
717 // 830 {
718 // 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);
719 // 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);
720 if (dotProduct < -0.9999999f) 833 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
721 { 834 }
722 // First assume X axis is orthogonal to the vectors. 835 else // other rotation
723 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 836 {
724 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 837 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
725 // Check for near zero vector. A very small non-zero number here will create 838 axis = llVecNorm(axis);
726 // a rotation in an undesired direction. 839 double x, y, z, s, t;
727 if (LSL_Vector.Mag(orthoVector) > 0.0001) 840 s = Math.Cos(theta);
728 { 841 t = Math.Sin(theta);
729 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 842 x = axis.x * t;
730 } 843 y = axis.y * t;
731 // If the magnitude of the vector was near zero, then assume the X axis is not 844 z = axis.z * t;
732 // orthogonal and use the Z axis instead. 845 return new LSL_Rotation(x,y,z,s);
733 else
734 {
735 // Set 180 z rotation.
736 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
737 }
738 }
739 // Check for parallel vectors.
740 // A dot product of 1 would mean the angle between vectors is 0 degrees.
741 else if (dotProduct > 0.9999999f)
742 {
743 // Set zero rotation.
744 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
745 }
746 else
747 {
748 // All special checks have been performed so get the axis of rotation.
749 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
750 // Quarternion s value is the length of the unit vector + dot product.
751 double qs = 1.0 + dotProduct;
752 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
753 // Normalize the rotation.
754 double mag = LSL_Rotation.Mag(rotBetween);
755 // We shouldn't have to worry about a divide by zero here. The qs value will be
756 // non-zero because we already know if we're here, then the dotProduct is not -1 so
757 // qs will not be zero. Also, we've already handled the input vectors being zero so the
758 // crossProduct vector should also not be zero.
759 rotBetween.x = rotBetween.x / mag;
760 rotBetween.y = rotBetween.y / mag;
761 rotBetween.z = rotBetween.z / mag;
762 rotBetween.s = rotBetween.s / mag;
763 // Check for undefined values and set zero rotation if any found. This code might not actually be required
764 // any longer since zero vectors are checked for at the top.
765 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
766 {
767 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
768 }
769 }
770 } 846 }
771 return rotBetween;
772 } 847 }
773 848
774 public void llWhisper(int channelID, string text) 849 public void llWhisper(int channelID, string text)
775 { 850 {
776 m_host.AddScriptLPS(1); 851 m_host.AddScriptLPS(1);
@@ -1094,10 +1169,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1094 return detectedParams.TouchUV; 1169 return detectedParams.TouchUV;
1095 } 1170 }
1096 1171
1172 [DebuggerNonUserCode]
1097 public virtual void llDie() 1173 public virtual void llDie()
1098 { 1174 {
1099 m_host.AddScriptLPS(1); 1175 m_host.AddScriptLPS(1);
1100 throw new SelfDeleteException(); 1176 if (!m_host.IsAttachment) throw new SelfDeleteException();
1101 } 1177 }
1102 1178
1103 public LSL_Float llGround(LSL_Vector offset) 1179 public LSL_Float llGround(LSL_Vector offset)
@@ -1170,6 +1246,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1170 1246
1171 public void llSetStatus(int status, int value) 1247 public void llSetStatus(int status, int value)
1172 { 1248 {
1249 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1250 return;
1173 m_host.AddScriptLPS(1); 1251 m_host.AddScriptLPS(1);
1174 1252
1175 int statusrotationaxis = 0; 1253 int statusrotationaxis = 0;
@@ -1399,6 +1477,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1399 { 1477 {
1400 m_host.AddScriptLPS(1); 1478 m_host.AddScriptLPS(1);
1401 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
1402 if (face == ScriptBaseClass.ALL_SIDES) 1522 if (face == ScriptBaseClass.ALL_SIDES)
1403 face = SceneObjectPart.ALL_SIDES; 1523 face = SceneObjectPart.ALL_SIDES;
1404 1524
@@ -1407,6 +1527,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1407 1527
1408 public void SetTexGen(SceneObjectPart part, int face,int style) 1528 public void SetTexGen(SceneObjectPart part, int face,int style)
1409 { 1529 {
1530 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1531 return;
1532
1410 Primitive.TextureEntry tex = part.Shape.Textures; 1533 Primitive.TextureEntry tex = part.Shape.Textures;
1411 MappingType textype; 1534 MappingType textype;
1412 textype = MappingType.Default; 1535 textype = MappingType.Default;
@@ -1437,6 +1560,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1437 1560
1438 public void SetGlow(SceneObjectPart part, int face, float glow) 1561 public void SetGlow(SceneObjectPart part, int face, float glow)
1439 { 1562 {
1563 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1564 return;
1565
1440 Primitive.TextureEntry tex = part.Shape.Textures; 1566 Primitive.TextureEntry tex = part.Shape.Textures;
1441 if (face >= 0 && face < GetNumberOfSides(part)) 1567 if (face >= 0 && face < GetNumberOfSides(part))
1442 { 1568 {
@@ -1462,6 +1588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1462 1588
1463 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1589 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1464 { 1590 {
1591 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1592 return;
1465 1593
1466 Shininess sval = new Shininess(); 1594 Shininess sval = new Shininess();
1467 1595
@@ -1512,6 +1640,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1512 1640
1513 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1641 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1514 { 1642 {
1643 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return;
1645
1515 Primitive.TextureEntry tex = part.Shape.Textures; 1646 Primitive.TextureEntry tex = part.Shape.Textures;
1516 if (face >= 0 && face < GetNumberOfSides(part)) 1647 if (face >= 0 && face < GetNumberOfSides(part))
1517 { 1648 {
@@ -1572,13 +1703,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1572 m_host.AddScriptLPS(1); 1703 m_host.AddScriptLPS(1);
1573 1704
1574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1705 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1575 1706 if (parts.Count > 0)
1576 foreach (SceneObjectPart part in parts) 1707 {
1577 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 }
1578 } 1719 }
1579 1720
1580 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1721 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1581 { 1722 {
1723 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1724 return;
1725
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1726 Primitive.TextureEntry tex = part.Shape.Textures;
1583 Color4 texcolor; 1727 Color4 texcolor;
1584 if (face >= 0 && face < GetNumberOfSides(part)) 1728 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1624,7 +1768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1624 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,
1625 float wind, float tension, LSL_Vector Force) 1769 float wind, float tension, LSL_Vector Force)
1626 { 1770 {
1627 if (part == null) 1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1628 return; 1772 return;
1629 1773
1630 if (flexi) 1774 if (flexi)
@@ -1659,7 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1659 /// <param name="falloff"></param> 1803 /// <param name="falloff"></param>
1660 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)
1661 { 1805 {
1662 if (part == null) 1806 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return; 1807 return;
1664 1808
1665 if (light) 1809 if (light)
@@ -1736,15 +1880,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1736 m_host.AddScriptLPS(1); 1880 m_host.AddScriptLPS(1);
1737 1881
1738 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1882 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1739 1883 if (parts.Count > 0)
1740 foreach (SceneObjectPart part in parts) 1884 {
1741 SetTexture(part, texture, face); 1885 try
1742 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 }
1743 ScriptSleep(200); 1896 ScriptSleep(200);
1744 } 1897 }
1745 1898
1746 protected void SetTexture(SceneObjectPart part, string texture, int face) 1899 protected void SetTexture(SceneObjectPart part, string texture, int face)
1747 { 1900 {
1901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1902 return;
1903
1748 UUID textureID=new UUID(); 1904 UUID textureID=new UUID();
1749 1905
1750 if (!UUID.TryParse(texture, out textureID)) 1906 if (!UUID.TryParse(texture, out textureID))
@@ -1790,6 +1946,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1790 1946
1791 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1792 { 1948 {
1949 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1950 return;
1951
1793 Primitive.TextureEntry tex = part.Shape.Textures; 1952 Primitive.TextureEntry tex = part.Shape.Textures;
1794 if (face >= 0 && face < GetNumberOfSides(part)) 1953 if (face >= 0 && face < GetNumberOfSides(part))
1795 { 1954 {
@@ -1826,6 +1985,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1826 1985
1827 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1986 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1828 { 1987 {
1988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1989 return;
1990
1829 Primitive.TextureEntry tex = part.Shape.Textures; 1991 Primitive.TextureEntry tex = part.Shape.Textures;
1830 if (face >= 0 && face < GetNumberOfSides(part)) 1992 if (face >= 0 && face < GetNumberOfSides(part))
1831 { 1993 {
@@ -1862,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1862 2024
1863 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2025 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1864 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1865 Primitive.TextureEntry tex = part.Shape.Textures; 2030 Primitive.TextureEntry tex = part.Shape.Textures;
1866 if (face >= 0 && face < GetNumberOfSides(part)) 2031 if (face >= 0 && face < GetNumberOfSides(part))
1867 { 2032 {
@@ -1932,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 2097
1933 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2098 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1934 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1935 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2103 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1936 LSL_Vector currentPos = llGetLocalPos(); 2104 LSL_Vector currentPos = llGetLocalPos();
1937 2105
@@ -1968,6 +2136,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1968 public LSL_Vector llGetLocalPos() 2136 public LSL_Vector llGetLocalPos()
1969 { 2137 {
1970 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
1971 if (m_host.ParentID != 0) 2155 if (m_host.ParentID != 0)
1972 { 2156 {
1973 return new LSL_Vector(m_host.OffsetPosition.X, 2157 return new LSL_Vector(m_host.OffsetPosition.X,
@@ -2018,6 +2202,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2202
2019 protected void SetRot(SceneObjectPart part, Quaternion rot) 2203 protected void SetRot(SceneObjectPart part, Quaternion rot)
2020 { 2204 {
2205 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2206 return;
2207
2021 part.UpdateRotation(rot); 2208 part.UpdateRotation(rot);
2022 // 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.
2023 2210
@@ -2637,12 +2824,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2637 2824
2638 m_host.AddScriptLPS(1); 2825 m_host.AddScriptLPS(1);
2639 2826
2827 m_host.TaskInventory.LockItemsForRead(true);
2640 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2828 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2641 2829 m_host.TaskInventory.LockItemsForRead(false);
2642 lock (m_host.TaskInventory)
2643 {
2644 item = m_host.TaskInventory[invItemID];
2645 }
2646 2830
2647 if (item.PermsGranter == UUID.Zero) 2831 if (item.PermsGranter == UUID.Zero)
2648 return 0; 2832 return 0;
@@ -2717,6 +2901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2717 if (dist > m_ScriptDistanceFactor * 10.0f) 2901 if (dist > m_ScriptDistanceFactor * 10.0f)
2718 return; 2902 return;
2719 2903
2904 //Clone is thread-safe
2720 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2905 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2721 2906
2722 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2779,6 +2964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2779 2964
2780 public void llLookAt(LSL_Vector target, double strength, double damping) 2965 public void llLookAt(LSL_Vector target, double strength, double damping)
2781 { 2966 {
2967 /*
2782 m_host.AddScriptLPS(1); 2968 m_host.AddScriptLPS(1);
2783 // Determine where we are looking from 2969 // Determine where we are looking from
2784 LSL_Vector from = llGetPos(); 2970 LSL_Vector from = llGetPos();
@@ -2798,10 +2984,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2798 // the angles of rotation in radians into rotation value 2984 // the angles of rotation in radians into rotation value
2799 2985
2800 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2986 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2801 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2987
2802 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
2803 // Orient the object to the angle calculated 2992 // Orient the object to the angle calculated
2804 //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
2805 } 3012 }
2806 3013
2807 public void llStopLookAt() 3014 public void llStopLookAt()
@@ -2850,13 +3057,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2850 { 3057 {
2851 TaskInventoryItem item; 3058 TaskInventoryItem item;
2852 3059
2853 lock (m_host.TaskInventory) 3060 m_host.TaskInventory.LockItemsForRead(true);
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2854 { 3062 {
2855 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3063 m_host.TaskInventory.LockItemsForRead(false);
2856 return; 3064 return;
2857 else 3065 }
2858 item = m_host.TaskInventory[InventorySelf()]; 3066 else
3067 {
3068 item = m_host.TaskInventory[InventorySelf()];
2859 } 3069 }
3070 m_host.TaskInventory.LockItemsForRead(false);
2860 3071
2861 if (item.PermsGranter != UUID.Zero) 3072 if (item.PermsGranter != UUID.Zero)
2862 { 3073 {
@@ -2878,13 +3089,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 { 3089 {
2879 TaskInventoryItem item; 3090 TaskInventoryItem item;
2880 3091
3092 m_host.TaskInventory.LockItemsForRead(true);
2881 lock (m_host.TaskInventory) 3093 lock (m_host.TaskInventory)
2882 { 3094 {
3095
2883 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3096 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3097 {
3098 m_host.TaskInventory.LockItemsForRead(false);
2884 return; 3099 return;
3100 }
2885 else 3101 else
3102 {
2886 item = m_host.TaskInventory[InventorySelf()]; 3103 item = m_host.TaskInventory[InventorySelf()];
3104 }
2887 } 3105 }
3106 m_host.TaskInventory.LockItemsForRead(false);
2888 3107
2889 m_host.AddScriptLPS(1); 3108 m_host.AddScriptLPS(1);
2890 3109
@@ -2916,19 +3135,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3135 {
2917 m_host.AddScriptLPS(1); 3136 m_host.AddScriptLPS(1);
2918 3137
2919 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2920 return;
2921
2922 TaskInventoryItem item; 3138 TaskInventoryItem item;
2923 3139
2924 lock (m_host.TaskInventory) 3140 m_host.TaskInventory.LockItemsForRead(true);
3141
3142 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2925 { 3143 {
2926 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3144 m_host.TaskInventory.LockItemsForRead(false);
2927 return; 3145 return;
2928 else 3146 }
2929 item = m_host.TaskInventory[InventorySelf()]; 3147 else
3148 {
3149 item = m_host.TaskInventory[InventorySelf()];
2930 } 3150 }
2931 3151
3152 m_host.TaskInventory.LockItemsForRead(false);
3153
2932 if (item.PermsGranter != m_host.OwnerID) 3154 if (item.PermsGranter != m_host.OwnerID)
2933 return; 3155 return;
2934 3156
@@ -2938,11 +3160,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 3160
2939 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3161 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2940 3162
3163 /*
2941 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3164 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2942 if (attachmentsModule != null) 3165 if (attachmentsModule != null)
3166 {
2943 attachmentsModule.AttachObject( 3167 attachmentsModule.AttachObject(
2944 presence.ControllingClient, grp.LocalId, 3168 presence.ControllingClient, grp.LocalId,
2945 (uint)attachment, Quaternion.Identity, Vector3.Zero, false); 3169 (uint)attachment, Quaternion.Identity, Vector3.Zero, false);
3170 }
3171 */
3172 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2946 } 3173 }
2947 } 3174 }
2948 3175
@@ -2955,13 +3182,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2955 3182
2956 TaskInventoryItem item; 3183 TaskInventoryItem item;
2957 3184
2958 lock (m_host.TaskInventory) 3185 m_host.TaskInventory.LockItemsForRead(true);
3186
3187 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2959 { 3188 {
2960 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3189 m_host.TaskInventory.LockItemsForRead(false);
2961 return; 3190 return;
2962 else 3191 }
2963 item = m_host.TaskInventory[InventorySelf()]; 3192 else
3193 {
3194 item = m_host.TaskInventory[InventorySelf()];
2964 } 3195 }
3196 m_host.TaskInventory.LockItemsForRead(false);
3197
2965 3198
2966 if (item.PermsGranter != m_host.OwnerID) 3199 if (item.PermsGranter != m_host.OwnerID)
2967 return; 3200 return;
@@ -2998,8 +3231,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2998 return m_host.OwnerID.ToString(); 3231 return m_host.OwnerID.ToString();
2999 } 3232 }
3000 3233
3234 [DebuggerNonUserCode]
3001 public void llInstantMessage(string user, string message) 3235 public void llInstantMessage(string user, string message)
3002 { 3236 {
3237 UUID result;
3238 if (!UUID.TryParse(user, out result))
3239 {
3240 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3241 return;
3242 }
3243
3244
3003 m_host.AddScriptLPS(1); 3245 m_host.AddScriptLPS(1);
3004 3246
3005 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3247 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3014,14 +3256,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3014 UUID friendTransactionID = UUID.Random(); 3256 UUID friendTransactionID = UUID.Random();
3015 3257
3016 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3258 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3017 3259
3018 GridInstantMessage msg = new GridInstantMessage(); 3260 GridInstantMessage msg = new GridInstantMessage();
3019 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3261 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3020 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3262 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3021 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3263 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3022// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3264// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3023// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3265// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3024 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3266 DateTime dt = DateTime.UtcNow;
3267
3268 // Ticks from UtcNow, but make it look like local. Evil, huh?
3269 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3270
3271 try
3272 {
3273 // Convert that to the PST timezone
3274 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3275 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3276 }
3277 catch
3278 {
3279 // No logging here, as it could be VERY spammy
3280 }
3281
3282 // And make it look local again to fool the unix time util
3283 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3284
3285 msg.timestamp = (uint)Util.ToUnixTime(dt);
3286
3025 //if (client != null) 3287 //if (client != null)
3026 //{ 3288 //{
3027 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3289 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3035,13 +3297,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3035 msg.message = message.Substring(0, 1024); 3297 msg.message = message.Substring(0, 1024);
3036 else 3298 else
3037 msg.message = message; 3299 msg.message = message;
3038 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3300 msg.dialog = (byte)19; // MessageFromObject
3039 msg.fromGroup = false;// fromGroup; 3301 msg.fromGroup = false;// fromGroup;
3040 msg.offline = (byte)0; //offline; 3302 msg.offline = (byte)0; //offline;
3041 msg.ParentEstateID = 0; //ParentEstateID; 3303 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3042 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3304 msg.Position = new Vector3(m_host.AbsolutePosition);
3043 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3305 msg.RegionID = World.RegionInfo.RegionID.Guid;
3044 msg.binaryBucket = new byte[0];// binaryBucket; 3306 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3045 3307
3046 if (m_TransferModule != null) 3308 if (m_TransferModule != null)
3047 { 3309 {
@@ -3163,13 +3425,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3163 m_host.AddScriptLPS(1); 3425 m_host.AddScriptLPS(1);
3164 } 3426 }
3165 3427
3166 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3167 {
3168 m_host.AddScriptLPS(1);
3169 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3170 m_host.RotLookAt(rot, (float)strength, (float)damping);
3171 }
3172
3173 public LSL_Integer llStringLength(string str) 3428 public LSL_Integer llStringLength(string str)
3174 { 3429 {
3175 m_host.AddScriptLPS(1); 3430 m_host.AddScriptLPS(1);
@@ -3193,14 +3448,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3193 3448
3194 TaskInventoryItem item; 3449 TaskInventoryItem item;
3195 3450
3196 lock (m_host.TaskInventory) 3451 m_host.TaskInventory.LockItemsForRead(true);
3452 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3197 { 3453 {
3198 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3454 m_host.TaskInventory.LockItemsForRead(false);
3199 return; 3455 return;
3200 else
3201 item = m_host.TaskInventory[InventorySelf()];
3202 } 3456 }
3203 3457 else
3458 {
3459 item = m_host.TaskInventory[InventorySelf()];
3460 }
3461 m_host.TaskInventory.LockItemsForRead(false);
3204 if (item.PermsGranter == UUID.Zero) 3462 if (item.PermsGranter == UUID.Zero)
3205 return; 3463 return;
3206 3464
@@ -3230,13 +3488,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3230 3488
3231 TaskInventoryItem item; 3489 TaskInventoryItem item;
3232 3490
3233 lock (m_host.TaskInventory) 3491 m_host.TaskInventory.LockItemsForRead(true);
3492 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3234 { 3493 {
3235 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3494 m_host.TaskInventory.LockItemsForRead(false);
3236 return; 3495 return;
3237 else 3496 }
3238 item = m_host.TaskInventory[InventorySelf()]; 3497 else
3498 {
3499 item = m_host.TaskInventory[InventorySelf()];
3239 } 3500 }
3501 m_host.TaskInventory.LockItemsForRead(false);
3502
3240 3503
3241 if (item.PermsGranter == UUID.Zero) 3504 if (item.PermsGranter == UUID.Zero)
3242 return; 3505 return;
@@ -3313,10 +3576,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3313 3576
3314 TaskInventoryItem item; 3577 TaskInventoryItem item;
3315 3578
3316 lock (m_host.TaskInventory) 3579
3580 m_host.TaskInventory.LockItemsForRead(true);
3581 if (!m_host.TaskInventory.ContainsKey(invItemID))
3582 {
3583 m_host.TaskInventory.LockItemsForRead(false);
3584 return;
3585 }
3586 else
3317 { 3587 {
3318 item = m_host.TaskInventory[invItemID]; 3588 item = m_host.TaskInventory[invItemID];
3319 } 3589 }
3590 m_host.TaskInventory.LockItemsForRead(false);
3320 3591
3321 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3592 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3322 { 3593 {
@@ -3348,11 +3619,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3348 3619
3349 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3620 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3350 { 3621 {
3351 lock (m_host.TaskInventory) 3622 m_host.TaskInventory.LockItemsForWrite(true);
3352 { 3623 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3353 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3624 m_host.TaskInventory[invItemID].PermsMask = perm;
3354 m_host.TaskInventory[invItemID].PermsMask = perm; 3625 m_host.TaskInventory.LockItemsForWrite(false);
3355 }
3356 3626
3357 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3627 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3358 "run_time_permissions", new Object[] { 3628 "run_time_permissions", new Object[] {
@@ -3372,11 +3642,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3372 3642
3373 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3643 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3374 { 3644 {
3375 lock (m_host.TaskInventory) 3645 m_host.TaskInventory.LockItemsForWrite(true);
3376 { 3646 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3377 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3647 m_host.TaskInventory[invItemID].PermsMask = perm;
3378 m_host.TaskInventory[invItemID].PermsMask = perm; 3648 m_host.TaskInventory.LockItemsForWrite(false);
3379 }
3380 3649
3381 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3650 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3382 "run_time_permissions", new Object[] { 3651 "run_time_permissions", new Object[] {
@@ -3397,11 +3666,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3397 3666
3398 if (!m_waitingForScriptAnswer) 3667 if (!m_waitingForScriptAnswer)
3399 { 3668 {
3400 lock (m_host.TaskInventory) 3669 m_host.TaskInventory.LockItemsForWrite(true);
3401 { 3670 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3402 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3671 m_host.TaskInventory[invItemID].PermsMask = 0;
3403 m_host.TaskInventory[invItemID].PermsMask = 0; 3672 m_host.TaskInventory.LockItemsForWrite(false);
3404 }
3405 3673
3406 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3674 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3407 m_waitingForScriptAnswer=true; 3675 m_waitingForScriptAnswer=true;
@@ -3436,10 +3704,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3436 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3704 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3437 llReleaseControls(); 3705 llReleaseControls();
3438 3706
3439 lock (m_host.TaskInventory) 3707
3440 { 3708 m_host.TaskInventory.LockItemsForWrite(true);
3441 m_host.TaskInventory[invItemID].PermsMask = answer; 3709 m_host.TaskInventory[invItemID].PermsMask = answer;
3442 } 3710 m_host.TaskInventory.LockItemsForWrite(false);
3711
3443 3712
3444 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3713 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3445 "run_time_permissions", new Object[] { 3714 "run_time_permissions", new Object[] {
@@ -3451,16 +3720,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3451 { 3720 {
3452 m_host.AddScriptLPS(1); 3721 m_host.AddScriptLPS(1);
3453 3722
3454 lock (m_host.TaskInventory) 3723 m_host.TaskInventory.LockItemsForRead(true);
3724
3725 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3455 { 3726 {
3456 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3727 if (item.Type == 10 && item.ItemID == m_itemID)
3457 { 3728 {
3458 if (item.Type == 10 && item.ItemID == m_itemID) 3729 m_host.TaskInventory.LockItemsForRead(false);
3459 { 3730 return item.PermsGranter.ToString();
3460 return item.PermsGranter.ToString();
3461 }
3462 } 3731 }
3463 } 3732 }
3733 m_host.TaskInventory.LockItemsForRead(false);
3464 3734
3465 return UUID.Zero.ToString(); 3735 return UUID.Zero.ToString();
3466 } 3736 }
@@ -3469,19 +3739,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3469 { 3739 {
3470 m_host.AddScriptLPS(1); 3740 m_host.AddScriptLPS(1);
3471 3741
3472 lock (m_host.TaskInventory) 3742 m_host.TaskInventory.LockItemsForRead(true);
3743
3744 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3473 { 3745 {
3474 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3746 if (item.Type == 10 && item.ItemID == m_itemID)
3475 { 3747 {
3476 if (item.Type == 10 && item.ItemID == m_itemID) 3748 int perms = item.PermsMask;
3477 { 3749 if (m_automaticLinkPermission)
3478 int perms = item.PermsMask; 3750 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3479 if (m_automaticLinkPermission) 3751 m_host.TaskInventory.LockItemsForRead(false);
3480 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3752 return perms;
3481 return perms;
3482 }
3483 } 3753 }
3484 } 3754 }
3755 m_host.TaskInventory.LockItemsForRead(false);
3485 3756
3486 return 0; 3757 return 0;
3487 } 3758 }
@@ -3503,9 +3774,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3503 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3774 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3504 { 3775 {
3505 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3776 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3506 3777 if (parts.Count > 0)
3507 foreach (SceneObjectPart part in parts) 3778 {
3508 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3779 try
3780 {
3781 parts[0].ParentGroup.areUpdatesSuspended = true;
3782 foreach (SceneObjectPart part in parts)
3783 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3784 }
3785 finally
3786 {
3787 parts[0].ParentGroup.areUpdatesSuspended = false;
3788 }
3789 }
3509 } 3790 }
3510 3791
3511 public void llCreateLink(string target, int parent) 3792 public void llCreateLink(string target, int parent)
@@ -3514,11 +3795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3514 UUID invItemID = InventorySelf(); 3795 UUID invItemID = InventorySelf();
3515 3796
3516 TaskInventoryItem item; 3797 TaskInventoryItem item;
3517 lock (m_host.TaskInventory) 3798 m_host.TaskInventory.LockItemsForRead(true);
3518 { 3799 item = m_host.TaskInventory[invItemID];
3519 item = m_host.TaskInventory[invItemID]; 3800 m_host.TaskInventory.LockItemsForRead(false);
3520 } 3801
3521
3522 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3802 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3523 && !m_automaticLinkPermission) 3803 && !m_automaticLinkPermission)
3524 { 3804 {
@@ -3571,16 +3851,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3571 m_host.AddScriptLPS(1); 3851 m_host.AddScriptLPS(1);
3572 UUID invItemID = InventorySelf(); 3852 UUID invItemID = InventorySelf();
3573 3853
3574 lock (m_host.TaskInventory) 3854 m_host.TaskInventory.LockItemsForRead(true);
3575 {
3576 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3855 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3577 && !m_automaticLinkPermission) 3856 && !m_automaticLinkPermission)
3578 { 3857 {
3579 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3858 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3859 m_host.TaskInventory.LockItemsForRead(false);
3580 return; 3860 return;
3581 } 3861 }
3582 } 3862 m_host.TaskInventory.LockItemsForRead(false);
3583 3863
3584 if (linknum < ScriptBaseClass.LINK_THIS) 3864 if (linknum < ScriptBaseClass.LINK_THIS)
3585 return; 3865 return;
3586 3866
@@ -3619,10 +3899,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3619 // Restructuring Multiple Prims. 3899 // Restructuring Multiple Prims.
3620 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3900 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3621 parts.Remove(parentPrim.RootPart); 3901 parts.Remove(parentPrim.RootPart);
3622 foreach (SceneObjectPart part in parts) 3902 if (parts.Count > 0)
3623 { 3903 {
3624 parentPrim.DelinkFromGroup(part.LocalId, true); 3904 try
3905 {
3906 parts[0].ParentGroup.areUpdatesSuspended = true;
3907 foreach (SceneObjectPart part in parts)
3908 {
3909 parentPrim.DelinkFromGroup(part.LocalId, true);
3910 }
3911 }
3912 finally
3913 {
3914 parts[0].ParentGroup.areUpdatesSuspended = false;
3915 }
3625 } 3916 }
3917
3626 parentPrim.HasGroupChanged = true; 3918 parentPrim.HasGroupChanged = true;
3627 parentPrim.ScheduleGroupForFullUpdate(); 3919 parentPrim.ScheduleGroupForFullUpdate();
3628 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3920 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3631,11 +3923,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3631 { 3923 {
3632 SceneObjectPart newRoot = parts[0]; 3924 SceneObjectPart newRoot = parts[0];
3633 parts.Remove(newRoot); 3925 parts.Remove(newRoot);
3634 foreach (SceneObjectPart part in parts) 3926
3927 try
3635 { 3928 {
3636 part.UpdateFlag = 0; 3929 parts[0].ParentGroup.areUpdatesSuspended = true;
3637 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3930 foreach (SceneObjectPart part in parts)
3931 {
3932 part.UpdateFlag = 0;
3933 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3934 }
3638 } 3935 }
3936 finally
3937 {
3938 parts[0].ParentGroup.areUpdatesSuspended = false;
3939 }
3940
3941
3639 newRoot.ParentGroup.HasGroupChanged = true; 3942 newRoot.ParentGroup.HasGroupChanged = true;
3640 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3943 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3641 } 3944 }
@@ -3661,11 +3964,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 3964
3662 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3965 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3663 parts.Remove(parentPrim.RootPart); 3966 parts.Remove(parentPrim.RootPart);
3664 3967 if (parts.Count > 0)
3665 foreach (SceneObjectPart part in parts)
3666 { 3968 {
3667 parentPrim.DelinkFromGroup(part.LocalId, true); 3969 try
3668 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3970 {
3971 parts[0].ParentGroup.areUpdatesSuspended = true;
3972 foreach (SceneObjectPart part in parts)
3973 {
3974 parentPrim.DelinkFromGroup(part.LocalId, true);
3975 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3976 }
3977 }
3978 finally
3979 {
3980 parts[0].ParentGroup.areUpdatesSuspended = false;
3981 }
3669 } 3982 }
3670 parentPrim.HasGroupChanged = true; 3983 parentPrim.HasGroupChanged = true;
3671 parentPrim.ScheduleGroupForFullUpdate(); 3984 parentPrim.ScheduleGroupForFullUpdate();
@@ -3757,17 +4070,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3757 m_host.AddScriptLPS(1); 4070 m_host.AddScriptLPS(1);
3758 int count = 0; 4071 int count = 0;
3759 4072
3760 lock (m_host.TaskInventory) 4073 m_host.TaskInventory.LockItemsForRead(true);
4074 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3761 { 4075 {
3762 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4076 if (inv.Value.Type == type || type == -1)
3763 { 4077 {
3764 if (inv.Value.Type == type || type == -1) 4078 count = count + 1;
3765 {
3766 count = count + 1;
3767 }
3768 } 4079 }
3769 } 4080 }
3770 4081
4082 m_host.TaskInventory.LockItemsForRead(false);
3771 return count; 4083 return count;
3772 } 4084 }
3773 4085
@@ -3776,16 +4088,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3776 m_host.AddScriptLPS(1); 4088 m_host.AddScriptLPS(1);
3777 ArrayList keys = new ArrayList(); 4089 ArrayList keys = new ArrayList();
3778 4090
3779 lock (m_host.TaskInventory) 4091 m_host.TaskInventory.LockItemsForRead(true);
4092 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3780 { 4093 {
3781 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4094 if (inv.Value.Type == type || type == -1)
3782 { 4095 {
3783 if (inv.Value.Type == type || type == -1) 4096 keys.Add(inv.Value.Name);
3784 {
3785 keys.Add(inv.Value.Name);
3786 }
3787 } 4097 }
3788 } 4098 }
4099 m_host.TaskInventory.LockItemsForRead(false);
3789 4100
3790 if (keys.Count == 0) 4101 if (keys.Count == 0)
3791 { 4102 {
@@ -3822,20 +4133,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3822 } 4133 }
3823 4134
3824 // move the first object found with this inventory name 4135 // move the first object found with this inventory name
3825 lock (m_host.TaskInventory) 4136 m_host.TaskInventory.LockItemsForRead(true);
4137 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3826 { 4138 {
3827 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4139 if (inv.Value.Name == inventory)
3828 { 4140 {
3829 if (inv.Value.Name == inventory) 4141 found = true;
3830 { 4142 objId = inv.Key;
3831 found = true; 4143 assetType = inv.Value.Type;
3832 objId = inv.Key; 4144 objName = inv.Value.Name;
3833 assetType = inv.Value.Type; 4145 break;
3834 objName = inv.Value.Name;
3835 break;
3836 }
3837 } 4146 }
3838 } 4147 }
4148 m_host.TaskInventory.LockItemsForRead(false);
3839 4149
3840 if (!found) 4150 if (!found)
3841 { 4151 {
@@ -3843,9 +4153,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4153 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3844 } 4154 }
3845 4155
3846 // check if destination is an avatar 4156 // check if destination is an object
3847 if (World.GetScenePresence(destId) != null) 4157 if (World.GetSceneObjectPart(destId) != null)
3848 { 4158 {
4159 // destination is an object
4160 World.MoveTaskInventoryItem(destId, m_host, objId);
4161 }
4162 else
4163 {
4164 ScenePresence presence = World.GetScenePresence(destId);
4165
4166 if (presence == null)
4167 {
4168 UserAccount account =
4169 World.UserAccountService.GetUserAccount(
4170 World.RegionInfo.ScopeID,
4171 destId);
4172
4173 if (account == null)
4174 {
4175 llSay(0, "Can't find destination "+destId.ToString());
4176 return;
4177 }
4178 }
4179
3849 // destination is an avatar 4180 // destination is an avatar
3850 InventoryItemBase agentItem = 4181 InventoryItemBase agentItem =
3851 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4182 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3871,33 +4202,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 4202
3872 if (m_TransferModule != null) 4203 if (m_TransferModule != null)
3873 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4204 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4205
4206 //This delay should only occur when giving inventory to avatars.
4207 ScriptSleep(3000);
3874 } 4208 }
3875 else
3876 {
3877 // destination is an object
3878 World.MoveTaskInventoryItem(destId, m_host, objId);
3879 }
3880 ScriptSleep(3000);
3881 } 4209 }
3882 4210
4211 [DebuggerNonUserCode]
3883 public void llRemoveInventory(string name) 4212 public void llRemoveInventory(string name)
3884 { 4213 {
3885 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3886 4215
3887 lock (m_host.TaskInventory) 4216 m_host.TaskInventory.LockItemsForRead(true);
4217 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3888 { 4218 {
3889 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4219 if (item.Name == name)
3890 { 4220 {
3891 if (item.Name == name) 4221 if (item.ItemID == m_itemID)
3892 { 4222 throw new ScriptDeleteException();
3893 if (item.ItemID == m_itemID) 4223 else
3894 throw new ScriptDeleteException(); 4224 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3895 else 4225
3896 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4226 m_host.TaskInventory.LockItemsForRead(false);
3897 return; 4227 return;
3898 }
3899 } 4228 }
3900 } 4229 }
4230 m_host.TaskInventory.LockItemsForRead(false);
3901 } 4231 }
3902 4232
3903 public void llSetText(string text, LSL_Vector color, double alpha) 4233 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3933,22 +4263,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3933 UUID uuid = (UUID)id; 4263 UUID uuid = (UUID)id;
3934 4264
3935 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4265 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4266 if (account == null)
4267 return UUID.Zero.ToString();
4268
3936 4269
3937 PresenceInfo pinfo = null; 4270 PresenceInfo pinfo = null;
3938 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4271 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3939 if (pinfos != null && pinfos.Length > 0) 4272 if (pinfos != null && pinfos.Length > 0)
3940 pinfo = pinfos[0]; 4273 pinfo = pinfos[0];
3941 4274
3942 if (pinfo == null)
3943 return UUID.Zero.ToString();
3944
3945 string reply = String.Empty; 4275 string reply = String.Empty;
3946 4276
3947 switch (data) 4277 switch (data)
3948 { 4278 {
3949 case 1: // DATA_ONLINE (0|1) 4279 case 1: // DATA_ONLINE (0|1)
3950 // TODO: implement fetching of this information 4280 if (pinfo != null && pinfo.RegionID != UUID.Zero)
3951 if (pinfo != null)
3952 reply = "1"; 4281 reply = "1";
3953 else 4282 else
3954 reply = "0"; 4283 reply = "0";
@@ -3988,6 +4317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3988 { 4317 {
3989 m_host.AddScriptLPS(1); 4318 m_host.AddScriptLPS(1);
3990 4319
4320 //Clone is thread safe
3991 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4321 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3992 4322
3993 foreach (TaskInventoryItem item in itemDictionary.Values) 4323 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4041,6 +4371,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4041 ScenePresence presence = World.GetScenePresence(agentId); 4371 ScenePresence presence = World.GetScenePresence(agentId);
4042 if (presence != null) 4372 if (presence != null)
4043 { 4373 {
4374 // agent must not be a god
4375 if (presence.GodLevel >= 200) return;
4376
4044 // agent must be over the owners land 4377 // agent must be over the owners land
4045 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4378 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4046 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4379 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4101,17 +4434,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4101 UUID soundId = UUID.Zero; 4434 UUID soundId = UUID.Zero;
4102 if (!UUID.TryParse(impact_sound, out soundId)) 4435 if (!UUID.TryParse(impact_sound, out soundId))
4103 { 4436 {
4104 lock (m_host.TaskInventory) 4437 m_host.TaskInventory.LockItemsForRead(true);
4438 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4105 { 4439 {
4106 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4440 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4107 { 4441 {
4108 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4442 soundId = item.AssetID;
4109 { 4443 break;
4110 soundId = item.AssetID;
4111 break;
4112 }
4113 } 4444 }
4114 } 4445 }
4446 m_host.TaskInventory.LockItemsForRead(false);
4115 } 4447 }
4116 m_host.CollisionSound = soundId; 4448 m_host.CollisionSound = soundId;
4117 m_host.CollisionSoundVolume = (float)impact_volume; 4449 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4157,6 +4489,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4157 UUID partItemID; 4489 UUID partItemID;
4158 foreach (SceneObjectPart part in parts) 4490 foreach (SceneObjectPart part in parts)
4159 { 4491 {
4492 //Clone is thread safe
4160 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4493 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4161 4494
4162 foreach (TaskInventoryItem item in itemsDictionary.Values) 4495 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4371,17 +4704,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4371 4704
4372 m_host.AddScriptLPS(1); 4705 m_host.AddScriptLPS(1);
4373 4706
4374 lock (m_host.TaskInventory) 4707 m_host.TaskInventory.LockItemsForRead(true);
4708 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4375 { 4709 {
4376 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4710 if (item.Type == 10 && item.ItemID == m_itemID)
4377 { 4711 {
4378 if (item.Type == 10 && item.ItemID == m_itemID) 4712 result = item.Name!=null?item.Name:String.Empty;
4379 { 4713 break;
4380 result = item.Name != null ? item.Name : String.Empty;
4381 break;
4382 }
4383 } 4714 }
4384 } 4715 }
4716 m_host.TaskInventory.LockItemsForRead(false);
4385 4717
4386 return result; 4718 return result;
4387 } 4719 }
@@ -4534,23 +4866,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4534 { 4866 {
4535 m_host.AddScriptLPS(1); 4867 m_host.AddScriptLPS(1);
4536 4868
4537 lock (m_host.TaskInventory) 4869 m_host.TaskInventory.LockItemsForRead(true);
4870 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4538 { 4871 {
4539 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4872 if (inv.Value.Name == name)
4540 { 4873 {
4541 if (inv.Value.Name == name) 4874 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4542 { 4875 {
4543 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4876 m_host.TaskInventory.LockItemsForRead(false);
4544 { 4877 return inv.Value.AssetID.ToString();
4545 return inv.Value.AssetID.ToString(); 4878 }
4546 } 4879 else
4547 else 4880 {
4548 { 4881 m_host.TaskInventory.LockItemsForRead(false);
4549 return UUID.Zero.ToString(); 4882 return UUID.Zero.ToString();
4550 }
4551 } 4883 }
4552 } 4884 }
4553 } 4885 }
4886 m_host.TaskInventory.LockItemsForRead(false);
4554 4887
4555 return UUID.Zero.ToString(); 4888 return UUID.Zero.ToString();
4556 } 4889 }
@@ -5486,10 +5819,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5486 m_host.AddScriptLPS(1); 5819 m_host.AddScriptLPS(1);
5487 5820
5488 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5821 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5489 5822 if (parts.Count > 0)
5490 foreach (var part in parts)
5491 { 5823 {
5492 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5824 try
5825 {
5826 parts[0].ParentGroup.areUpdatesSuspended = true;
5827 foreach (var part in parts)
5828 {
5829 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5830 }
5831 }
5832 finally
5833 {
5834 parts[0].ParentGroup.areUpdatesSuspended = false;
5835 }
5493 } 5836 }
5494 } 5837 }
5495 5838
@@ -5545,74 +5888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5545 5888
5546 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5889 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5547 { 5890 {
5548 m_host.AddScriptLPS(1); 5891 return ParseString2List(str, separators, in_spacers, false);
5549 LSL_List ret = new LSL_List();
5550 LSL_List spacers = new LSL_List();
5551 if (in_spacers.Length > 0 && separators.Length > 0)
5552 {
5553 for (int i = 0; i < in_spacers.Length; i++)
5554 {
5555 object s = in_spacers.Data[i];
5556 for (int j = 0; j < separators.Length; j++)
5557 {
5558 if (separators.Data[j].ToString() == s.ToString())
5559 {
5560 s = null;
5561 break;
5562 }
5563 }
5564 if (s != null)
5565 {
5566 spacers.Add(s);
5567 }
5568 }
5569 }
5570 object[] delimiters = new object[separators.Length + spacers.Length];
5571 separators.Data.CopyTo(delimiters, 0);
5572 spacers.Data.CopyTo(delimiters, separators.Length);
5573 bool dfound = false;
5574 do
5575 {
5576 dfound = false;
5577 int cindex = -1;
5578 string cdeli = "";
5579 for (int i = 0; i < delimiters.Length; i++)
5580 {
5581 int index = str.IndexOf(delimiters[i].ToString());
5582 bool found = index != -1;
5583 if (found && String.Empty != delimiters[i].ToString())
5584 {
5585 if ((cindex > index) || (cindex == -1))
5586 {
5587 cindex = index;
5588 cdeli = delimiters[i].ToString();
5589 }
5590 dfound = dfound || found;
5591 }
5592 }
5593 if (cindex != -1)
5594 {
5595 if (cindex > 0)
5596 {
5597 ret.Add(new LSL_String(str.Substring(0, cindex)));
5598 }
5599 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5600 for (int j = 0; j < spacers.Length; j++)
5601 {
5602 if (spacers.Data[j].ToString() == cdeli)
5603 {
5604 ret.Add(new LSL_String(cdeli));
5605 break;
5606 }
5607 }
5608 str = str.Substring(cindex + cdeli.Length);
5609 }
5610 } while (dfound);
5611 if (str != "")
5612 {
5613 ret.Add(new LSL_String(str));
5614 }
5615 return ret;
5616 } 5892 }
5617 5893
5618 public LSL_Integer llOverMyLand(string id) 5894 public LSL_Integer llOverMyLand(string id)
@@ -6068,6 +6344,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6068 tempf = (float)rules.GetLSLFloatItem(i + 1); 6344 tempf = (float)rules.GetLSLFloatItem(i + 1);
6069 prules.OuterAngle = (float)tempf; 6345 prules.OuterAngle = (float)tempf;
6070 break; 6346 break;
6347
6348 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6349 tempf = (float)rules.GetLSLFloatItem(i + 1);
6350 prules.InnerAngle = (float)tempf;
6351 break;
6352
6353 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6354 tempf = (float)rules.GetLSLFloatItem(i + 1);
6355 prules.OuterAngle = (float)tempf;
6356 break;
6071 } 6357 }
6072 6358
6073 } 6359 }
@@ -6106,14 +6392,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6106 6392
6107 protected UUID GetTaskInventoryItem(string name) 6393 protected UUID GetTaskInventoryItem(string name)
6108 { 6394 {
6109 lock (m_host.TaskInventory) 6395 m_host.TaskInventory.LockItemsForRead(true);
6396 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6110 { 6397 {
6111 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6398 if (inv.Value.Name == name)
6112 { 6399 {
6113 if (inv.Value.Name == name) 6400 m_host.TaskInventory.LockItemsForRead(false);
6114 return inv.Key; 6401 return inv.Key;
6115 } 6402 }
6116 } 6403 }
6404 m_host.TaskInventory.LockItemsForRead(false);
6117 6405
6118 return UUID.Zero; 6406 return UUID.Zero;
6119 } 6407 }
@@ -6441,22 +6729,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6441 } 6729 }
6442 6730
6443 // copy the first script found with this inventory name 6731 // copy the first script found with this inventory name
6444 lock (m_host.TaskInventory) 6732 m_host.TaskInventory.LockItemsForRead(true);
6733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6445 { 6734 {
6446 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6735 if (inv.Value.Name == name)
6447 { 6736 {
6448 if (inv.Value.Name == name) 6737 // make sure the object is a script
6738 if (10 == inv.Value.Type)
6449 { 6739 {
6450 // make sure the object is a script 6740 found = true;
6451 if (10 == inv.Value.Type) 6741 srcId = inv.Key;
6452 { 6742 break;
6453 found = true;
6454 srcId = inv.Key;
6455 break;
6456 }
6457 } 6743 }
6458 } 6744 }
6459 } 6745 }
6746 m_host.TaskInventory.LockItemsForRead(false);
6460 6747
6461 if (!found) 6748 if (!found)
6462 { 6749 {
@@ -6540,6 +6827,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6540 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6827 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6541 { 6828 {
6542 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6829 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6830 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6831 return shapeBlock;
6543 6832
6544 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6833 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6545 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6834 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6615,6 +6904,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6615 6904
6616 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6905 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6617 { 6906 {
6907 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6908 return;
6909
6618 ObjectShapePacket.ObjectDataBlock shapeBlock; 6910 ObjectShapePacket.ObjectDataBlock shapeBlock;
6619 6911
6620 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6912 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6664,6 +6956,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6664 6956
6665 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6957 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6666 { 6958 {
6959 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6960 return;
6961
6667 ObjectShapePacket.ObjectDataBlock shapeBlock; 6962 ObjectShapePacket.ObjectDataBlock shapeBlock;
6668 6963
6669 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6964 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6706,6 +7001,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6706 7001
6707 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) 7002 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)
6708 { 7003 {
7004 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7005 return;
7006
6709 ObjectShapePacket.ObjectDataBlock shapeBlock; 7007 ObjectShapePacket.ObjectDataBlock shapeBlock;
6710 7008
6711 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7009 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6832,6 +7130,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6832 7130
6833 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7131 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6834 { 7132 {
7133 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7134 return;
7135
6835 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7136 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6836 UUID sculptId; 7137 UUID sculptId;
6837 7138
@@ -6847,13 +7148,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 shapeBlock.PathScaleX = 100; 7148 shapeBlock.PathScaleX = 100;
6848 shapeBlock.PathScaleY = 150; 7149 shapeBlock.PathScaleY = 150;
6849 7150
6850 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7151 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6851 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7152 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6852 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7153 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6853 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7154 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6854 { 7155 {
6855 // default 7156 // default
6856 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7157 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6857 } 7158 }
6858 7159
6859 // retain pathcurve 7160 // retain pathcurve
@@ -6872,12 +7173,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6872 7173
6873 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7174 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6874 { 7175 {
6875 m_host.AddScriptLPS(1); 7176 m_host.AddScriptLPS(1);
6876 7177
6877 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7178 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6878 7179 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
6879 foreach (SceneObjectPart part in parts) 7180 if (parts.Count>0)
6880 SetPrimParams(part, rules); 7181 {
7182 try
7183 {
7184 parts[0].ParentGroup.areUpdatesSuspended = true;
7185 foreach (SceneObjectPart part in parts)
7186 SetPrimParams(part, rules);
7187 }
7188 finally
7189 {
7190 parts[0].ParentGroup.areUpdatesSuspended = false;
7191 }
7192 }
7193 if (avatars.Count > 0)
7194 {
7195 foreach (ScenePresence avatar in avatars)
7196 SetPrimParams(avatar, rules);
7197 }
6881 } 7198 }
6882 7199
6883 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7200 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
@@ -6885,8 +7202,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6885 llSetLinkPrimitiveParams(linknumber, rules); 7202 llSetLinkPrimitiveParams(linknumber, rules);
6886 } 7203 }
6887 7204
7205 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7206 {
7207 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7208 //We only support PRIM_POSITION and PRIM_ROTATION
7209
7210 int idx = 0;
7211
7212 while (idx < rules.Length)
7213 {
7214 int code = rules.GetLSLIntegerItem(idx++);
7215
7216 int remain = rules.Length - idx;
7217
7218
7219
7220 switch (code)
7221 {
7222 case (int)ScriptBaseClass.PRIM_POSITION:
7223 if (remain < 1)
7224 return;
7225 LSL_Vector v;
7226 v = rules.GetVector3Item(idx++);
7227 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7228 av.SendFullUpdateToAllClients();
7229
7230 break;
7231
7232 case (int)ScriptBaseClass.PRIM_ROTATION:
7233 if (remain < 1)
7234 return;
7235 LSL_Rotation r;
7236 r = rules.GetQuaternionItem(idx++);
7237 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7238 av.SendFullUpdateToAllClients();
7239 break;
7240 }
7241 }
7242
7243 }
7244
6888 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7245 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6889 { 7246 {
7247 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7248 return;
7249
6890 int idx = 0; 7250 int idx = 0;
6891 7251
6892 while (idx < rules.Length) 7252 while (idx < rules.Length)
@@ -7718,24 +8078,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7718 break; 8078 break;
7719 8079
7720 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8080 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7721 // TODO--------------
7722 if (remain < 1) 8081 if (remain < 1)
7723 return res; 8082 return res;
8083 face = (int)rules.GetLSLIntegerItem(idx++);
7724 8084
7725 face=(int)rules.GetLSLIntegerItem(idx++); 8085 tex = part.Shape.Textures;
7726 8086 int shiny;
7727 res.Add(new LSL_Integer(0)); 8087 if (face == ScriptBaseClass.ALL_SIDES)
7728 res.Add(new LSL_Integer(0)); 8088 {
8089 for (face = 0; face < GetNumberOfSides(part); face++)
8090 {
8091 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8092 if (shinyness == Shininess.High)
8093 {
8094 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8095 }
8096 else if (shinyness == Shininess.Medium)
8097 {
8098 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8099 }
8100 else if (shinyness == Shininess.Low)
8101 {
8102 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8103 }
8104 else
8105 {
8106 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8107 }
8108 res.Add(new LSL_Integer(shiny));
8109 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8110 }
8111 }
8112 else
8113 {
8114 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8115 if (shinyness == Shininess.High)
8116 {
8117 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8118 }
8119 else if (shinyness == Shininess.Medium)
8120 {
8121 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8122 }
8123 else if (shinyness == Shininess.Low)
8124 {
8125 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8126 }
8127 else
8128 {
8129 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8130 }
8131 res.Add(new LSL_Integer(shiny));
8132 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8133 }
7729 break; 8134 break;
7730 8135
7731 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8136 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7732 // TODO--------------
7733 if (remain < 1) 8137 if (remain < 1)
7734 return res; 8138 return res;
8139 face = (int)rules.GetLSLIntegerItem(idx++);
7735 8140
7736 face=(int)rules.GetLSLIntegerItem(idx++); 8141 tex = part.Shape.Textures;
7737 8142 int fullbright;
7738 res.Add(new LSL_Integer(0)); 8143 if (face == ScriptBaseClass.ALL_SIDES)
8144 {
8145 for (face = 0; face < GetNumberOfSides(part); face++)
8146 {
8147 if (tex.GetFace((uint)face).Fullbright == true)
8148 {
8149 fullbright = ScriptBaseClass.TRUE;
8150 }
8151 else
8152 {
8153 fullbright = ScriptBaseClass.FALSE;
8154 }
8155 res.Add(new LSL_Integer(fullbright));
8156 }
8157 }
8158 else
8159 {
8160 if (tex.GetFace((uint)face).Fullbright == true)
8161 {
8162 fullbright = ScriptBaseClass.TRUE;
8163 }
8164 else
8165 {
8166 fullbright = ScriptBaseClass.FALSE;
8167 }
8168 res.Add(new LSL_Integer(fullbright));
8169 }
7739 break; 8170 break;
7740 8171
7741 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8172 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7756,14 +8187,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7756 break; 8187 break;
7757 8188
7758 case (int)ScriptBaseClass.PRIM_TEXGEN: 8189 case (int)ScriptBaseClass.PRIM_TEXGEN:
7759 // TODO--------------
7760 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8190 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7761 if (remain < 1) 8191 if (remain < 1)
7762 return res; 8192 return res;
8193 face = (int)rules.GetLSLIntegerItem(idx++);
7763 8194
7764 face=(int)rules.GetLSLIntegerItem(idx++); 8195 tex = part.Shape.Textures;
7765 8196 if (face == ScriptBaseClass.ALL_SIDES)
7766 res.Add(new LSL_Integer(0)); 8197 {
8198 for (face = 0; face < GetNumberOfSides(part); face++)
8199 {
8200 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8201 {
8202 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8203 }
8204 else
8205 {
8206 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8207 }
8208 }
8209 }
8210 else
8211 {
8212 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8213 {
8214 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8215 }
8216 else
8217 {
8218 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8219 }
8220 }
7767 break; 8221 break;
7768 8222
7769 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8223 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7782,13 +8236,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7782 break; 8236 break;
7783 8237
7784 case (int)ScriptBaseClass.PRIM_GLOW: 8238 case (int)ScriptBaseClass.PRIM_GLOW:
7785 // TODO--------------
7786 if (remain < 1) 8239 if (remain < 1)
7787 return res; 8240 return res;
8241 face = (int)rules.GetLSLIntegerItem(idx++);
7788 8242
7789 face=(int)rules.GetLSLIntegerItem(idx++); 8243 tex = part.Shape.Textures;
7790 8244 float primglow;
7791 res.Add(new LSL_Float(0)); 8245 if (face == ScriptBaseClass.ALL_SIDES)
8246 {
8247 for (face = 0; face < GetNumberOfSides(part); face++)
8248 {
8249 primglow = tex.GetFace((uint)face).Glow;
8250 res.Add(new LSL_Float(primglow));
8251 }
8252 }
8253 else
8254 {
8255 primglow = tex.GetFace((uint)face).Glow;
8256 res.Add(new LSL_Float(primglow));
8257 }
7792 break; 8258 break;
7793 case (int)ScriptBaseClass.PRIM_TEXT: 8259 case (int)ScriptBaseClass.PRIM_TEXT:
7794 Color4 textColor = part.GetTextColor(); 8260 Color4 textColor = part.GetTextColor();
@@ -8094,8 +8560,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8094 // The function returns an ordered list 8560 // The function returns an ordered list
8095 // representing the tokens found in the supplied 8561 // representing the tokens found in the supplied
8096 // sources string. If two successive tokenizers 8562 // sources string. If two successive tokenizers
8097 // are encountered, then a NULL entry is added 8563 // are encountered, then a null-string entry is
8098 // to the list. 8564 // added to the list.
8099 // 8565 //
8100 // It is a precondition that the source and 8566 // It is a precondition that the source and
8101 // toekizer lisst are non-null. If they are null, 8567 // toekizer lisst are non-null. If they are null,
@@ -8103,7 +8569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8103 // while their lengths are being determined. 8569 // while their lengths are being determined.
8104 // 8570 //
8105 // A small amount of working memoryis required 8571 // A small amount of working memoryis required
8106 // of approximately 8*#tokenizers. 8572 // of approximately 8*#tokenizers + 8*srcstrlen.
8107 // 8573 //
8108 // There are many ways in which this function 8574 // There are many ways in which this function
8109 // can be implemented, this implementation is 8575 // can be implemented, this implementation is
@@ -8119,136 +8585,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8119 // and eliminates redundant tokenizers as soon 8585 // and eliminates redundant tokenizers as soon
8120 // as is possible. 8586 // as is possible.
8121 // 8587 //
8122 // The implementation tries to avoid any copying 8588 // The implementation tries to minimize temporary
8123 // of arrays or other objects. 8589 // garbage generation.
8124 // </remarks> 8590 // </remarks>
8125 8591
8126 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8592 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8127 { 8593 {
8128 int beginning = 0; 8594 return ParseString2List(src, separators, spacers, true);
8129 int srclen = src.Length; 8595 }
8130 int seplen = separators.Length;
8131 object[] separray = separators.Data;
8132 int spclen = spacers.Length;
8133 object[] spcarray = spacers.Data;
8134 int mlen = seplen+spclen;
8135
8136 int[] offset = new int[mlen+1];
8137 bool[] active = new bool[mlen];
8138 8596
8139 int best; 8597 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8140 int j; 8598 {
8599 int srclen = src.Length;
8600 int seplen = separators.Length;
8601 object[] separray = separators.Data;
8602 int spclen = spacers.Length;
8603 object[] spcarray = spacers.Data;
8604 int dellen = 0;
8605 string[] delarray = new string[seplen+spclen];
8141 8606
8142 // Initial capacity reduces resize cost 8607 int outlen = 0;
8608 string[] outarray = new string[srclen*2+1];
8143 8609
8144 LSL_List tokens = new LSL_List(); 8610 int i, j;
8611 string d;
8145 8612
8146 m_host.AddScriptLPS(1); 8613 m_host.AddScriptLPS(1);
8147 8614
8148 // All entries are initially valid 8615 /*
8149 8616 * Convert separator and spacer lists to C# strings.
8150 for (int i = 0; i < mlen; i++) 8617 * Also filter out null strings so we don't hang.
8151 active[i] = true; 8618 */
8152 8619 for (i = 0; i < seplen; i ++) {
8153 offset[mlen] = srclen; 8620 d = separray[i].ToString();
8154 8621 if (d.Length > 0) {
8155 while (beginning < srclen) 8622 delarray[dellen++] = d;
8156 { 8623 }
8157 8624 }
8158 best = mlen; // as bad as it gets 8625 seplen = dellen;
8159
8160 // Scan for separators
8161 8626
8162 for (j = 0; j < seplen; j++) 8627 for (i = 0; i < spclen; i ++) {
8163 { 8628 d = spcarray[i].ToString();
8164 if (active[j]) 8629 if (d.Length > 0) {
8165 { 8630 delarray[dellen++] = d;
8166 // scan all of the markers
8167 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8168 {
8169 // not present at all
8170 active[j] = false;
8171 }
8172 else
8173 {
8174 // present and correct
8175 if (offset[j] < offset[best])
8176 {
8177 // closest so far
8178 best = j;
8179 if (offset[best] == beginning)
8180 break;
8181 }
8182 }
8183 }
8184 } 8631 }
8632 }
8185 8633
8186 // Scan for spacers 8634 /*
8635 * Scan through source string from beginning to end.
8636 */
8637 for (i = 0;;) {
8187 8638
8188 if (offset[best] != beginning) 8639 /*
8189 { 8640 * Find earliest delimeter in src starting at i (if any).
8190 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8641 */
8191 { 8642 int earliestDel = -1;
8192 if (active[j]) 8643 int earliestSrc = srclen;
8193 { 8644 string earliestStr = null;
8194 // scan all of the markers 8645 for (j = 0; j < dellen; j ++) {
8195 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8646 d = delarray[j];
8196 { 8647 if (d != null) {
8197 // not present at all 8648 int index = src.IndexOf(d, i);
8198 active[j] = false; 8649 if (index < 0) {
8199 } 8650 delarray[j] = null; // delim nowhere in src, don't check it anymore
8200 else 8651 } else if (index < earliestSrc) {
8201 { 8652 earliestSrc = index; // where delimeter starts in source string
8202 // present and correct 8653 earliestDel = j; // where delimeter is in delarray[]
8203 if (offset[j] < offset[best]) 8654 earliestStr = d; // the delimeter string from delarray[]
8204 { 8655 if (index == i) break; // can't do any better than found at beg of string
8205 // closest so far
8206 best = j;
8207 }
8208 }
8209 } 8656 }
8210 } 8657 }
8211 } 8658 }
8212 8659
8213 // This is the normal exit from the scanning loop 8660 /*
8214 8661 * Output source string starting at i through start of earliest delimeter.
8215 if (best == mlen) 8662 */
8216 { 8663 if (keepNulls || (earliestSrc > i)) {
8217 // no markers were found on this pass 8664 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8218 // so we're pretty much done
8219 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8220 break;
8221 } 8665 }
8222 8666
8223 // Otherwise we just add the newly delimited token 8667 /*
8224 // and recalculate where the search should continue. 8668 * If no delimeter found at or after i, we're done scanning.
8669 */
8670 if (earliestDel < 0) break;
8225 8671
8226 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8672 /*
8227 8673 * If delimeter was a spacer, output the spacer.
8228 if (best < seplen) 8674 */
8229 { 8675 if (earliestDel >= seplen) {
8230 beginning = offset[best] + (separray[best].ToString()).Length; 8676 outarray[outlen++] = earliestStr;
8231 } 8677 }
8232 else
8233 {
8234 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8235 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8236 }
8237 }
8238 8678
8239 // This an awkward an not very intuitive boundary case. If the 8679 /*
8240 // last substring is a tokenizer, then there is an implied trailing 8680 * Look at rest of src string following delimeter.
8241 // null list entry. Hopefully the single comparison will not be too 8681 */
8242 // arduous. Alternatively the 'break' could be replced with a return 8682 i = earliestSrc + earliestStr.Length;
8243 // but that's shabby programming.
8244
8245 if (beginning == srclen)
8246 {
8247 if (srclen != 0)
8248 tokens.Add(new LSL_String(""));
8249 } 8683 }
8250 8684
8251 return tokens; 8685 /*
8686 * Make up an exact-sized output array suitable for an LSL_List object.
8687 */
8688 object[] outlist = new object[outlen];
8689 for (i = 0; i < outlen; i ++) {
8690 outlist[i] = new LSL_String(outarray[i]);
8691 }
8692 return new LSL_List(outlist);
8252 } 8693 }
8253 8694
8254 public LSL_Integer llGetObjectPermMask(int mask) 8695 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8325,28 +8766,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8325 { 8766 {
8326 m_host.AddScriptLPS(1); 8767 m_host.AddScriptLPS(1);
8327 8768
8328 lock (m_host.TaskInventory) 8769 m_host.TaskInventory.LockItemsForRead(true);
8770 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8329 { 8771 {
8330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8772 if (inv.Value.Name == item)
8331 { 8773 {
8332 if (inv.Value.Name == item) 8774 m_host.TaskInventory.LockItemsForRead(false);
8775 switch (mask)
8333 { 8776 {
8334 switch (mask) 8777 case 0:
8335 { 8778 return (int)inv.Value.BasePermissions;
8336 case 0: 8779 case 1:
8337 return (int)inv.Value.BasePermissions; 8780 return (int)inv.Value.CurrentPermissions;
8338 case 1: 8781 case 2:
8339 return (int)inv.Value.CurrentPermissions; 8782 return (int)inv.Value.GroupPermissions;
8340 case 2: 8783 case 3:
8341 return (int)inv.Value.GroupPermissions; 8784 return (int)inv.Value.EveryonePermissions;
8342 case 3: 8785 case 4:
8343 return (int)inv.Value.EveryonePermissions; 8786 return (int)inv.Value.NextPermissions;
8344 case 4:
8345 return (int)inv.Value.NextPermissions;
8346 }
8347 } 8787 }
8348 } 8788 }
8349 } 8789 }
8790 m_host.TaskInventory.LockItemsForRead(false);
8350 8791
8351 return -1; 8792 return -1;
8352 } 8793 }
@@ -8393,16 +8834,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8393 { 8834 {
8394 m_host.AddScriptLPS(1); 8835 m_host.AddScriptLPS(1);
8395 8836
8396 lock (m_host.TaskInventory) 8837 m_host.TaskInventory.LockItemsForRead(true);
8838 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8397 { 8839 {
8398 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8840 if (inv.Value.Name == item)
8399 { 8841 {
8400 if (inv.Value.Name == item) 8842 m_host.TaskInventory.LockItemsForRead(false);
8401 { 8843 return inv.Value.CreatorID.ToString();
8402 return inv.Value.CreatorID.ToString();
8403 }
8404 } 8844 }
8405 } 8845 }
8846 m_host.TaskInventory.LockItemsForRead(false);
8406 8847
8407 llSay(0, "No item name '" + item + "'"); 8848 llSay(0, "No item name '" + item + "'");
8408 8849
@@ -8662,17 +9103,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8662 int width = 0; 9103 int width = 0;
8663 int height = 0; 9104 int height = 0;
8664 9105
8665 ParcelMediaCommandEnum? commandToSend = null; 9106 uint commandToSend = 0;
8666 float time = 0.0f; // default is from start 9107 float time = 0.0f; // default is from start
8667 9108
8668 ScenePresence presence = null; 9109 ScenePresence presence = null;
8669 9110
8670 for (int i = 0; i < commandList.Data.Length; i++) 9111 for (int i = 0; i < commandList.Data.Length; i++)
8671 { 9112 {
8672 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9113 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8673 switch (command) 9114 switch (command)
8674 { 9115 {
8675 case ParcelMediaCommandEnum.Agent: 9116 case (uint)ParcelMediaCommandEnum.Agent:
8676 // we send only to one agent 9117 // we send only to one agent
8677 if ((i + 1) < commandList.Length) 9118 if ((i + 1) < commandList.Length)
8678 { 9119 {
@@ -8689,25 +9130,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8689 } 9130 }
8690 break; 9131 break;
8691 9132
8692 case ParcelMediaCommandEnum.Loop: 9133 case (uint)ParcelMediaCommandEnum.Loop:
8693 loop = 1; 9134 loop = 1;
8694 commandToSend = command; 9135 commandToSend = command;
8695 update = true; //need to send the media update packet to set looping 9136 update = true; //need to send the media update packet to set looping
8696 break; 9137 break;
8697 9138
8698 case ParcelMediaCommandEnum.Play: 9139 case (uint)ParcelMediaCommandEnum.Play:
8699 loop = 0; 9140 loop = 0;
8700 commandToSend = command; 9141 commandToSend = command;
8701 update = true; //need to send the media update packet to make sure it doesn't loop 9142 update = true; //need to send the media update packet to make sure it doesn't loop
8702 break; 9143 break;
8703 9144
8704 case ParcelMediaCommandEnum.Pause: 9145 case (uint)ParcelMediaCommandEnum.Pause:
8705 case ParcelMediaCommandEnum.Stop: 9146 case (uint)ParcelMediaCommandEnum.Stop:
8706 case ParcelMediaCommandEnum.Unload: 9147 case (uint)ParcelMediaCommandEnum.Unload:
8707 commandToSend = command; 9148 commandToSend = command;
8708 break; 9149 break;
8709 9150
8710 case ParcelMediaCommandEnum.Url: 9151 case (uint)ParcelMediaCommandEnum.Url:
8711 if ((i + 1) < commandList.Length) 9152 if ((i + 1) < commandList.Length)
8712 { 9153 {
8713 if (commandList.Data[i + 1] is LSL_String) 9154 if (commandList.Data[i + 1] is LSL_String)
@@ -8720,7 +9161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8720 } 9161 }
8721 break; 9162 break;
8722 9163
8723 case ParcelMediaCommandEnum.Texture: 9164 case (uint)ParcelMediaCommandEnum.Texture:
8724 if ((i + 1) < commandList.Length) 9165 if ((i + 1) < commandList.Length)
8725 { 9166 {
8726 if (commandList.Data[i + 1] is LSL_String) 9167 if (commandList.Data[i + 1] is LSL_String)
@@ -8733,7 +9174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8733 } 9174 }
8734 break; 9175 break;
8735 9176
8736 case ParcelMediaCommandEnum.Time: 9177 case (uint)ParcelMediaCommandEnum.Time:
8737 if ((i + 1) < commandList.Length) 9178 if ((i + 1) < commandList.Length)
8738 { 9179 {
8739 if (commandList.Data[i + 1] is LSL_Float) 9180 if (commandList.Data[i + 1] is LSL_Float)
@@ -8745,7 +9186,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8745 } 9186 }
8746 break; 9187 break;
8747 9188
8748 case ParcelMediaCommandEnum.AutoAlign: 9189 case (uint)ParcelMediaCommandEnum.AutoAlign:
8749 if ((i + 1) < commandList.Length) 9190 if ((i + 1) < commandList.Length)
8750 { 9191 {
8751 if (commandList.Data[i + 1] is LSL_Integer) 9192 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8759,7 +9200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8759 } 9200 }
8760 break; 9201 break;
8761 9202
8762 case ParcelMediaCommandEnum.Type: 9203 case (uint)ParcelMediaCommandEnum.Type:
8763 if ((i + 1) < commandList.Length) 9204 if ((i + 1) < commandList.Length)
8764 { 9205 {
8765 if (commandList.Data[i + 1] is LSL_String) 9206 if (commandList.Data[i + 1] is LSL_String)
@@ -8772,7 +9213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8772 } 9213 }
8773 break; 9214 break;
8774 9215
8775 case ParcelMediaCommandEnum.Desc: 9216 case (uint)ParcelMediaCommandEnum.Desc:
8776 if ((i + 1) < commandList.Length) 9217 if ((i + 1) < commandList.Length)
8777 { 9218 {
8778 if (commandList.Data[i + 1] is LSL_String) 9219 if (commandList.Data[i + 1] is LSL_String)
@@ -8785,7 +9226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8785 } 9226 }
8786 break; 9227 break;
8787 9228
8788 case ParcelMediaCommandEnum.Size: 9229 case (uint)ParcelMediaCommandEnum.Size:
8789 if ((i + 2) < commandList.Length) 9230 if ((i + 2) < commandList.Length)
8790 { 9231 {
8791 if (commandList.Data[i + 1] is LSL_Integer) 9232 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8855,7 +9296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8855 } 9296 }
8856 } 9297 }
8857 9298
8858 if (commandToSend != null) 9299 if (commandToSend != 0)
8859 { 9300 {
8860 // the commandList contained a start/stop/... command, too 9301 // the commandList contained a start/stop/... command, too
8861 if (presence == null) 9302 if (presence == null)
@@ -8892,7 +9333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8892 9333
8893 if (aList.Data[i] != null) 9334 if (aList.Data[i] != null)
8894 { 9335 {
8895 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9336 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
8896 { 9337 {
8897 case ParcelMediaCommandEnum.Url: 9338 case ParcelMediaCommandEnum.Url:
8898 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9339 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -8935,16 +9376,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8935 { 9376 {
8936 m_host.AddScriptLPS(1); 9377 m_host.AddScriptLPS(1);
8937 9378
8938 lock (m_host.TaskInventory) 9379 m_host.TaskInventory.LockItemsForRead(true);
9380 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8939 { 9381 {
8940 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9382 if (inv.Value.Name == name)
8941 { 9383 {
8942 if (inv.Value.Name == name) 9384 m_host.TaskInventory.LockItemsForRead(false);
8943 { 9385 return inv.Value.Type;
8944 return inv.Value.Type;
8945 }
8946 } 9386 }
8947 } 9387 }
9388 m_host.TaskInventory.LockItemsForRead(false);
8948 9389
8949 return -1; 9390 return -1;
8950 } 9391 }
@@ -8955,15 +9396,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8955 9396
8956 if (quick_pay_buttons.Data.Length < 4) 9397 if (quick_pay_buttons.Data.Length < 4)
8957 { 9398 {
8958 LSLError("List must have at least 4 elements"); 9399 int x;
8959 return; 9400 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9401 {
9402 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9403 }
8960 } 9404 }
8961 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9405 int[] nPrice = new int[5];
8962 9406 nPrice[0]=price;
8963 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9407 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8964 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9408 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8965 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9409 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8966 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9410 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9411 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8967 m_host.ParentGroup.HasGroupChanged = true; 9412 m_host.ParentGroup.HasGroupChanged = true;
8968 } 9413 }
8969 9414
@@ -8975,17 +9420,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8975 if (invItemID == UUID.Zero) 9420 if (invItemID == UUID.Zero)
8976 return new LSL_Vector(); 9421 return new LSL_Vector();
8977 9422
8978 lock (m_host.TaskInventory) 9423 m_host.TaskInventory.LockItemsForRead(true);
9424 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8979 { 9425 {
8980 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9426 m_host.TaskInventory.LockItemsForRead(false);
8981 return new LSL_Vector(); 9427 return new LSL_Vector();
9428 }
8982 9429
8983 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9430 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8984 { 9431 {
8985 ShoutError("No permissions to track the camera"); 9432 ShoutError("No permissions to track the camera");
8986 return new LSL_Vector(); 9433 m_host.TaskInventory.LockItemsForRead(false);
8987 } 9434 return new LSL_Vector();
8988 } 9435 }
9436 m_host.TaskInventory.LockItemsForRead(false);
8989 9437
8990 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9438 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8991 if (presence != null) 9439 if (presence != null)
@@ -9003,17 +9451,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9003 if (invItemID == UUID.Zero) 9451 if (invItemID == UUID.Zero)
9004 return new LSL_Rotation(); 9452 return new LSL_Rotation();
9005 9453
9006 lock (m_host.TaskInventory) 9454 m_host.TaskInventory.LockItemsForRead(true);
9455 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9007 { 9456 {
9008 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9457 m_host.TaskInventory.LockItemsForRead(false);
9009 return new LSL_Rotation(); 9458 return new LSL_Rotation();
9010 9459 }
9011 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9460 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9012 { 9461 {
9013 ShoutError("No permissions to track the camera"); 9462 ShoutError("No permissions to track the camera");
9014 return new LSL_Rotation(); 9463 m_host.TaskInventory.LockItemsForRead(false);
9015 } 9464 return new LSL_Rotation();
9016 } 9465 }
9466 m_host.TaskInventory.LockItemsForRead(false);
9017 9467
9018 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9468 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9019 if (presence != null) 9469 if (presence != null)
@@ -9075,8 +9525,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9075 { 9525 {
9076 m_host.AddScriptLPS(1); 9526 m_host.AddScriptLPS(1);
9077 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9527 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9078 if (detectedParams == null) return; // only works on the first detected avatar 9528 if (detectedParams == null)
9079 9529 {
9530 if (m_host.IsAttachment == true)
9531 {
9532 detectedParams = new DetectParams();
9533 detectedParams.Key = m_host.OwnerID;
9534 }
9535 else
9536 {
9537 return;
9538 }
9539 }
9540
9080 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9541 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9081 if (avatar != null) 9542 if (avatar != null)
9082 { 9543 {
@@ -9084,6 +9545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9084 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9545 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9085 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9546 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9086 } 9547 }
9548
9087 ScriptSleep(1000); 9549 ScriptSleep(1000);
9088 } 9550 }
9089 9551
@@ -9163,14 +9625,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9163 if (objectID == UUID.Zero) return; 9625 if (objectID == UUID.Zero) return;
9164 9626
9165 UUID agentID; 9627 UUID agentID;
9166 lock (m_host.TaskInventory) 9628 m_host.TaskInventory.LockItemsForRead(true);
9167 { 9629 // we need the permission first, to know which avatar we want to set the camera for
9168 // we need the permission first, to know which avatar we want to set the camera for 9630 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9169 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9170 9631
9171 if (agentID == UUID.Zero) return; 9632 if (agentID == UUID.Zero)
9172 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9633 {
9634 m_host.TaskInventory.LockItemsForRead(false);
9635 return;
9636 }
9637 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9638 {
9639 m_host.TaskInventory.LockItemsForRead(false);
9640 return;
9173 } 9641 }
9642 m_host.TaskInventory.LockItemsForRead(false);
9174 9643
9175 ScenePresence presence = World.GetScenePresence(agentID); 9644 ScenePresence presence = World.GetScenePresence(agentID);
9176 9645
@@ -9220,12 +9689,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9220 9689
9221 // we need the permission first, to know which avatar we want to clear the camera for 9690 // we need the permission first, to know which avatar we want to clear the camera for
9222 UUID agentID; 9691 UUID agentID;
9223 lock (m_host.TaskInventory) 9692 m_host.TaskInventory.LockItemsForRead(true);
9693 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9694 if (agentID == UUID.Zero)
9695 {
9696 m_host.TaskInventory.LockItemsForRead(false);
9697 return;
9698 }
9699 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9224 { 9700 {
9225 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9701 m_host.TaskInventory.LockItemsForRead(false);
9226 if (agentID == UUID.Zero) return; 9702 return;
9227 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9228 } 9703 }
9704 m_host.TaskInventory.LockItemsForRead(false);
9229 9705
9230 ScenePresence presence = World.GetScenePresence(agentID); 9706 ScenePresence presence = World.GetScenePresence(agentID);
9231 9707
@@ -9292,19 +9768,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 9768 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9293 { 9769 {
9294 m_host.AddScriptLPS(1); 9770 m_host.AddScriptLPS(1);
9295 string ret = String.Empty; 9771
9296 string src1 = llBase64ToString(str1); 9772 if (str1 == String.Empty)
9297 string src2 = llBase64ToString(str2); 9773 return String.Empty;
9298 int c = 0; 9774 if (str2 == String.Empty)
9299 for (int i = 0; i < src1.Length; i++) 9775 return str1;
9776
9777 byte[] data1 = Convert.FromBase64String(str1);
9778 byte[] data2 = Convert.FromBase64String(str2);
9779
9780 byte[] d2 = new Byte[data1.Length];
9781 int pos = 0;
9782
9783 if (data1.Length <= data2.Length)
9300 { 9784 {
9301 ret += (char) (src1[i] ^ src2[c]); 9785 Array.Copy(data2, 0, d2, 0, data1.Length);
9786 }
9787 else
9788 {
9789 while (pos < data1.Length)
9790 {
9791 int len = data1.Length - pos;
9792 if (len > data2.Length)
9793 len = data2.Length;
9302 9794
9303 c++; 9795 Array.Copy(data2, 0, d2, pos, len);
9304 if (c >= src2.Length) 9796 pos += len;
9305 c = 0; 9797 }
9306 } 9798 }
9307 return llStringToBase64(ret); 9799
9800 for (pos = 0 ; pos < data1.Length ; pos++ )
9801 data1[pos] ^= d2[pos];
9802
9803 return Convert.ToBase64String(data1);
9308 } 9804 }
9309 9805
9310 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 9806 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9682,15 +10178,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 10178
9683 internal UUID ScriptByName(string name) 10179 internal UUID ScriptByName(string name)
9684 { 10180 {
9685 lock (m_host.TaskInventory) 10181 m_host.TaskInventory.LockItemsForRead(true);
10182
10183 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9686 { 10184 {
9687 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10185 if (item.Type == 10 && item.Name == name)
9688 { 10186 {
9689 if (item.Type == 10 && item.Name == name) 10187 m_host.TaskInventory.LockItemsForRead(false);
9690 return item.ItemID; 10188 return item.ItemID;
9691 } 10189 }
9692 } 10190 }
9693 10191
10192 m_host.TaskInventory.LockItemsForRead(false);
10193
9694 return UUID.Zero; 10194 return UUID.Zero;
9695 } 10195 }
9696 10196
@@ -9731,6 +10231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9731 { 10231 {
9732 m_host.AddScriptLPS(1); 10232 m_host.AddScriptLPS(1);
9733 10233
10234 //Clone is thread safe
9734 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10235 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9735 10236
9736 UUID assetID = UUID.Zero; 10237 UUID assetID = UUID.Zero;
@@ -9793,6 +10294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9793 { 10294 {
9794 m_host.AddScriptLPS(1); 10295 m_host.AddScriptLPS(1);
9795 10296
10297 //Clone is thread safe
9796 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10298 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9797 10299
9798 UUID assetID = UUID.Zero; 10300 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..c9049e2 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
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0299385..d4c1727 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 }
@@ -701,113 +769,119 @@ namespace OpenSim.Region.ScriptEngine.XEngine
701 } 769 }
702 } 770 }
703 771
704 lock (m_Scripts) 772
773
774 ScriptInstance instance = null;
775 // Create the object record
776 lockScriptsForRead(true);
777 if ((!m_Scripts.ContainsKey(itemID)) ||
778 (m_Scripts[itemID].AssetID != assetID))
705 { 779 {
706 ScriptInstance instance = null; 780 lockScriptsForRead(false);
707 // Create the object record
708 781
709 if ((!m_Scripts.ContainsKey(itemID)) || 782 UUID appDomain = assetID;
710 (m_Scripts[itemID].AssetID != assetID))
711 {
712 UUID appDomain = assetID;
713 783
714 if (part.ParentGroup.IsAttachment) 784 if (part.ParentGroup.IsAttachment)
715 appDomain = part.ParentGroup.RootPart.UUID; 785 appDomain = part.ParentGroup.RootPart.UUID;
716 786
717 if (!m_AppDomains.ContainsKey(appDomain)) 787 if (!m_AppDomains.ContainsKey(appDomain))
788 {
789 try
718 { 790 {
719 try 791 AppDomainSetup appSetup = new AppDomainSetup();
720 { 792 // appSetup.ApplicationBase = Path.Combine(
721 AppDomainSetup appSetup = new AppDomainSetup(); 793 // "ScriptEngines",
722// appSetup.ApplicationBase = Path.Combine( 794 // m_Scene.RegionInfo.RegionID.ToString());
723// "ScriptEngines", 795
724// m_Scene.RegionInfo.RegionID.ToString()); 796 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
725 797 Evidence evidence = new Evidence(baseEvidence);
726 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 798
727 Evidence evidence = new Evidence(baseEvidence); 799 AppDomain sandbox;
728 800 if (m_AppDomainLoading)
729 AppDomain sandbox; 801 sandbox = AppDomain.CreateDomain(
730 if (m_AppDomainLoading) 802 m_Scene.RegionInfo.RegionID.ToString(),
731 sandbox = AppDomain.CreateDomain( 803 evidence, appSetup);
732 m_Scene.RegionInfo.RegionID.ToString(), 804 else
733 evidence, appSetup); 805 sandbox = AppDomain.CurrentDomain;
734 else 806
735 sandbox = AppDomain.CurrentDomain; 807 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
736 808 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
737 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 809 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
738 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 810 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
739 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 811 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
740 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 812 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
741 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 813 //sandbox.SetAppDomainPolicy(sandboxPolicy);
742 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 814
743 //sandbox.SetAppDomainPolicy(sandboxPolicy); 815 m_AppDomains[appDomain] = sandbox;
744 816
745 m_AppDomains[appDomain] = sandbox; 817 m_AppDomains[appDomain].AssemblyResolve +=
746 818 new ResolveEventHandler(
747 m_AppDomains[appDomain].AssemblyResolve += 819 AssemblyResolver.OnAssemblyResolve);
748 new ResolveEventHandler( 820 m_DomainScripts[appDomain] = new List<UUID>();
749 AssemblyResolver.OnAssemblyResolve); 821 }
750 m_DomainScripts[appDomain] = new List<UUID>(); 822 catch (Exception e)
751 } 823 {
752 catch (Exception e) 824 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
825 m_ScriptErrorMessage += "Exception creating app domain:\n";
826 m_ScriptFailCount++;
827 lock (m_AddingAssemblies)
753 { 828 {
754 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 829 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 } 830 }
831 return false;
763 } 832 }
764 m_DomainScripts[appDomain].Add(itemID); 833 }
765 834 m_DomainScripts[appDomain].Add(itemID);
766 instance = new ScriptInstance(this, part, 835
767 itemID, assetID, assembly, 836 instance = new ScriptInstance(this, part,
768 m_AppDomains[appDomain], 837 itemID, assetID, assembly,
769 part.ParentGroup.RootPart.Name, 838 m_AppDomains[appDomain],
770 item.Name, startParam, postOnRez, 839 part.ParentGroup.RootPart.Name,
771 stateSource, m_MaxScriptQueue); 840 item.Name, startParam, postOnRez,
772 841 stateSource, m_MaxScriptQueue);
773 m_log.DebugFormat( 842
843 m_log.DebugFormat(
774 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 844 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
775 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 845 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
776 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 846 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
777 847
778 if (presence != null) 848 if (presence != null)
779 {
780 ShowScriptSaveResponse(item.OwnerID,
781 assetID, "Compile successful", true);
782 }
783
784 instance.AppDomain = appDomain;
785 instance.LineMap = linemap;
786
787 m_Scripts[itemID] = instance;
788 }
789
790 lock (m_PrimObjects)
791 { 849 {
792 if (!m_PrimObjects.ContainsKey(localID)) 850 ShowScriptSaveResponse(item.OwnerID,
793 m_PrimObjects[localID] = new List<UUID>(); 851 assetID, "Compile successful", true);
852 }
794 853
795 if (!m_PrimObjects[localID].Contains(itemID)) 854 instance.AppDomain = appDomain;
796 m_PrimObjects[localID].Add(itemID); 855 instance.LineMap = linemap;
856 lockScriptsForWrite(true);
857 m_Scripts[itemID] = instance;
858 lockScriptsForWrite(false);
859 }
860 else
861 {
862 lockScriptsForRead(false);
863 }
864 lock (m_PrimObjects)
865 {
866 if (!m_PrimObjects.ContainsKey(localID))
867 m_PrimObjects[localID] = new List<UUID>();
797 868
798 } 869 if (!m_PrimObjects[localID].Contains(itemID))
870 m_PrimObjects[localID].Add(itemID);
799 871
800 if (!m_Assemblies.ContainsKey(assetID)) 872 }
801 m_Assemblies[assetID] = assembly;
802 873
803 lock (m_AddingAssemblies) 874 if (!m_Assemblies.ContainsKey(assetID))
804 { 875 m_Assemblies[assetID] = assembly;
805 m_AddingAssemblies[assembly]--;
806 }
807 876
808 if (instance!=null) 877 lock (m_AddingAssemblies)
809 instance.Init(); 878 {
879 m_AddingAssemblies[assembly]--;
810 } 880 }
881
882 if (instance!=null)
883 instance.Init();
884
811 return true; 885 return true;
812 } 886 }
813 887
@@ -820,60 +894,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine
820 m_CompileDict.Remove(itemID); 894 m_CompileDict.Remove(itemID);
821 } 895 }
822 896
823 lock (m_Scripts) 897 lockScriptsForRead(true);
898 // Do we even have it?
899 if (!m_Scripts.ContainsKey(itemID))
824 { 900 {
825 // Do we even have it? 901 lockScriptsForRead(false);
826 if (!m_Scripts.ContainsKey(itemID)) 902 return;
827 return; 903 }
828 904
829 IScriptInstance instance=m_Scripts[itemID];
830 m_Scripts.Remove(itemID);
831 905
832 instance.ClearQueue(); 906 IScriptInstance instance=m_Scripts[itemID];
833 instance.Stop(0); 907 lockScriptsForRead(false);
908 lockScriptsForWrite(true);
909 m_Scripts.Remove(itemID);
910 lockScriptsForWrite(false);
911 instance.ClearQueue();
912 instance.Stop(0);
834 913
835// bool objectRemoved = false; 914// bool objectRemoved = false;
836 915
837 lock (m_PrimObjects) 916 lock (m_PrimObjects)
917 {
918 // Remove the script from it's prim
919 if (m_PrimObjects.ContainsKey(localID))
838 { 920 {
839 // Remove the script from it's prim 921 // Remove inventory item record
840 if (m_PrimObjects.ContainsKey(localID)) 922 if (m_PrimObjects[localID].Contains(itemID))
841 { 923 m_PrimObjects[localID].Remove(itemID);
842 // Remove inventory item record
843 if (m_PrimObjects[localID].Contains(itemID))
844 m_PrimObjects[localID].Remove(itemID);
845 924
846 // If there are no more scripts, remove prim 925 // If there are no more scripts, remove prim
847 if (m_PrimObjects[localID].Count == 0) 926 if (m_PrimObjects[localID].Count == 0)
848 { 927 {
849 m_PrimObjects.Remove(localID); 928 m_PrimObjects.Remove(localID);
850// objectRemoved = true; 929// objectRemoved = true;
851 }
852 } 930 }
853 } 931 }
932 }
854 933
855 instance.RemoveState(); 934 instance.RemoveState();
856 instance.DestroyScriptInstance(); 935 instance.DestroyScriptInstance();
857 936
858 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 937 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
859 if (m_DomainScripts[instance.AppDomain].Count == 0) 938 if (m_DomainScripts[instance.AppDomain].Count == 0)
860 { 939 {
861 m_DomainScripts.Remove(instance.AppDomain); 940 m_DomainScripts.Remove(instance.AppDomain);
862 UnloadAppDomain(instance.AppDomain); 941 UnloadAppDomain(instance.AppDomain);
863 } 942 }
864
865 instance = null;
866 943
867 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 944 instance = null;
868 if (handlerObjectRemoved != null)
869 {
870 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
871 handlerObjectRemoved(part.UUID);
872 }
873 945
874 CleanAssemblies(); 946 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
947 if (handlerObjectRemoved != null)
948 {
949 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
950 handlerObjectRemoved(part.UUID);
875 } 951 }
876 952
953 CleanAssemblies();
954
955
877 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 956 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
878 if (handlerScriptRemoved != null) 957 if (handlerScriptRemoved != null)
879 handlerScriptRemoved(itemID); 958 handlerScriptRemoved(itemID);
@@ -1125,12 +1204,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1125 private IScriptInstance GetInstance(UUID itemID) 1204 private IScriptInstance GetInstance(UUID itemID)
1126 { 1205 {
1127 IScriptInstance instance; 1206 IScriptInstance instance;
1128 lock (m_Scripts) 1207 lockScriptsForRead(true);
1208 if (!m_Scripts.ContainsKey(itemID))
1129 { 1209 {
1130 if (!m_Scripts.ContainsKey(itemID)) 1210 lockScriptsForRead(false);
1131 return null; 1211 return null;
1132 instance = m_Scripts[itemID];
1133 } 1212 }
1213 instance = m_Scripts[itemID];
1214 lockScriptsForRead(false);
1134 return instance; 1215 return instance;
1135 } 1216 }
1136 1217
@@ -1154,6 +1235,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1154 return false; 1235 return false;
1155 } 1236 }
1156 1237
1238 [DebuggerNonUserCode]
1157 public void ApiResetScript(UUID itemID) 1239 public void ApiResetScript(UUID itemID)
1158 { 1240 {
1159 IScriptInstance instance = GetInstance(itemID); 1241 IScriptInstance instance = GetInstance(itemID);
@@ -1205,6 +1287,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1205 return UUID.Zero; 1287 return UUID.Zero;
1206 } 1288 }
1207 1289
1290 [DebuggerNonUserCode]
1208 public void SetState(UUID itemID, string newState) 1291 public void SetState(UUID itemID, string newState)
1209 { 1292 {
1210 IScriptInstance instance = GetInstance(itemID); 1293 IScriptInstance instance = GetInstance(itemID);
@@ -1225,11 +1308,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1225 { 1308 {
1226 List<IScriptInstance> instances = new List<IScriptInstance>(); 1309 List<IScriptInstance> instances = new List<IScriptInstance>();
1227 1310
1228 lock (m_Scripts) 1311 lockScriptsForRead(true);
1229 { 1312 foreach (IScriptInstance instance in m_Scripts.Values)
1230 foreach (IScriptInstance instance in m_Scripts.Values)
1231 instances.Add(instance); 1313 instances.Add(instance);
1232 } 1314 lockScriptsForRead(false);
1233 1315
1234 foreach (IScriptInstance i in instances) 1316 foreach (IScriptInstance i in instances)
1235 { 1317 {