aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1722
-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, 1465 insertions, 841 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index dbea6ef..defe633 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,10 +3160,7 @@ 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
2941 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3163 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2942 if (attachmentsModule != null)
2943 attachmentsModule.AttachObject(presence.ControllingClient,
2944 grp, (uint)attachment, false);
2945 } 3164 }
2946 } 3165 }
2947 3166
@@ -2954,13 +3173,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3173
2955 TaskInventoryItem item; 3174 TaskInventoryItem item;
2956 3175
2957 lock (m_host.TaskInventory) 3176 m_host.TaskInventory.LockItemsForRead(true);
3177
3178 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2958 { 3179 {
2959 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3180 m_host.TaskInventory.LockItemsForRead(false);
2960 return; 3181 return;
2961 else 3182 }
2962 item = m_host.TaskInventory[InventorySelf()]; 3183 else
3184 {
3185 item = m_host.TaskInventory[InventorySelf()];
2963 } 3186 }
3187 m_host.TaskInventory.LockItemsForRead(false);
3188
2964 3189
2965 if (item.PermsGranter != m_host.OwnerID) 3190 if (item.PermsGranter != m_host.OwnerID)
2966 return; 3191 return;
@@ -2997,8 +3222,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 return m_host.OwnerID.ToString(); 3222 return m_host.OwnerID.ToString();
2998 } 3223 }
2999 3224
3225 [DebuggerNonUserCode]
3000 public void llInstantMessage(string user, string message) 3226 public void llInstantMessage(string user, string message)
3001 { 3227 {
3228 UUID result;
3229 if (!UUID.TryParse(user, out result))
3230 {
3231 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3232 return;
3233 }
3234
3235
3002 m_host.AddScriptLPS(1); 3236 m_host.AddScriptLPS(1);
3003 3237
3004 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3238 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3013,14 +3247,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 UUID friendTransactionID = UUID.Random(); 3247 UUID friendTransactionID = UUID.Random();
3014 3248
3015 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3249 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3016 3250
3017 GridInstantMessage msg = new GridInstantMessage(); 3251 GridInstantMessage msg = new GridInstantMessage();
3018 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3252 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3019 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3253 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3020 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3254 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3021// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3255// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3022// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3256// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3023 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3257 DateTime dt = DateTime.UtcNow;
3258
3259 // Ticks from UtcNow, but make it look like local. Evil, huh?
3260 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3261
3262 try
3263 {
3264 // Convert that to the PST timezone
3265 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3266 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3267 }
3268 catch
3269 {
3270 // No logging here, as it could be VERY spammy
3271 }
3272
3273 // And make it look local again to fool the unix time util
3274 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3275
3276 msg.timestamp = (uint)Util.ToUnixTime(dt);
3277
3024 //if (client != null) 3278 //if (client != null)
3025 //{ 3279 //{
3026 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3280 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3034,13 +3288,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3034 msg.message = message.Substring(0, 1024); 3288 msg.message = message.Substring(0, 1024);
3035 else 3289 else
3036 msg.message = message; 3290 msg.message = message;
3037 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3291 msg.dialog = (byte)19; // MessageFromObject
3038 msg.fromGroup = false;// fromGroup; 3292 msg.fromGroup = false;// fromGroup;
3039 msg.offline = (byte)0; //offline; 3293 msg.offline = (byte)0; //offline;
3040 msg.ParentEstateID = 0; //ParentEstateID; 3294 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3041 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3295 msg.Position = new Vector3(m_host.AbsolutePosition);
3042 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3296 msg.RegionID = World.RegionInfo.RegionID.Guid;
3043 msg.binaryBucket = new byte[0];// binaryBucket; 3297 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3044 3298
3045 if (m_TransferModule != null) 3299 if (m_TransferModule != null)
3046 { 3300 {
@@ -3162,13 +3416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3162 m_host.AddScriptLPS(1); 3416 m_host.AddScriptLPS(1);
3163 } 3417 }
3164 3418
3165 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3166 {
3167 m_host.AddScriptLPS(1);
3168 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3169 m_host.RotLookAt(rot, (float)strength, (float)damping);
3170 }
3171
3172 public LSL_Integer llStringLength(string str) 3419 public LSL_Integer llStringLength(string str)
3173 { 3420 {
3174 m_host.AddScriptLPS(1); 3421 m_host.AddScriptLPS(1);
@@ -3192,14 +3439,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 3439
3193 TaskInventoryItem item; 3440 TaskInventoryItem item;
3194 3441
3195 lock (m_host.TaskInventory) 3442 m_host.TaskInventory.LockItemsForRead(true);
3443 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3196 { 3444 {
3197 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3445 m_host.TaskInventory.LockItemsForRead(false);
3198 return; 3446 return;
3199 else
3200 item = m_host.TaskInventory[InventorySelf()];
3201 } 3447 }
3202 3448 else
3449 {
3450 item = m_host.TaskInventory[InventorySelf()];
3451 }
3452 m_host.TaskInventory.LockItemsForRead(false);
3203 if (item.PermsGranter == UUID.Zero) 3453 if (item.PermsGranter == UUID.Zero)
3204 return; 3454 return;
3205 3455
@@ -3229,13 +3479,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3229 3479
3230 TaskInventoryItem item; 3480 TaskInventoryItem item;
3231 3481
3232 lock (m_host.TaskInventory) 3482 m_host.TaskInventory.LockItemsForRead(true);
3483 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3233 { 3484 {
3234 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3485 m_host.TaskInventory.LockItemsForRead(false);
3235 return; 3486 return;
3236 else 3487 }
3237 item = m_host.TaskInventory[InventorySelf()]; 3488 else
3489 {
3490 item = m_host.TaskInventory[InventorySelf()];
3238 } 3491 }
3492 m_host.TaskInventory.LockItemsForRead(false);
3493
3239 3494
3240 if (item.PermsGranter == UUID.Zero) 3495 if (item.PermsGranter == UUID.Zero)
3241 return; 3496 return;
@@ -3312,10 +3567,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3312 3567
3313 TaskInventoryItem item; 3568 TaskInventoryItem item;
3314 3569
3315 lock (m_host.TaskInventory) 3570
3571 m_host.TaskInventory.LockItemsForRead(true);
3572 if (!m_host.TaskInventory.ContainsKey(invItemID))
3573 {
3574 m_host.TaskInventory.LockItemsForRead(false);
3575 return;
3576 }
3577 else
3316 { 3578 {
3317 item = m_host.TaskInventory[invItemID]; 3579 item = m_host.TaskInventory[invItemID];
3318 } 3580 }
3581 m_host.TaskInventory.LockItemsForRead(false);
3319 3582
3320 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3583 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3321 { 3584 {
@@ -3347,11 +3610,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3347 3610
3348 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3611 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3349 { 3612 {
3350 lock (m_host.TaskInventory) 3613 m_host.TaskInventory.LockItemsForWrite(true);
3351 { 3614 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3352 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3615 m_host.TaskInventory[invItemID].PermsMask = perm;
3353 m_host.TaskInventory[invItemID].PermsMask = perm; 3616 m_host.TaskInventory.LockItemsForWrite(false);
3354 }
3355 3617
3356 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3618 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3357 "run_time_permissions", new Object[] { 3619 "run_time_permissions", new Object[] {
@@ -3371,11 +3633,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3371 3633
3372 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3634 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3373 { 3635 {
3374 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForWrite(true);
3375 { 3637 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3376 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3638 m_host.TaskInventory[invItemID].PermsMask = perm;
3377 m_host.TaskInventory[invItemID].PermsMask = perm; 3639 m_host.TaskInventory.LockItemsForWrite(false);
3378 }
3379 3640
3380 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3641 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3381 "run_time_permissions", new Object[] { 3642 "run_time_permissions", new Object[] {
@@ -3396,11 +3657,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3396 3657
3397 if (!m_waitingForScriptAnswer) 3658 if (!m_waitingForScriptAnswer)
3398 { 3659 {
3399 lock (m_host.TaskInventory) 3660 m_host.TaskInventory.LockItemsForWrite(true);
3400 { 3661 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3401 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3662 m_host.TaskInventory[invItemID].PermsMask = 0;
3402 m_host.TaskInventory[invItemID].PermsMask = 0; 3663 m_host.TaskInventory.LockItemsForWrite(false);
3403 }
3404 3664
3405 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3665 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3406 m_waitingForScriptAnswer=true; 3666 m_waitingForScriptAnswer=true;
@@ -3435,10 +3695,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3435 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3695 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3436 llReleaseControls(); 3696 llReleaseControls();
3437 3697
3438 lock (m_host.TaskInventory) 3698
3439 { 3699 m_host.TaskInventory.LockItemsForWrite(true);
3440 m_host.TaskInventory[invItemID].PermsMask = answer; 3700 m_host.TaskInventory[invItemID].PermsMask = answer;
3441 } 3701 m_host.TaskInventory.LockItemsForWrite(false);
3702
3442 3703
3443 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3704 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3444 "run_time_permissions", new Object[] { 3705 "run_time_permissions", new Object[] {
@@ -3450,16 +3711,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3450 { 3711 {
3451 m_host.AddScriptLPS(1); 3712 m_host.AddScriptLPS(1);
3452 3713
3453 lock (m_host.TaskInventory) 3714 m_host.TaskInventory.LockItemsForRead(true);
3715
3716 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3454 { 3717 {
3455 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3718 if (item.Type == 10 && item.ItemID == m_itemID)
3456 { 3719 {
3457 if (item.Type == 10 && item.ItemID == m_itemID) 3720 m_host.TaskInventory.LockItemsForRead(false);
3458 { 3721 return item.PermsGranter.ToString();
3459 return item.PermsGranter.ToString();
3460 }
3461 } 3722 }
3462 } 3723 }
3724 m_host.TaskInventory.LockItemsForRead(false);
3463 3725
3464 return UUID.Zero.ToString(); 3726 return UUID.Zero.ToString();
3465 } 3727 }
@@ -3468,19 +3730,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3468 { 3730 {
3469 m_host.AddScriptLPS(1); 3731 m_host.AddScriptLPS(1);
3470 3732
3471 lock (m_host.TaskInventory) 3733 m_host.TaskInventory.LockItemsForRead(true);
3734
3735 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3472 { 3736 {
3473 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3737 if (item.Type == 10 && item.ItemID == m_itemID)
3474 { 3738 {
3475 if (item.Type == 10 && item.ItemID == m_itemID) 3739 int perms = item.PermsMask;
3476 { 3740 if (m_automaticLinkPermission)
3477 int perms = item.PermsMask; 3741 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3478 if (m_automaticLinkPermission) 3742 m_host.TaskInventory.LockItemsForRead(false);
3479 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3743 return perms;
3480 return perms;
3481 }
3482 } 3744 }
3483 } 3745 }
3746 m_host.TaskInventory.LockItemsForRead(false);
3484 3747
3485 return 0; 3748 return 0;
3486 } 3749 }
@@ -3502,9 +3765,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3502 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3765 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3503 { 3766 {
3504 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3767 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3505 3768 if (parts.Count > 0)
3506 foreach (SceneObjectPart part in parts) 3769 {
3507 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3770 try
3771 {
3772 parts[0].ParentGroup.areUpdatesSuspended = true;
3773 foreach (SceneObjectPart part in parts)
3774 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3775 }
3776 finally
3777 {
3778 parts[0].ParentGroup.areUpdatesSuspended = false;
3779 }
3780 }
3508 } 3781 }
3509 3782
3510 public void llCreateLink(string target, int parent) 3783 public void llCreateLink(string target, int parent)
@@ -3513,11 +3786,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3513 UUID invItemID = InventorySelf(); 3786 UUID invItemID = InventorySelf();
3514 3787
3515 TaskInventoryItem item; 3788 TaskInventoryItem item;
3516 lock (m_host.TaskInventory) 3789 m_host.TaskInventory.LockItemsForRead(true);
3517 { 3790 item = m_host.TaskInventory[invItemID];
3518 item = m_host.TaskInventory[invItemID]; 3791 m_host.TaskInventory.LockItemsForRead(false);
3519 } 3792
3520
3521 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3793 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3522 && !m_automaticLinkPermission) 3794 && !m_automaticLinkPermission)
3523 { 3795 {
@@ -3570,16 +3842,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3570 m_host.AddScriptLPS(1); 3842 m_host.AddScriptLPS(1);
3571 UUID invItemID = InventorySelf(); 3843 UUID invItemID = InventorySelf();
3572 3844
3573 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3574 {
3575 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3846 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3576 && !m_automaticLinkPermission) 3847 && !m_automaticLinkPermission)
3577 { 3848 {
3578 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3849 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3850 m_host.TaskInventory.LockItemsForRead(false);
3579 return; 3851 return;
3580 } 3852 }
3581 } 3853 m_host.TaskInventory.LockItemsForRead(false);
3582 3854
3583 if (linknum < ScriptBaseClass.LINK_THIS) 3855 if (linknum < ScriptBaseClass.LINK_THIS)
3584 return; 3856 return;
3585 3857
@@ -3618,10 +3890,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3618 // Restructuring Multiple Prims. 3890 // Restructuring Multiple Prims.
3619 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3891 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3620 parts.Remove(parentPrim.RootPart); 3892 parts.Remove(parentPrim.RootPart);
3621 foreach (SceneObjectPart part in parts) 3893 if (parts.Count > 0)
3622 { 3894 {
3623 parentPrim.DelinkFromGroup(part.LocalId, true); 3895 try
3896 {
3897 parts[0].ParentGroup.areUpdatesSuspended = true;
3898 foreach (SceneObjectPart part in parts)
3899 {
3900 parentPrim.DelinkFromGroup(part.LocalId, true);
3901 }
3902 }
3903 finally
3904 {
3905 parts[0].ParentGroup.areUpdatesSuspended = false;
3906 }
3624 } 3907 }
3908
3625 parentPrim.HasGroupChanged = true; 3909 parentPrim.HasGroupChanged = true;
3626 parentPrim.ScheduleGroupForFullUpdate(); 3910 parentPrim.ScheduleGroupForFullUpdate();
3627 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3911 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3630,11 +3914,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3630 { 3914 {
3631 SceneObjectPart newRoot = parts[0]; 3915 SceneObjectPart newRoot = parts[0];
3632 parts.Remove(newRoot); 3916 parts.Remove(newRoot);
3633 foreach (SceneObjectPart part in parts) 3917
3918 try
3634 { 3919 {
3635 part.UpdateFlag = 0; 3920 parts[0].ParentGroup.areUpdatesSuspended = true;
3636 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3921 foreach (SceneObjectPart part in parts)
3922 {
3923 part.UpdateFlag = 0;
3924 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3925 }
3637 } 3926 }
3927 finally
3928 {
3929 parts[0].ParentGroup.areUpdatesSuspended = false;
3930 }
3931
3932
3638 newRoot.ParentGroup.HasGroupChanged = true; 3933 newRoot.ParentGroup.HasGroupChanged = true;
3639 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3934 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3640 } 3935 }
@@ -3660,11 +3955,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3660 3955
3661 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3956 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3662 parts.Remove(parentPrim.RootPart); 3957 parts.Remove(parentPrim.RootPart);
3663 3958 if (parts.Count > 0)
3664 foreach (SceneObjectPart part in parts)
3665 { 3959 {
3666 parentPrim.DelinkFromGroup(part.LocalId, true); 3960 try
3667 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3961 {
3962 parts[0].ParentGroup.areUpdatesSuspended = true;
3963 foreach (SceneObjectPart part in parts)
3964 {
3965 parentPrim.DelinkFromGroup(part.LocalId, true);
3966 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3967 }
3968 }
3969 finally
3970 {
3971 parts[0].ParentGroup.areUpdatesSuspended = false;
3972 }
3668 } 3973 }
3669 parentPrim.HasGroupChanged = true; 3974 parentPrim.HasGroupChanged = true;
3670 parentPrim.ScheduleGroupForFullUpdate(); 3975 parentPrim.ScheduleGroupForFullUpdate();
@@ -3756,17 +4061,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3756 m_host.AddScriptLPS(1); 4061 m_host.AddScriptLPS(1);
3757 int count = 0; 4062 int count = 0;
3758 4063
3759 lock (m_host.TaskInventory) 4064 m_host.TaskInventory.LockItemsForRead(true);
4065 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3760 { 4066 {
3761 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4067 if (inv.Value.Type == type || type == -1)
3762 { 4068 {
3763 if (inv.Value.Type == type || type == -1) 4069 count = count + 1;
3764 {
3765 count = count + 1;
3766 }
3767 } 4070 }
3768 } 4071 }
3769 4072
4073 m_host.TaskInventory.LockItemsForRead(false);
3770 return count; 4074 return count;
3771 } 4075 }
3772 4076
@@ -3775,16 +4079,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3775 m_host.AddScriptLPS(1); 4079 m_host.AddScriptLPS(1);
3776 ArrayList keys = new ArrayList(); 4080 ArrayList keys = new ArrayList();
3777 4081
3778 lock (m_host.TaskInventory) 4082 m_host.TaskInventory.LockItemsForRead(true);
4083 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3779 { 4084 {
3780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4085 if (inv.Value.Type == type || type == -1)
3781 { 4086 {
3782 if (inv.Value.Type == type || type == -1) 4087 keys.Add(inv.Value.Name);
3783 {
3784 keys.Add(inv.Value.Name);
3785 }
3786 } 4088 }
3787 } 4089 }
4090 m_host.TaskInventory.LockItemsForRead(false);
3788 4091
3789 if (keys.Count == 0) 4092 if (keys.Count == 0)
3790 { 4093 {
@@ -3821,20 +4124,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3821 } 4124 }
3822 4125
3823 // move the first object found with this inventory name 4126 // move the first object found with this inventory name
3824 lock (m_host.TaskInventory) 4127 m_host.TaskInventory.LockItemsForRead(true);
4128 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3825 { 4129 {
3826 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4130 if (inv.Value.Name == inventory)
3827 { 4131 {
3828 if (inv.Value.Name == inventory) 4132 found = true;
3829 { 4133 objId = inv.Key;
3830 found = true; 4134 assetType = inv.Value.Type;
3831 objId = inv.Key; 4135 objName = inv.Value.Name;
3832 assetType = inv.Value.Type; 4136 break;
3833 objName = inv.Value.Name;
3834 break;
3835 }
3836 } 4137 }
3837 } 4138 }
4139 m_host.TaskInventory.LockItemsForRead(false);
3838 4140
3839 if (!found) 4141 if (!found)
3840 { 4142 {
@@ -3842,9 +4144,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3842 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4144 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3843 } 4145 }
3844 4146
3845 // check if destination is an avatar 4147 // check if destination is an object
3846 if (World.GetScenePresence(destId) != null) 4148 if (World.GetSceneObjectPart(destId) != null)
3847 { 4149 {
4150 // destination is an object
4151 World.MoveTaskInventoryItem(destId, m_host, objId);
4152 }
4153 else
4154 {
4155 ScenePresence presence = World.GetScenePresence(destId);
4156
4157 if (presence == null)
4158 {
4159 UserAccount account =
4160 World.UserAccountService.GetUserAccount(
4161 World.RegionInfo.ScopeID,
4162 destId);
4163
4164 if (account == null)
4165 {
4166 llSay(0, "Can't find destination "+destId.ToString());
4167 return;
4168 }
4169 }
4170
3848 // destination is an avatar 4171 // destination is an avatar
3849 InventoryItemBase agentItem = 4172 InventoryItemBase agentItem =
3850 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4173 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3870,33 +4193,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3870 4193
3871 if (m_TransferModule != null) 4194 if (m_TransferModule != null)
3872 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4195 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4196
4197 //This delay should only occur when giving inventory to avatars.
4198 ScriptSleep(3000);
3873 } 4199 }
3874 else
3875 {
3876 // destination is an object
3877 World.MoveTaskInventoryItem(destId, m_host, objId);
3878 }
3879 ScriptSleep(3000);
3880 } 4200 }
3881 4201
4202 [DebuggerNonUserCode]
3882 public void llRemoveInventory(string name) 4203 public void llRemoveInventory(string name)
3883 { 4204 {
3884 m_host.AddScriptLPS(1); 4205 m_host.AddScriptLPS(1);
3885 4206
3886 lock (m_host.TaskInventory) 4207 m_host.TaskInventory.LockItemsForRead(true);
4208 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3887 { 4209 {
3888 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4210 if (item.Name == name)
3889 { 4211 {
3890 if (item.Name == name) 4212 if (item.ItemID == m_itemID)
3891 { 4213 throw new ScriptDeleteException();
3892 if (item.ItemID == m_itemID) 4214 else
3893 throw new ScriptDeleteException(); 4215 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3894 else 4216
3895 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4217 m_host.TaskInventory.LockItemsForRead(false);
3896 return; 4218 return;
3897 }
3898 } 4219 }
3899 } 4220 }
4221 m_host.TaskInventory.LockItemsForRead(false);
3900 } 4222 }
3901 4223
3902 public void llSetText(string text, LSL_Vector color, double alpha) 4224 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3932,22 +4254,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 UUID uuid = (UUID)id; 4254 UUID uuid = (UUID)id;
3933 4255
3934 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4256 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4257 if (account == null)
4258 return UUID.Zero.ToString();
4259
3935 4260
3936 PresenceInfo pinfo = null; 4261 PresenceInfo pinfo = null;
3937 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4262 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3938 if (pinfos != null && pinfos.Length > 0) 4263 if (pinfos != null && pinfos.Length > 0)
3939 pinfo = pinfos[0]; 4264 pinfo = pinfos[0];
3940 4265
3941 if (pinfo == null)
3942 return UUID.Zero.ToString();
3943
3944 string reply = String.Empty; 4266 string reply = String.Empty;
3945 4267
3946 switch (data) 4268 switch (data)
3947 { 4269 {
3948 case 1: // DATA_ONLINE (0|1) 4270 case 1: // DATA_ONLINE (0|1)
3949 // TODO: implement fetching of this information 4271 if (pinfo != null && pinfo.RegionID != UUID.Zero)
3950 if (pinfo != null)
3951 reply = "1"; 4272 reply = "1";
3952 else 4273 else
3953 reply = "0"; 4274 reply = "0";
@@ -3987,6 +4308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 { 4308 {
3988 m_host.AddScriptLPS(1); 4309 m_host.AddScriptLPS(1);
3989 4310
4311 //Clone is thread safe
3990 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4312 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3991 4313
3992 foreach (TaskInventoryItem item in itemDictionary.Values) 4314 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4040,6 +4362,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4040 ScenePresence presence = World.GetScenePresence(agentId); 4362 ScenePresence presence = World.GetScenePresence(agentId);
4041 if (presence != null) 4363 if (presence != null)
4042 { 4364 {
4365 // agent must not be a god
4366 if (presence.GodLevel >= 200) return;
4367
4043 // agent must be over the owners land 4368 // agent must be over the owners land
4044 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4369 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4045 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4370 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4100,17 +4425,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4100 UUID soundId = UUID.Zero; 4425 UUID soundId = UUID.Zero;
4101 if (!UUID.TryParse(impact_sound, out soundId)) 4426 if (!UUID.TryParse(impact_sound, out soundId))
4102 { 4427 {
4103 lock (m_host.TaskInventory) 4428 m_host.TaskInventory.LockItemsForRead(true);
4429 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4104 { 4430 {
4105 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4431 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4106 { 4432 {
4107 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4433 soundId = item.AssetID;
4108 { 4434 break;
4109 soundId = item.AssetID;
4110 break;
4111 }
4112 } 4435 }
4113 } 4436 }
4437 m_host.TaskInventory.LockItemsForRead(false);
4114 } 4438 }
4115 m_host.CollisionSound = soundId; 4439 m_host.CollisionSound = soundId;
4116 m_host.CollisionSoundVolume = (float)impact_volume; 4440 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4156,6 +4480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4156 UUID partItemID; 4480 UUID partItemID;
4157 foreach (SceneObjectPart part in parts) 4481 foreach (SceneObjectPart part in parts)
4158 { 4482 {
4483 //Clone is thread safe
4159 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4484 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4160 4485
4161 foreach (TaskInventoryItem item in itemsDictionary.Values) 4486 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4370,17 +4695,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4370 4695
4371 m_host.AddScriptLPS(1); 4696 m_host.AddScriptLPS(1);
4372 4697
4373 lock (m_host.TaskInventory) 4698 m_host.TaskInventory.LockItemsForRead(true);
4699 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4374 { 4700 {
4375 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4701 if (item.Type == 10 && item.ItemID == m_itemID)
4376 { 4702 {
4377 if (item.Type == 10 && item.ItemID == m_itemID) 4703 result = item.Name!=null?item.Name:String.Empty;
4378 { 4704 break;
4379 result = item.Name != null ? item.Name : String.Empty;
4380 break;
4381 }
4382 } 4705 }
4383 } 4706 }
4707 m_host.TaskInventory.LockItemsForRead(false);
4384 4708
4385 return result; 4709 return result;
4386 } 4710 }
@@ -4533,23 +4857,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4533 { 4857 {
4534 m_host.AddScriptLPS(1); 4858 m_host.AddScriptLPS(1);
4535 4859
4536 lock (m_host.TaskInventory) 4860 m_host.TaskInventory.LockItemsForRead(true);
4861 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4537 { 4862 {
4538 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4863 if (inv.Value.Name == name)
4539 { 4864 {
4540 if (inv.Value.Name == name) 4865 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4541 { 4866 {
4542 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4867 m_host.TaskInventory.LockItemsForRead(false);
4543 { 4868 return inv.Value.AssetID.ToString();
4544 return inv.Value.AssetID.ToString(); 4869 }
4545 } 4870 else
4546 else 4871 {
4547 { 4872 m_host.TaskInventory.LockItemsForRead(false);
4548 return UUID.Zero.ToString(); 4873 return UUID.Zero.ToString();
4549 }
4550 } 4874 }
4551 } 4875 }
4552 } 4876 }
4877 m_host.TaskInventory.LockItemsForRead(false);
4553 4878
4554 return UUID.Zero.ToString(); 4879 return UUID.Zero.ToString();
4555 } 4880 }
@@ -5485,10 +5810,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5485 m_host.AddScriptLPS(1); 5810 m_host.AddScriptLPS(1);
5486 5811
5487 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5812 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5488 5813 if (parts.Count > 0)
5489 foreach (var part in parts)
5490 { 5814 {
5491 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5815 try
5816 {
5817 parts[0].ParentGroup.areUpdatesSuspended = true;
5818 foreach (var part in parts)
5819 {
5820 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5821 }
5822 }
5823 finally
5824 {
5825 parts[0].ParentGroup.areUpdatesSuspended = false;
5826 }
5492 } 5827 }
5493 } 5828 }
5494 5829
@@ -5544,74 +5879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5544 5879
5545 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5880 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5546 { 5881 {
5547 m_host.AddScriptLPS(1); 5882 return ParseString2List(str, separators, in_spacers, false);
5548 LSL_List ret = new LSL_List();
5549 LSL_List spacers = new LSL_List();
5550 if (in_spacers.Length > 0 && separators.Length > 0)
5551 {
5552 for (int i = 0; i < in_spacers.Length; i++)
5553 {
5554 object s = in_spacers.Data[i];
5555 for (int j = 0; j < separators.Length; j++)
5556 {
5557 if (separators.Data[j].ToString() == s.ToString())
5558 {
5559 s = null;
5560 break;
5561 }
5562 }
5563 if (s != null)
5564 {
5565 spacers.Add(s);
5566 }
5567 }
5568 }
5569 object[] delimiters = new object[separators.Length + spacers.Length];
5570 separators.Data.CopyTo(delimiters, 0);
5571 spacers.Data.CopyTo(delimiters, separators.Length);
5572 bool dfound = false;
5573 do
5574 {
5575 dfound = false;
5576 int cindex = -1;
5577 string cdeli = "";
5578 for (int i = 0; i < delimiters.Length; i++)
5579 {
5580 int index = str.IndexOf(delimiters[i].ToString());
5581 bool found = index != -1;
5582 if (found && String.Empty != delimiters[i].ToString())
5583 {
5584 if ((cindex > index) || (cindex == -1))
5585 {
5586 cindex = index;
5587 cdeli = delimiters[i].ToString();
5588 }
5589 dfound = dfound || found;
5590 }
5591 }
5592 if (cindex != -1)
5593 {
5594 if (cindex > 0)
5595 {
5596 ret.Add(new LSL_String(str.Substring(0, cindex)));
5597 }
5598 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5599 for (int j = 0; j < spacers.Length; j++)
5600 {
5601 if (spacers.Data[j].ToString() == cdeli)
5602 {
5603 ret.Add(new LSL_String(cdeli));
5604 break;
5605 }
5606 }
5607 str = str.Substring(cindex + cdeli.Length);
5608 }
5609 } while (dfound);
5610 if (str != "")
5611 {
5612 ret.Add(new LSL_String(str));
5613 }
5614 return ret;
5615 } 5883 }
5616 5884
5617 public LSL_Integer llOverMyLand(string id) 5885 public LSL_Integer llOverMyLand(string id)
@@ -6067,6 +6335,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6067 tempf = (float)rules.GetLSLFloatItem(i + 1); 6335 tempf = (float)rules.GetLSLFloatItem(i + 1);
6068 prules.OuterAngle = (float)tempf; 6336 prules.OuterAngle = (float)tempf;
6069 break; 6337 break;
6338
6339 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6340 tempf = (float)rules.GetLSLFloatItem(i + 1);
6341 prules.InnerAngle = (float)tempf;
6342 break;
6343
6344 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6345 tempf = (float)rules.GetLSLFloatItem(i + 1);
6346 prules.OuterAngle = (float)tempf;
6347 break;
6070 } 6348 }
6071 6349
6072 } 6350 }
@@ -6105,14 +6383,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6105 6383
6106 protected UUID GetTaskInventoryItem(string name) 6384 protected UUID GetTaskInventoryItem(string name)
6107 { 6385 {
6108 lock (m_host.TaskInventory) 6386 m_host.TaskInventory.LockItemsForRead(true);
6387 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6109 { 6388 {
6110 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6389 if (inv.Value.Name == name)
6111 { 6390 {
6112 if (inv.Value.Name == name) 6391 m_host.TaskInventory.LockItemsForRead(false);
6113 return inv.Key; 6392 return inv.Key;
6114 } 6393 }
6115 } 6394 }
6395 m_host.TaskInventory.LockItemsForRead(false);
6116 6396
6117 return UUID.Zero; 6397 return UUID.Zero;
6118 } 6398 }
@@ -6440,22 +6720,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6440 } 6720 }
6441 6721
6442 // copy the first script found with this inventory name 6722 // copy the first script found with this inventory name
6443 lock (m_host.TaskInventory) 6723 m_host.TaskInventory.LockItemsForRead(true);
6724 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6444 { 6725 {
6445 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6726 if (inv.Value.Name == name)
6446 { 6727 {
6447 if (inv.Value.Name == name) 6728 // make sure the object is a script
6729 if (10 == inv.Value.Type)
6448 { 6730 {
6449 // make sure the object is a script 6731 found = true;
6450 if (10 == inv.Value.Type) 6732 srcId = inv.Key;
6451 { 6733 break;
6452 found = true;
6453 srcId = inv.Key;
6454 break;
6455 }
6456 } 6734 }
6457 } 6735 }
6458 } 6736 }
6737 m_host.TaskInventory.LockItemsForRead(false);
6459 6738
6460 if (!found) 6739 if (!found)
6461 { 6740 {
@@ -6539,6 +6818,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6539 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6818 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6540 { 6819 {
6541 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6820 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6821 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6822 return shapeBlock;
6542 6823
6543 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6824 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6544 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6825 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6614,6 +6895,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6614 6895
6615 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6896 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6616 { 6897 {
6898 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6899 return;
6900
6617 ObjectShapePacket.ObjectDataBlock shapeBlock; 6901 ObjectShapePacket.ObjectDataBlock shapeBlock;
6618 6902
6619 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6903 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6663,6 +6947,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6663 6947
6664 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6948 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6665 { 6949 {
6950 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6951 return;
6952
6666 ObjectShapePacket.ObjectDataBlock shapeBlock; 6953 ObjectShapePacket.ObjectDataBlock shapeBlock;
6667 6954
6668 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6955 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6705,6 +6992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6705 6992
6706 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) 6993 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)
6707 { 6994 {
6995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6996 return;
6997
6708 ObjectShapePacket.ObjectDataBlock shapeBlock; 6998 ObjectShapePacket.ObjectDataBlock shapeBlock;
6709 6999
6710 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7000 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6831,6 +7121,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6831 7121
6832 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7122 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6833 { 7123 {
7124 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7125 return;
7126
6834 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7127 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6835 UUID sculptId; 7128 UUID sculptId;
6836 7129
@@ -6846,13 +7139,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6846 shapeBlock.PathScaleX = 100; 7139 shapeBlock.PathScaleX = 100;
6847 shapeBlock.PathScaleY = 150; 7140 shapeBlock.PathScaleY = 150;
6848 7141
6849 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7142 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6850 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7143 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6851 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7144 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6852 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7145 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6853 { 7146 {
6854 // default 7147 // default
6855 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7148 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6856 } 7149 }
6857 7150
6858 // retain pathcurve 7151 // retain pathcurve
@@ -6871,12 +7164,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6871 7164
6872 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7165 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6873 { 7166 {
6874 m_host.AddScriptLPS(1); 7167 m_host.AddScriptLPS(1);
6875 7168
6876 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7169 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6877 7170 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
6878 foreach (SceneObjectPart part in parts) 7171 if (parts.Count>0)
6879 SetPrimParams(part, rules); 7172 {
7173 try
7174 {
7175 parts[0].ParentGroup.areUpdatesSuspended = true;
7176 foreach (SceneObjectPart part in parts)
7177 SetPrimParams(part, rules);
7178 }
7179 finally
7180 {
7181 parts[0].ParentGroup.areUpdatesSuspended = false;
7182 }
7183 }
7184 if (avatars.Count > 0)
7185 {
7186 foreach (ScenePresence avatar in avatars)
7187 SetPrimParams(avatar, rules);
7188 }
6880 } 7189 }
6881 7190
6882 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7191 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
@@ -6884,8 +7193,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6884 llSetLinkPrimitiveParams(linknumber, rules); 7193 llSetLinkPrimitiveParams(linknumber, rules);
6885 } 7194 }
6886 7195
7196 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7197 {
7198 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7199 //We only support PRIM_POSITION and PRIM_ROTATION
7200
7201 int idx = 0;
7202
7203 while (idx < rules.Length)
7204 {
7205 int code = rules.GetLSLIntegerItem(idx++);
7206
7207 int remain = rules.Length - idx;
7208
7209
7210
7211 switch (code)
7212 {
7213 case (int)ScriptBaseClass.PRIM_POSITION:
7214 if (remain < 1)
7215 return;
7216 LSL_Vector v;
7217 v = rules.GetVector3Item(idx++);
7218 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7219 av.SendFullUpdateToAllClients();
7220
7221 break;
7222
7223 case (int)ScriptBaseClass.PRIM_ROTATION:
7224 if (remain < 1)
7225 return;
7226 LSL_Rotation r;
7227 r = rules.GetQuaternionItem(idx++);
7228 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7229 av.SendFullUpdateToAllClients();
7230 break;
7231 }
7232 }
7233
7234 }
7235
6887 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7236 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6888 { 7237 {
7238 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7239 return;
7240
6889 int idx = 0; 7241 int idx = 0;
6890 7242
6891 while (idx < rules.Length) 7243 while (idx < rules.Length)
@@ -7717,24 +8069,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7717 break; 8069 break;
7718 8070
7719 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8071 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7720 // TODO--------------
7721 if (remain < 1) 8072 if (remain < 1)
7722 return res; 8073 return res;
8074 face = (int)rules.GetLSLIntegerItem(idx++);
7723 8075
7724 face=(int)rules.GetLSLIntegerItem(idx++); 8076 tex = part.Shape.Textures;
7725 8077 int shiny;
7726 res.Add(new LSL_Integer(0)); 8078 if (face == ScriptBaseClass.ALL_SIDES)
7727 res.Add(new LSL_Integer(0)); 8079 {
8080 for (face = 0; face < GetNumberOfSides(part); face++)
8081 {
8082 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8083 if (shinyness == Shininess.High)
8084 {
8085 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8086 }
8087 else if (shinyness == Shininess.Medium)
8088 {
8089 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8090 }
8091 else if (shinyness == Shininess.Low)
8092 {
8093 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8094 }
8095 else
8096 {
8097 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8098 }
8099 res.Add(new LSL_Integer(shiny));
8100 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8101 }
8102 }
8103 else
8104 {
8105 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8106 if (shinyness == Shininess.High)
8107 {
8108 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8109 }
8110 else if (shinyness == Shininess.Medium)
8111 {
8112 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8113 }
8114 else if (shinyness == Shininess.Low)
8115 {
8116 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8117 }
8118 else
8119 {
8120 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8121 }
8122 res.Add(new LSL_Integer(shiny));
8123 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8124 }
7728 break; 8125 break;
7729 8126
7730 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8127 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7731 // TODO--------------
7732 if (remain < 1) 8128 if (remain < 1)
7733 return res; 8129 return res;
8130 face = (int)rules.GetLSLIntegerItem(idx++);
7734 8131
7735 face=(int)rules.GetLSLIntegerItem(idx++); 8132 tex = part.Shape.Textures;
7736 8133 int fullbright;
7737 res.Add(new LSL_Integer(0)); 8134 if (face == ScriptBaseClass.ALL_SIDES)
8135 {
8136 for (face = 0; face < GetNumberOfSides(part); face++)
8137 {
8138 if (tex.GetFace((uint)face).Fullbright == true)
8139 {
8140 fullbright = ScriptBaseClass.TRUE;
8141 }
8142 else
8143 {
8144 fullbright = ScriptBaseClass.FALSE;
8145 }
8146 res.Add(new LSL_Integer(fullbright));
8147 }
8148 }
8149 else
8150 {
8151 if (tex.GetFace((uint)face).Fullbright == true)
8152 {
8153 fullbright = ScriptBaseClass.TRUE;
8154 }
8155 else
8156 {
8157 fullbright = ScriptBaseClass.FALSE;
8158 }
8159 res.Add(new LSL_Integer(fullbright));
8160 }
7738 break; 8161 break;
7739 8162
7740 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8163 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7755,14 +8178,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7755 break; 8178 break;
7756 8179
7757 case (int)ScriptBaseClass.PRIM_TEXGEN: 8180 case (int)ScriptBaseClass.PRIM_TEXGEN:
7758 // TODO--------------
7759 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8181 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7760 if (remain < 1) 8182 if (remain < 1)
7761 return res; 8183 return res;
8184 face = (int)rules.GetLSLIntegerItem(idx++);
7762 8185
7763 face=(int)rules.GetLSLIntegerItem(idx++); 8186 tex = part.Shape.Textures;
7764 8187 if (face == ScriptBaseClass.ALL_SIDES)
7765 res.Add(new LSL_Integer(0)); 8188 {
8189 for (face = 0; face < GetNumberOfSides(part); face++)
8190 {
8191 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8192 {
8193 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8194 }
8195 else
8196 {
8197 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8198 }
8199 }
8200 }
8201 else
8202 {
8203 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8204 {
8205 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8206 }
8207 else
8208 {
8209 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8210 }
8211 }
7766 break; 8212 break;
7767 8213
7768 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8214 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7781,13 +8227,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7781 break; 8227 break;
7782 8228
7783 case (int)ScriptBaseClass.PRIM_GLOW: 8229 case (int)ScriptBaseClass.PRIM_GLOW:
7784 // TODO--------------
7785 if (remain < 1) 8230 if (remain < 1)
7786 return res; 8231 return res;
8232 face = (int)rules.GetLSLIntegerItem(idx++);
7787 8233
7788 face=(int)rules.GetLSLIntegerItem(idx++); 8234 tex = part.Shape.Textures;
7789 8235 float primglow;
7790 res.Add(new LSL_Float(0)); 8236 if (face == ScriptBaseClass.ALL_SIDES)
8237 {
8238 for (face = 0; face < GetNumberOfSides(part); face++)
8239 {
8240 primglow = tex.GetFace((uint)face).Glow;
8241 res.Add(new LSL_Float(primglow));
8242 }
8243 }
8244 else
8245 {
8246 primglow = tex.GetFace((uint)face).Glow;
8247 res.Add(new LSL_Float(primglow));
8248 }
7791 break; 8249 break;
7792 case (int)ScriptBaseClass.PRIM_TEXT: 8250 case (int)ScriptBaseClass.PRIM_TEXT:
7793 Color4 textColor = part.GetTextColor(); 8251 Color4 textColor = part.GetTextColor();
@@ -8093,8 +8551,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8093 // The function returns an ordered list 8551 // The function returns an ordered list
8094 // representing the tokens found in the supplied 8552 // representing the tokens found in the supplied
8095 // sources string. If two successive tokenizers 8553 // sources string. If two successive tokenizers
8096 // are encountered, then a NULL entry is added 8554 // are encountered, then a null-string entry is
8097 // to the list. 8555 // added to the list.
8098 // 8556 //
8099 // It is a precondition that the source and 8557 // It is a precondition that the source and
8100 // toekizer lisst are non-null. If they are null, 8558 // toekizer lisst are non-null. If they are null,
@@ -8102,7 +8560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8102 // while their lengths are being determined. 8560 // while their lengths are being determined.
8103 // 8561 //
8104 // A small amount of working memoryis required 8562 // A small amount of working memoryis required
8105 // of approximately 8*#tokenizers. 8563 // of approximately 8*#tokenizers + 8*srcstrlen.
8106 // 8564 //
8107 // There are many ways in which this function 8565 // There are many ways in which this function
8108 // can be implemented, this implementation is 8566 // can be implemented, this implementation is
@@ -8118,136 +8576,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8118 // and eliminates redundant tokenizers as soon 8576 // and eliminates redundant tokenizers as soon
8119 // as is possible. 8577 // as is possible.
8120 // 8578 //
8121 // The implementation tries to avoid any copying 8579 // The implementation tries to minimize temporary
8122 // of arrays or other objects. 8580 // garbage generation.
8123 // </remarks> 8581 // </remarks>
8124 8582
8125 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8583 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8126 { 8584 {
8127 int beginning = 0; 8585 return ParseString2List(src, separators, spacers, true);
8128 int srclen = src.Length; 8586 }
8129 int seplen = separators.Length;
8130 object[] separray = separators.Data;
8131 int spclen = spacers.Length;
8132 object[] spcarray = spacers.Data;
8133 int mlen = seplen+spclen;
8134
8135 int[] offset = new int[mlen+1];
8136 bool[] active = new bool[mlen];
8137 8587
8138 int best; 8588 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8139 int j; 8589 {
8590 int srclen = src.Length;
8591 int seplen = separators.Length;
8592 object[] separray = separators.Data;
8593 int spclen = spacers.Length;
8594 object[] spcarray = spacers.Data;
8595 int dellen = 0;
8596 string[] delarray = new string[seplen+spclen];
8140 8597
8141 // Initial capacity reduces resize cost 8598 int outlen = 0;
8599 string[] outarray = new string[srclen*2+1];
8142 8600
8143 LSL_List tokens = new LSL_List(); 8601 int i, j;
8602 string d;
8144 8603
8145 m_host.AddScriptLPS(1); 8604 m_host.AddScriptLPS(1);
8146 8605
8147 // All entries are initially valid 8606 /*
8148 8607 * Convert separator and spacer lists to C# strings.
8149 for (int i = 0; i < mlen; i++) 8608 * Also filter out null strings so we don't hang.
8150 active[i] = true; 8609 */
8151 8610 for (i = 0; i < seplen; i ++) {
8152 offset[mlen] = srclen; 8611 d = separray[i].ToString();
8153 8612 if (d.Length > 0) {
8154 while (beginning < srclen) 8613 delarray[dellen++] = d;
8155 { 8614 }
8156 8615 }
8157 best = mlen; // as bad as it gets 8616 seplen = dellen;
8158
8159 // Scan for separators
8160 8617
8161 for (j = 0; j < seplen; j++) 8618 for (i = 0; i < spclen; i ++) {
8162 { 8619 d = spcarray[i].ToString();
8163 if (active[j]) 8620 if (d.Length > 0) {
8164 { 8621 delarray[dellen++] = d;
8165 // scan all of the markers
8166 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8167 {
8168 // not present at all
8169 active[j] = false;
8170 }
8171 else
8172 {
8173 // present and correct
8174 if (offset[j] < offset[best])
8175 {
8176 // closest so far
8177 best = j;
8178 if (offset[best] == beginning)
8179 break;
8180 }
8181 }
8182 }
8183 } 8622 }
8623 }
8184 8624
8185 // Scan for spacers 8625 /*
8626 * Scan through source string from beginning to end.
8627 */
8628 for (i = 0;;) {
8186 8629
8187 if (offset[best] != beginning) 8630 /*
8188 { 8631 * Find earliest delimeter in src starting at i (if any).
8189 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8632 */
8190 { 8633 int earliestDel = -1;
8191 if (active[j]) 8634 int earliestSrc = srclen;
8192 { 8635 string earliestStr = null;
8193 // scan all of the markers 8636 for (j = 0; j < dellen; j ++) {
8194 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8637 d = delarray[j];
8195 { 8638 if (d != null) {
8196 // not present at all 8639 int index = src.IndexOf(d, i);
8197 active[j] = false; 8640 if (index < 0) {
8198 } 8641 delarray[j] = null; // delim nowhere in src, don't check it anymore
8199 else 8642 } else if (index < earliestSrc) {
8200 { 8643 earliestSrc = index; // where delimeter starts in source string
8201 // present and correct 8644 earliestDel = j; // where delimeter is in delarray[]
8202 if (offset[j] < offset[best]) 8645 earliestStr = d; // the delimeter string from delarray[]
8203 { 8646 if (index == i) break; // can't do any better than found at beg of string
8204 // closest so far
8205 best = j;
8206 }
8207 }
8208 } 8647 }
8209 } 8648 }
8210 } 8649 }
8211 8650
8212 // This is the normal exit from the scanning loop 8651 /*
8213 8652 * Output source string starting at i through start of earliest delimeter.
8214 if (best == mlen) 8653 */
8215 { 8654 if (keepNulls || (earliestSrc > i)) {
8216 // no markers were found on this pass 8655 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8217 // so we're pretty much done
8218 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8219 break;
8220 } 8656 }
8221 8657
8222 // Otherwise we just add the newly delimited token 8658 /*
8223 // and recalculate where the search should continue. 8659 * If no delimeter found at or after i, we're done scanning.
8660 */
8661 if (earliestDel < 0) break;
8224 8662
8225 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8663 /*
8226 8664 * If delimeter was a spacer, output the spacer.
8227 if (best < seplen) 8665 */
8228 { 8666 if (earliestDel >= seplen) {
8229 beginning = offset[best] + (separray[best].ToString()).Length; 8667 outarray[outlen++] = earliestStr;
8230 } 8668 }
8231 else
8232 {
8233 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8234 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8235 }
8236 }
8237 8669
8238 // This an awkward an not very intuitive boundary case. If the 8670 /*
8239 // last substring is a tokenizer, then there is an implied trailing 8671 * Look at rest of src string following delimeter.
8240 // null list entry. Hopefully the single comparison will not be too 8672 */
8241 // arduous. Alternatively the 'break' could be replced with a return 8673 i = earliestSrc + earliestStr.Length;
8242 // but that's shabby programming.
8243
8244 if (beginning == srclen)
8245 {
8246 if (srclen != 0)
8247 tokens.Add(new LSL_String(""));
8248 } 8674 }
8249 8675
8250 return tokens; 8676 /*
8677 * Make up an exact-sized output array suitable for an LSL_List object.
8678 */
8679 object[] outlist = new object[outlen];
8680 for (i = 0; i < outlen; i ++) {
8681 outlist[i] = new LSL_String(outarray[i]);
8682 }
8683 return new LSL_List(outlist);
8251 } 8684 }
8252 8685
8253 public LSL_Integer llGetObjectPermMask(int mask) 8686 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8324,28 +8757,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8324 { 8757 {
8325 m_host.AddScriptLPS(1); 8758 m_host.AddScriptLPS(1);
8326 8759
8327 lock (m_host.TaskInventory) 8760 m_host.TaskInventory.LockItemsForRead(true);
8761 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8328 { 8762 {
8329 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8763 if (inv.Value.Name == item)
8330 { 8764 {
8331 if (inv.Value.Name == item) 8765 m_host.TaskInventory.LockItemsForRead(false);
8766 switch (mask)
8332 { 8767 {
8333 switch (mask) 8768 case 0:
8334 { 8769 return (int)inv.Value.BasePermissions;
8335 case 0: 8770 case 1:
8336 return (int)inv.Value.BasePermissions; 8771 return (int)inv.Value.CurrentPermissions;
8337 case 1: 8772 case 2:
8338 return (int)inv.Value.CurrentPermissions; 8773 return (int)inv.Value.GroupPermissions;
8339 case 2: 8774 case 3:
8340 return (int)inv.Value.GroupPermissions; 8775 return (int)inv.Value.EveryonePermissions;
8341 case 3: 8776 case 4:
8342 return (int)inv.Value.EveryonePermissions; 8777 return (int)inv.Value.NextPermissions;
8343 case 4:
8344 return (int)inv.Value.NextPermissions;
8345 }
8346 } 8778 }
8347 } 8779 }
8348 } 8780 }
8781 m_host.TaskInventory.LockItemsForRead(false);
8349 8782
8350 return -1; 8783 return -1;
8351 } 8784 }
@@ -8392,16 +8825,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8392 { 8825 {
8393 m_host.AddScriptLPS(1); 8826 m_host.AddScriptLPS(1);
8394 8827
8395 lock (m_host.TaskInventory) 8828 m_host.TaskInventory.LockItemsForRead(true);
8829 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8396 { 8830 {
8397 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8831 if (inv.Value.Name == item)
8398 { 8832 {
8399 if (inv.Value.Name == item) 8833 m_host.TaskInventory.LockItemsForRead(false);
8400 { 8834 return inv.Value.CreatorID.ToString();
8401 return inv.Value.CreatorID.ToString();
8402 }
8403 } 8835 }
8404 } 8836 }
8837 m_host.TaskInventory.LockItemsForRead(false);
8405 8838
8406 llSay(0, "No item name '" + item + "'"); 8839 llSay(0, "No item name '" + item + "'");
8407 8840
@@ -8661,17 +9094,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8661 int width = 0; 9094 int width = 0;
8662 int height = 0; 9095 int height = 0;
8663 9096
8664 ParcelMediaCommandEnum? commandToSend = null; 9097 uint commandToSend = 0;
8665 float time = 0.0f; // default is from start 9098 float time = 0.0f; // default is from start
8666 9099
8667 ScenePresence presence = null; 9100 ScenePresence presence = null;
8668 9101
8669 for (int i = 0; i < commandList.Data.Length; i++) 9102 for (int i = 0; i < commandList.Data.Length; i++)
8670 { 9103 {
8671 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9104 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8672 switch (command) 9105 switch (command)
8673 { 9106 {
8674 case ParcelMediaCommandEnum.Agent: 9107 case (uint)ParcelMediaCommandEnum.Agent:
8675 // we send only to one agent 9108 // we send only to one agent
8676 if ((i + 1) < commandList.Length) 9109 if ((i + 1) < commandList.Length)
8677 { 9110 {
@@ -8688,25 +9121,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8688 } 9121 }
8689 break; 9122 break;
8690 9123
8691 case ParcelMediaCommandEnum.Loop: 9124 case (uint)ParcelMediaCommandEnum.Loop:
8692 loop = 1; 9125 loop = 1;
8693 commandToSend = command; 9126 commandToSend = command;
8694 update = true; //need to send the media update packet to set looping 9127 update = true; //need to send the media update packet to set looping
8695 break; 9128 break;
8696 9129
8697 case ParcelMediaCommandEnum.Play: 9130 case (uint)ParcelMediaCommandEnum.Play:
8698 loop = 0; 9131 loop = 0;
8699 commandToSend = command; 9132 commandToSend = command;
8700 update = true; //need to send the media update packet to make sure it doesn't loop 9133 update = true; //need to send the media update packet to make sure it doesn't loop
8701 break; 9134 break;
8702 9135
8703 case ParcelMediaCommandEnum.Pause: 9136 case (uint)ParcelMediaCommandEnum.Pause:
8704 case ParcelMediaCommandEnum.Stop: 9137 case (uint)ParcelMediaCommandEnum.Stop:
8705 case ParcelMediaCommandEnum.Unload: 9138 case (uint)ParcelMediaCommandEnum.Unload:
8706 commandToSend = command; 9139 commandToSend = command;
8707 break; 9140 break;
8708 9141
8709 case ParcelMediaCommandEnum.Url: 9142 case (uint)ParcelMediaCommandEnum.Url:
8710 if ((i + 1) < commandList.Length) 9143 if ((i + 1) < commandList.Length)
8711 { 9144 {
8712 if (commandList.Data[i + 1] is LSL_String) 9145 if (commandList.Data[i + 1] is LSL_String)
@@ -8719,7 +9152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8719 } 9152 }
8720 break; 9153 break;
8721 9154
8722 case ParcelMediaCommandEnum.Texture: 9155 case (uint)ParcelMediaCommandEnum.Texture:
8723 if ((i + 1) < commandList.Length) 9156 if ((i + 1) < commandList.Length)
8724 { 9157 {
8725 if (commandList.Data[i + 1] is LSL_String) 9158 if (commandList.Data[i + 1] is LSL_String)
@@ -8732,7 +9165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8732 } 9165 }
8733 break; 9166 break;
8734 9167
8735 case ParcelMediaCommandEnum.Time: 9168 case (uint)ParcelMediaCommandEnum.Time:
8736 if ((i + 1) < commandList.Length) 9169 if ((i + 1) < commandList.Length)
8737 { 9170 {
8738 if (commandList.Data[i + 1] is LSL_Float) 9171 if (commandList.Data[i + 1] is LSL_Float)
@@ -8744,7 +9177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8744 } 9177 }
8745 break; 9178 break;
8746 9179
8747 case ParcelMediaCommandEnum.AutoAlign: 9180 case (uint)ParcelMediaCommandEnum.AutoAlign:
8748 if ((i + 1) < commandList.Length) 9181 if ((i + 1) < commandList.Length)
8749 { 9182 {
8750 if (commandList.Data[i + 1] is LSL_Integer) 9183 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8758,7 +9191,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8758 } 9191 }
8759 break; 9192 break;
8760 9193
8761 case ParcelMediaCommandEnum.Type: 9194 case (uint)ParcelMediaCommandEnum.Type:
8762 if ((i + 1) < commandList.Length) 9195 if ((i + 1) < commandList.Length)
8763 { 9196 {
8764 if (commandList.Data[i + 1] is LSL_String) 9197 if (commandList.Data[i + 1] is LSL_String)
@@ -8771,7 +9204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8771 } 9204 }
8772 break; 9205 break;
8773 9206
8774 case ParcelMediaCommandEnum.Desc: 9207 case (uint)ParcelMediaCommandEnum.Desc:
8775 if ((i + 1) < commandList.Length) 9208 if ((i + 1) < commandList.Length)
8776 { 9209 {
8777 if (commandList.Data[i + 1] is LSL_String) 9210 if (commandList.Data[i + 1] is LSL_String)
@@ -8784,7 +9217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8784 } 9217 }
8785 break; 9218 break;
8786 9219
8787 case ParcelMediaCommandEnum.Size: 9220 case (uint)ParcelMediaCommandEnum.Size:
8788 if ((i + 2) < commandList.Length) 9221 if ((i + 2) < commandList.Length)
8789 { 9222 {
8790 if (commandList.Data[i + 1] is LSL_Integer) 9223 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8854,7 +9287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8854 } 9287 }
8855 } 9288 }
8856 9289
8857 if (commandToSend != null) 9290 if (commandToSend != 0)
8858 { 9291 {
8859 // the commandList contained a start/stop/... command, too 9292 // the commandList contained a start/stop/... command, too
8860 if (presence == null) 9293 if (presence == null)
@@ -8891,7 +9324,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8891 9324
8892 if (aList.Data[i] != null) 9325 if (aList.Data[i] != null)
8893 { 9326 {
8894 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9327 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
8895 { 9328 {
8896 case ParcelMediaCommandEnum.Url: 9329 case ParcelMediaCommandEnum.Url:
8897 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9330 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -8934,16 +9367,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8934 { 9367 {
8935 m_host.AddScriptLPS(1); 9368 m_host.AddScriptLPS(1);
8936 9369
8937 lock (m_host.TaskInventory) 9370 m_host.TaskInventory.LockItemsForRead(true);
9371 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8938 { 9372 {
8939 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9373 if (inv.Value.Name == name)
8940 { 9374 {
8941 if (inv.Value.Name == name) 9375 m_host.TaskInventory.LockItemsForRead(false);
8942 { 9376 return inv.Value.Type;
8943 return inv.Value.Type;
8944 }
8945 } 9377 }
8946 } 9378 }
9379 m_host.TaskInventory.LockItemsForRead(false);
8947 9380
8948 return -1; 9381 return -1;
8949 } 9382 }
@@ -8954,15 +9387,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8954 9387
8955 if (quick_pay_buttons.Data.Length < 4) 9388 if (quick_pay_buttons.Data.Length < 4)
8956 { 9389 {
8957 LSLError("List must have at least 4 elements"); 9390 int x;
8958 return; 9391 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9392 {
9393 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9394 }
8959 } 9395 }
8960 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9396 int[] nPrice = new int[5];
8961 9397 nPrice[0]=price;
8962 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9398 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8963 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9399 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8964 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9400 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8965 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9401 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9402 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8966 m_host.ParentGroup.HasGroupChanged = true; 9403 m_host.ParentGroup.HasGroupChanged = true;
8967 } 9404 }
8968 9405
@@ -8974,17 +9411,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8974 if (invItemID == UUID.Zero) 9411 if (invItemID == UUID.Zero)
8975 return new LSL_Vector(); 9412 return new LSL_Vector();
8976 9413
8977 lock (m_host.TaskInventory) 9414 m_host.TaskInventory.LockItemsForRead(true);
9415 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8978 { 9416 {
8979 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9417 m_host.TaskInventory.LockItemsForRead(false);
8980 return new LSL_Vector(); 9418 return new LSL_Vector();
9419 }
8981 9420
8982 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9421 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8983 { 9422 {
8984 ShoutError("No permissions to track the camera"); 9423 ShoutError("No permissions to track the camera");
8985 return new LSL_Vector(); 9424 m_host.TaskInventory.LockItemsForRead(false);
8986 } 9425 return new LSL_Vector();
8987 } 9426 }
9427 m_host.TaskInventory.LockItemsForRead(false);
8988 9428
8989 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9429 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8990 if (presence != null) 9430 if (presence != null)
@@ -9002,17 +9442,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9002 if (invItemID == UUID.Zero) 9442 if (invItemID == UUID.Zero)
9003 return new LSL_Rotation(); 9443 return new LSL_Rotation();
9004 9444
9005 lock (m_host.TaskInventory) 9445 m_host.TaskInventory.LockItemsForRead(true);
9446 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9006 { 9447 {
9007 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9448 m_host.TaskInventory.LockItemsForRead(false);
9008 return new LSL_Rotation(); 9449 return new LSL_Rotation();
9009 9450 }
9010 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9451 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9011 { 9452 {
9012 ShoutError("No permissions to track the camera"); 9453 ShoutError("No permissions to track the camera");
9013 return new LSL_Rotation(); 9454 m_host.TaskInventory.LockItemsForRead(false);
9014 } 9455 return new LSL_Rotation();
9015 } 9456 }
9457 m_host.TaskInventory.LockItemsForRead(false);
9016 9458
9017 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9459 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9018 if (presence != null) 9460 if (presence != null)
@@ -9074,8 +9516,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9074 { 9516 {
9075 m_host.AddScriptLPS(1); 9517 m_host.AddScriptLPS(1);
9076 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9518 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9077 if (detectedParams == null) return; // only works on the first detected avatar 9519 if (detectedParams == null)
9078 9520 {
9521 if (m_host.IsAttachment == true)
9522 {
9523 detectedParams = new DetectParams();
9524 detectedParams.Key = m_host.OwnerID;
9525 }
9526 else
9527 {
9528 return;
9529 }
9530 }
9531
9079 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9532 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9080 if (avatar != null) 9533 if (avatar != null)
9081 { 9534 {
@@ -9083,6 +9536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9083 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9536 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9084 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9537 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9085 } 9538 }
9539
9086 ScriptSleep(1000); 9540 ScriptSleep(1000);
9087 } 9541 }
9088 9542
@@ -9162,14 +9616,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9162 if (objectID == UUID.Zero) return; 9616 if (objectID == UUID.Zero) return;
9163 9617
9164 UUID agentID; 9618 UUID agentID;
9165 lock (m_host.TaskInventory) 9619 m_host.TaskInventory.LockItemsForRead(true);
9166 { 9620 // we need the permission first, to know which avatar we want to set the camera for
9167 // we need the permission first, to know which avatar we want to set the camera for 9621 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9168 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9169 9622
9170 if (agentID == UUID.Zero) return; 9623 if (agentID == UUID.Zero)
9171 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9624 {
9625 m_host.TaskInventory.LockItemsForRead(false);
9626 return;
9627 }
9628 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9629 {
9630 m_host.TaskInventory.LockItemsForRead(false);
9631 return;
9172 } 9632 }
9633 m_host.TaskInventory.LockItemsForRead(false);
9173 9634
9174 ScenePresence presence = World.GetScenePresence(agentID); 9635 ScenePresence presence = World.GetScenePresence(agentID);
9175 9636
@@ -9219,12 +9680,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9219 9680
9220 // we need the permission first, to know which avatar we want to clear the camera for 9681 // we need the permission first, to know which avatar we want to clear the camera for
9221 UUID agentID; 9682 UUID agentID;
9222 lock (m_host.TaskInventory) 9683 m_host.TaskInventory.LockItemsForRead(true);
9684 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9685 if (agentID == UUID.Zero)
9686 {
9687 m_host.TaskInventory.LockItemsForRead(false);
9688 return;
9689 }
9690 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9223 { 9691 {
9224 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9692 m_host.TaskInventory.LockItemsForRead(false);
9225 if (agentID == UUID.Zero) return; 9693 return;
9226 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9227 } 9694 }
9695 m_host.TaskInventory.LockItemsForRead(false);
9228 9696
9229 ScenePresence presence = World.GetScenePresence(agentID); 9697 ScenePresence presence = World.GetScenePresence(agentID);
9230 9698
@@ -9291,19 +9759,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9291 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 9759 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9292 { 9760 {
9293 m_host.AddScriptLPS(1); 9761 m_host.AddScriptLPS(1);
9294 string ret = String.Empty; 9762
9295 string src1 = llBase64ToString(str1); 9763 if (str1 == String.Empty)
9296 string src2 = llBase64ToString(str2); 9764 return String.Empty;
9297 int c = 0; 9765 if (str2 == String.Empty)
9298 for (int i = 0; i < src1.Length; i++) 9766 return str1;
9767
9768 byte[] data1 = Convert.FromBase64String(str1);
9769 byte[] data2 = Convert.FromBase64String(str2);
9770
9771 byte[] d2 = new Byte[data1.Length];
9772 int pos = 0;
9773
9774 if (data1.Length <= data2.Length)
9299 { 9775 {
9300 ret += (char) (src1[i] ^ src2[c]); 9776 Array.Copy(data2, 0, d2, 0, data1.Length);
9777 }
9778 else
9779 {
9780 while (pos < data1.Length)
9781 {
9782 int len = data1.Length - pos;
9783 if (len > data2.Length)
9784 len = data2.Length;
9301 9785
9302 c++; 9786 Array.Copy(data2, 0, d2, pos, len);
9303 if (c >= src2.Length) 9787 pos += len;
9304 c = 0; 9788 }
9305 } 9789 }
9306 return llStringToBase64(ret); 9790
9791 for (pos = 0 ; pos < data1.Length ; pos++ )
9792 data1[pos] ^= d2[pos];
9793
9794 return Convert.ToBase64String(data1);
9307 } 9795 }
9308 9796
9309 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 9797 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9681,15 +10169,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9681 10169
9682 internal UUID ScriptByName(string name) 10170 internal UUID ScriptByName(string name)
9683 { 10171 {
9684 lock (m_host.TaskInventory) 10172 m_host.TaskInventory.LockItemsForRead(true);
10173
10174 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9685 { 10175 {
9686 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10176 if (item.Type == 10 && item.Name == name)
9687 { 10177 {
9688 if (item.Type == 10 && item.Name == name) 10178 m_host.TaskInventory.LockItemsForRead(false);
9689 return item.ItemID; 10179 return item.ItemID;
9690 } 10180 }
9691 } 10181 }
9692 10182
10183 m_host.TaskInventory.LockItemsForRead(false);
10184
9693 return UUID.Zero; 10185 return UUID.Zero;
9694 } 10186 }
9695 10187
@@ -9730,6 +10222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9730 { 10222 {
9731 m_host.AddScriptLPS(1); 10223 m_host.AddScriptLPS(1);
9732 10224
10225 //Clone is thread safe
9733 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10226 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9734 10227
9735 UUID assetID = UUID.Zero; 10228 UUID assetID = UUID.Zero;
@@ -9792,6 +10285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9792 { 10285 {
9793 m_host.AddScriptLPS(1); 10286 m_host.AddScriptLPS(1);
9794 10287
10288 //Clone is thread safe
9795 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10289 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9796 10290
9797 UUID assetID = UUID.Zero; 10291 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 {