aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1297
-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.cs422
13 files changed, 1297 insertions, 579 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 1feb153..7d7320d 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;
@@ -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
@@ -485,25 +553,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
485 return remainder; 553 return remainder;
486 } 554 }
487 555
488 // Old implementation of llRot2Euler, now normalized 556 public LSL_Vector llRot2Euler(LSL_Rotation q1)
489
490 public LSL_Vector llRot2Euler(LSL_Rotation r)
491 { 557 {
492 m_host.AddScriptLPS(1); 558 m_host.AddScriptLPS(1);
493 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 559 LSL_Vector eul = new LSL_Vector();
494 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 560
495 double m = (t.x + t.y + t.z + t.s); 561 double sqw = q1.s*q1.s;
496 if (m == 0) return new LSL_Vector(); 562 double sqx = q1.x*q1.x;
497 double n = 2 * (r.y * r.s + r.x * r.z); 563 double sqy = q1.z*q1.z;
498 double p = m * m - n * n; 564 double sqz = q1.y*q1.y;
499 if (p > 0) 565 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
500 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))), 566 double test = q1.x*q1.z + q1.y*q1.s;
501 NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), 567 if (test > 0.4999*unit) { // singularity at north pole
502 NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); 568 eul.z = 2 * Math.Atan2(q1.x,q1.s);
503 else if (n > 0) 569 eul.y = Math.PI/2;
504 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))); 570 eul.x = 0;
505 else 571 return eul;
506 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))); 572 }
573 if (test < -0.4999*unit) { // singularity at south pole
574 eul.z = -2 * Math.Atan2(q1.x,q1.s);
575 eul.y = -Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
580 eul.y = Math.Asin(2*test/unit);
581 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
582 return eul;
507 } 583 }
508 584
509 /* From wiki: 585 /* From wiki:
@@ -705,6 +781,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 781 {
706 //A and B should both be normalized 782 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 783 m_host.AddScriptLPS(1);
784 /* This method is more accurate than the SL one, and thus causes problems
785 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
786
708 double dotProduct = LSL_Vector.Dot(a, b); 787 double dotProduct = LSL_Vector.Dot(a, b);
709 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 788 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
710 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b); 789 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
@@ -721,8 +800,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
721 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 800 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
722 801
723 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w); 802 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
724 } 803 */
725 804
805 // This method mimics the 180 errors found in SL
806 // See www.euclideanspace.com... angleBetween
807 LSL_Vector vec_a = a;
808 LSL_Vector vec_b = b;
809
810 // Eliminate zero length
811 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
812 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
813 if (vec_a_mag < 0.00001 ||
814 vec_b_mag < 0.00001)
815 {
816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
817 }
818
819 // Normalize
820 vec_a = llVecNorm(vec_a);
821 vec_b = llVecNorm(vec_b);
822
823 // Calculate axis and rotation angle
824 LSL_Vector axis = vec_a % vec_b;
825 LSL_Float cos_theta = vec_a * vec_b;
826
827 // Check if parallel
828 if (cos_theta > 0.99999)
829 {
830 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
831 }
832
833 // Check if anti-parallel
834 else if (cos_theta < -0.99999)
835 {
836 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
837 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
838 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
839 }
840 else // other rotation
841 {
842 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
843 axis = llVecNorm(axis);
844 double x, y, z, s, t;
845 s = Math.Cos(theta);
846 t = Math.Sin(theta);
847 x = axis.x * t;
848 y = axis.y * t;
849 z = axis.z * t;
850 return new LSL_Rotation(x,y,z,s);
851 }
852 }
853
726 public void llWhisper(int channelID, string text) 854 public void llWhisper(int channelID, string text)
727 { 855 {
728 m_host.AddScriptLPS(1); 856 m_host.AddScriptLPS(1);
@@ -1046,10 +1174,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1046 return detectedParams.TouchUV; 1174 return detectedParams.TouchUV;
1047 } 1175 }
1048 1176
1177 [DebuggerNonUserCode]
1049 public virtual void llDie() 1178 public virtual void llDie()
1050 { 1179 {
1051 m_host.AddScriptLPS(1); 1180 m_host.AddScriptLPS(1);
1052 throw new SelfDeleteException(); 1181 if (!m_host.IsAttachment) throw new SelfDeleteException();
1053 } 1182 }
1054 1183
1055 public LSL_Float llGround(LSL_Vector offset) 1184 public LSL_Float llGround(LSL_Vector offset)
@@ -1122,6 +1251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1122 1251
1123 public void llSetStatus(int status, int value) 1252 public void llSetStatus(int status, int value)
1124 { 1253 {
1254 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1255 return;
1125 m_host.AddScriptLPS(1); 1256 m_host.AddScriptLPS(1);
1126 1257
1127 int statusrotationaxis = 0; 1258 int statusrotationaxis = 0;
@@ -1351,6 +1482,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1351 { 1482 {
1352 m_host.AddScriptLPS(1); 1483 m_host.AddScriptLPS(1);
1353 1484
1485 SetColor(m_host, color, face);
1486 }
1487
1488 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1489 {
1490 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1491 return;
1492
1493 Primitive.TextureEntry tex = part.Shape.Textures;
1494 Color4 texcolor;
1495 if (face >= 0 && face < GetNumberOfSides(part))
1496 {
1497 texcolor = tex.CreateFace((uint)face).RGBA;
1498 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1499 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1500 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1501 tex.FaceTextures[face].RGBA = texcolor;
1502 part.UpdateTexture(tex);
1503 return;
1504 }
1505 else if (face == ScriptBaseClass.ALL_SIDES)
1506 {
1507 for (uint i = 0; i < GetNumberOfSides(part); i++)
1508 {
1509 if (tex.FaceTextures[i] != null)
1510 {
1511 texcolor = tex.FaceTextures[i].RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[i].RGBA = texcolor;
1516 }
1517 texcolor = tex.DefaultTexture.RGBA;
1518 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1519 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1520 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1521 tex.DefaultTexture.RGBA = texcolor;
1522 }
1523 part.UpdateTexture(tex);
1524 return;
1525 }
1526
1354 if (face == ScriptBaseClass.ALL_SIDES) 1527 if (face == ScriptBaseClass.ALL_SIDES)
1355 face = SceneObjectPart.ALL_SIDES; 1528 face = SceneObjectPart.ALL_SIDES;
1356 1529
@@ -1359,6 +1532,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1359 1532
1360 public void SetTexGen(SceneObjectPart part, int face,int style) 1533 public void SetTexGen(SceneObjectPart part, int face,int style)
1361 { 1534 {
1535 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1536 return;
1537
1362 Primitive.TextureEntry tex = part.Shape.Textures; 1538 Primitive.TextureEntry tex = part.Shape.Textures;
1363 MappingType textype; 1539 MappingType textype;
1364 textype = MappingType.Default; 1540 textype = MappingType.Default;
@@ -1389,6 +1565,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1389 1565
1390 public void SetGlow(SceneObjectPart part, int face, float glow) 1566 public void SetGlow(SceneObjectPart part, int face, float glow)
1391 { 1567 {
1568 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1569 return;
1570
1392 Primitive.TextureEntry tex = part.Shape.Textures; 1571 Primitive.TextureEntry tex = part.Shape.Textures;
1393 if (face >= 0 && face < GetNumberOfSides(part)) 1572 if (face >= 0 && face < GetNumberOfSides(part))
1394 { 1573 {
@@ -1414,6 +1593,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1593
1415 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1594 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1416 { 1595 {
1596 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1597 return;
1417 1598
1418 Shininess sval = new Shininess(); 1599 Shininess sval = new Shininess();
1419 1600
@@ -1464,6 +1645,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1464 1645
1465 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1646 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1466 { 1647 {
1648 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return;
1650
1467 Primitive.TextureEntry tex = part.Shape.Textures; 1651 Primitive.TextureEntry tex = part.Shape.Textures;
1468 if (face >= 0 && face < GetNumberOfSides(part)) 1652 if (face >= 0 && face < GetNumberOfSides(part))
1469 { 1653 {
@@ -1524,13 +1708,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1524 m_host.AddScriptLPS(1); 1708 m_host.AddScriptLPS(1);
1525 1709
1526 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1710 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1527 1711 if (parts.Count > 0)
1528 foreach (SceneObjectPart part in parts) 1712 {
1529 SetAlpha(part, alpha, face); 1713 try
1714 {
1715 parts[0].ParentGroup.areUpdatesSuspended = true;
1716 foreach (SceneObjectPart part in parts)
1717 SetAlpha(part, alpha, face);
1718 }
1719 finally
1720 {
1721 parts[0].ParentGroup.areUpdatesSuspended = false;
1722 }
1723 }
1530 } 1724 }
1531 1725
1532 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1726 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1533 { 1727 {
1728 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1729 return;
1730
1534 Primitive.TextureEntry tex = part.Shape.Textures; 1731 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor; 1732 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part)) 1733 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1576,7 +1773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1576 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1577 float wind, float tension, LSL_Vector Force) 1774 float wind, float tension, LSL_Vector Force)
1578 { 1775 {
1579 if (part == null) 1776 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1580 return; 1777 return;
1581 1778
1582 if (flexi) 1779 if (flexi)
@@ -1611,7 +1808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 /// <param name="falloff"></param> 1808 /// <param name="falloff"></param>
1612 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1809 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1613 { 1810 {
1614 if (part == null) 1811 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1812 return;
1616 1813
1617 if (light) 1814 if (light)
@@ -1688,15 +1885,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1688 m_host.AddScriptLPS(1); 1885 m_host.AddScriptLPS(1);
1689 1886
1690 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1887 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1691 1888 if (parts.Count > 0)
1692 foreach (SceneObjectPart part in parts) 1889 {
1693 SetTexture(part, texture, face); 1890 try
1694 1891 {
1892 parts[0].ParentGroup.areUpdatesSuspended = true;
1893 foreach (SceneObjectPart part in parts)
1894 SetTexture(part, texture, face);
1895 }
1896 finally
1897 {
1898 parts[0].ParentGroup.areUpdatesSuspended = false;
1899 }
1900 }
1695 ScriptSleep(200); 1901 ScriptSleep(200);
1696 } 1902 }
1697 1903
1698 protected void SetTexture(SceneObjectPart part, string texture, int face) 1904 protected void SetTexture(SceneObjectPart part, string texture, int face)
1699 { 1905 {
1906 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1907 return;
1908
1700 UUID textureID=new UUID(); 1909 UUID textureID=new UUID();
1701 1910
1702 if (!UUID.TryParse(texture, out textureID)) 1911 if (!UUID.TryParse(texture, out textureID))
@@ -1742,6 +1951,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1742 1951
1743 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1952 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1744 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1745 Primitive.TextureEntry tex = part.Shape.Textures; 1957 Primitive.TextureEntry tex = part.Shape.Textures;
1746 if (face >= 0 && face < GetNumberOfSides(part)) 1958 if (face >= 0 && face < GetNumberOfSides(part))
1747 { 1959 {
@@ -1778,6 +1990,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1778 1990
1779 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1991 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1780 { 1992 {
1993 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1994 return;
1995
1781 Primitive.TextureEntry tex = part.Shape.Textures; 1996 Primitive.TextureEntry tex = part.Shape.Textures;
1782 if (face >= 0 && face < GetNumberOfSides(part)) 1997 if (face >= 0 && face < GetNumberOfSides(part))
1783 { 1998 {
@@ -1814,6 +2029,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 2029
1815 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2030 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1816 { 2031 {
2032 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2033 return;
2034
1817 Primitive.TextureEntry tex = part.Shape.Textures; 2035 Primitive.TextureEntry tex = part.Shape.Textures;
1818 if (face >= 0 && face < GetNumberOfSides(part)) 2036 if (face >= 0 && face < GetNumberOfSides(part))
1819 { 2037 {
@@ -1884,6 +2102,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1884 2102
1885 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2103 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1886 { 2104 {
2105 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2106 return;
2107
1887 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2108 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1888 LSL_Vector currentPos = llGetLocalPos(); 2109 LSL_Vector currentPos = llGetLocalPos();
1889 2110
@@ -1970,6 +2191,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1970 2191
1971 protected void SetRot(SceneObjectPart part, Quaternion rot) 2192 protected void SetRot(SceneObjectPart part, Quaternion rot)
1972 { 2193 {
2194 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2195 return;
2196
1973 part.UpdateRotation(rot); 2197 part.UpdateRotation(rot);
1974 // Update rotation does not move the object in the physics scene if it's a linkset. 2198 // Update rotation does not move the object in the physics scene if it's a linkset.
1975 2199
@@ -2589,12 +2813,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2589 2813
2590 m_host.AddScriptLPS(1); 2814 m_host.AddScriptLPS(1);
2591 2815
2816 m_host.TaskInventory.LockItemsForRead(true);
2592 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2817 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2593 2818 m_host.TaskInventory.LockItemsForRead(false);
2594 lock (m_host.TaskInventory)
2595 {
2596 item = m_host.TaskInventory[invItemID];
2597 }
2598 2819
2599 if (item.PermsGranter == UUID.Zero) 2820 if (item.PermsGranter == UUID.Zero)
2600 return 0; 2821 return 0;
@@ -2669,6 +2890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2669 if (dist > m_ScriptDistanceFactor * 10.0f) 2890 if (dist > m_ScriptDistanceFactor * 10.0f)
2670 return; 2891 return;
2671 2892
2893 //Clone is thread-safe
2672 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2894 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2673 2895
2674 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2896 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2731,6 +2953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2731 2953
2732 public void llLookAt(LSL_Vector target, double strength, double damping) 2954 public void llLookAt(LSL_Vector target, double strength, double damping)
2733 { 2955 {
2956 /*
2734 m_host.AddScriptLPS(1); 2957 m_host.AddScriptLPS(1);
2735 // Determine where we are looking from 2958 // Determine where we are looking from
2736 LSL_Vector from = llGetPos(); 2959 LSL_Vector from = llGetPos();
@@ -2750,10 +2973,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2750 // the angles of rotation in radians into rotation value 2973 // the angles of rotation in radians into rotation value
2751 2974
2752 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2975 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2753 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2976
2754 m_host.startLookAt(rotation, (float)damping, (float)strength); 2977 // This would only work if your physics system contains an APID controller:
2978 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2979 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2980
2755 // Orient the object to the angle calculated 2981 // Orient the object to the angle calculated
2756 //llSetRot(rot); 2982 llSetRot(rot);
2983 */
2984
2985 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2986 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2987 // http://bugs.meta7.com/view.php?id=28
2988 // - Tom
2989
2990 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
2991 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
2992
2993 }
2994
2995 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2996 {
2997 m_host.AddScriptLPS(1);
2998// NotImplemented("llRotLookAt");
2999 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3000
2757 } 3001 }
2758 3002
2759 public void llStopLookAt() 3003 public void llStopLookAt()
@@ -2802,13 +3046,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2802 { 3046 {
2803 TaskInventoryItem item; 3047 TaskInventoryItem item;
2804 3048
2805 lock (m_host.TaskInventory) 3049 m_host.TaskInventory.LockItemsForRead(true);
3050 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2806 { 3051 {
2807 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3052 m_host.TaskInventory.LockItemsForRead(false);
2808 return; 3053 return;
2809 else 3054 }
2810 item = m_host.TaskInventory[InventorySelf()]; 3055 else
3056 {
3057 item = m_host.TaskInventory[InventorySelf()];
2811 } 3058 }
3059 m_host.TaskInventory.LockItemsForRead(false);
2812 3060
2813 if (item.PermsGranter != UUID.Zero) 3061 if (item.PermsGranter != UUID.Zero)
2814 { 3062 {
@@ -2830,13 +3078,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2830 { 3078 {
2831 TaskInventoryItem item; 3079 TaskInventoryItem item;
2832 3080
3081 m_host.TaskInventory.LockItemsForRead(true);
2833 lock (m_host.TaskInventory) 3082 lock (m_host.TaskInventory)
2834 { 3083 {
3084
2835 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3085 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3086 {
3087 m_host.TaskInventory.LockItemsForRead(false);
2836 return; 3088 return;
3089 }
2837 else 3090 else
3091 {
2838 item = m_host.TaskInventory[InventorySelf()]; 3092 item = m_host.TaskInventory[InventorySelf()];
3093 }
2839 } 3094 }
3095 m_host.TaskInventory.LockItemsForRead(false);
2840 3096
2841 m_host.AddScriptLPS(1); 3097 m_host.AddScriptLPS(1);
2842 3098
@@ -2868,19 +3124,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2868 { 3124 {
2869 m_host.AddScriptLPS(1); 3125 m_host.AddScriptLPS(1);
2870 3126
2871 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2872 return;
2873
2874 TaskInventoryItem item; 3127 TaskInventoryItem item;
2875 3128
2876 lock (m_host.TaskInventory) 3129 m_host.TaskInventory.LockItemsForRead(true);
3130
3131 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2877 { 3132 {
2878 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3133 m_host.TaskInventory.LockItemsForRead(false);
2879 return; 3134 return;
2880 else 3135 }
2881 item = m_host.TaskInventory[InventorySelf()]; 3136 else
3137 {
3138 item = m_host.TaskInventory[InventorySelf()];
2882 } 3139 }
2883 3140
3141 m_host.TaskInventory.LockItemsForRead(false);
3142
2884 if (item.PermsGranter != m_host.OwnerID) 3143 if (item.PermsGranter != m_host.OwnerID)
2885 return; 3144 return;
2886 3145
@@ -2890,11 +3149,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2890 3149
2891 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3150 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2892 3151
3152 /*
2893 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3153 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2894 if (attachmentsModule != null) 3154 if (attachmentsModule != null)
3155 {
2895 attachmentsModule.AttachObject( 3156 attachmentsModule.AttachObject(
2896 presence.ControllingClient, grp.LocalId, 3157 presence.ControllingClient, grp.LocalId,
2897 (uint)attachment, Quaternion.Identity, Vector3.Zero, false); 3158 (uint)attachment, Quaternion.Identity, Vector3.Zero, false);
3159 }
3160 */
3161 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2898 } 3162 }
2899 } 3163 }
2900 3164
@@ -2907,13 +3171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2907 3171
2908 TaskInventoryItem item; 3172 TaskInventoryItem item;
2909 3173
2910 lock (m_host.TaskInventory) 3174 m_host.TaskInventory.LockItemsForRead(true);
3175
3176 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2911 { 3177 {
2912 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3178 m_host.TaskInventory.LockItemsForRead(false);
2913 return; 3179 return;
2914 else
2915 item = m_host.TaskInventory[InventorySelf()];
2916 } 3180 }
3181 else
3182 {
3183 item = m_host.TaskInventory[InventorySelf()];
3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
3186
2917 3187
2918 if (item.PermsGranter != m_host.OwnerID) 3188 if (item.PermsGranter != m_host.OwnerID)
2919 return; 3189 return;
@@ -2950,8 +3220,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2950 return m_host.OwnerID.ToString(); 3220 return m_host.OwnerID.ToString();
2951 } 3221 }
2952 3222
3223 [DebuggerNonUserCode]
2953 public void llInstantMessage(string user, string message) 3224 public void llInstantMessage(string user, string message)
2954 { 3225 {
3226 UUID result;
3227 if (!UUID.TryParse(user, out result))
3228 {
3229 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3230 return;
3231 }
3232
3233
2955 m_host.AddScriptLPS(1); 3234 m_host.AddScriptLPS(1);
2956 3235
2957 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3236 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2966,7 +3245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2966 UUID friendTransactionID = UUID.Random(); 3245 UUID friendTransactionID = UUID.Random();
2967 3246
2968 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3247 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
2969 3248
2970 GridInstantMessage msg = new GridInstantMessage(); 3249 GridInstantMessage msg = new GridInstantMessage();
2971 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3250 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
2972 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3251 msg.toAgentID = new Guid(user); // toAgentID.Guid;
@@ -3115,13 +3394,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3115 m_host.AddScriptLPS(1); 3394 m_host.AddScriptLPS(1);
3116 } 3395 }
3117 3396
3118 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3119 {
3120 m_host.AddScriptLPS(1);
3121 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3122 m_host.RotLookAt(rot, (float)strength, (float)damping);
3123 }
3124
3125 public LSL_Integer llStringLength(string str) 3397 public LSL_Integer llStringLength(string str)
3126 { 3398 {
3127 m_host.AddScriptLPS(1); 3399 m_host.AddScriptLPS(1);
@@ -3145,14 +3417,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3145 3417
3146 TaskInventoryItem item; 3418 TaskInventoryItem item;
3147 3419
3148 lock (m_host.TaskInventory) 3420 m_host.TaskInventory.LockItemsForRead(true);
3421 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3149 { 3422 {
3150 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3423 m_host.TaskInventory.LockItemsForRead(false);
3151 return; 3424 return;
3152 else
3153 item = m_host.TaskInventory[InventorySelf()];
3154 } 3425 }
3155 3426 else
3427 {
3428 item = m_host.TaskInventory[InventorySelf()];
3429 }
3430 m_host.TaskInventory.LockItemsForRead(false);
3156 if (item.PermsGranter == UUID.Zero) 3431 if (item.PermsGranter == UUID.Zero)
3157 return; 3432 return;
3158 3433
@@ -3182,13 +3457,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3182 3457
3183 TaskInventoryItem item; 3458 TaskInventoryItem item;
3184 3459
3185 lock (m_host.TaskInventory) 3460 m_host.TaskInventory.LockItemsForRead(true);
3461 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3186 { 3462 {
3187 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3463 m_host.TaskInventory.LockItemsForRead(false);
3188 return; 3464 return;
3189 else
3190 item = m_host.TaskInventory[InventorySelf()];
3191 } 3465 }
3466 else
3467 {
3468 item = m_host.TaskInventory[InventorySelf()];
3469 }
3470 m_host.TaskInventory.LockItemsForRead(false);
3471
3192 3472
3193 if (item.PermsGranter == UUID.Zero) 3473 if (item.PermsGranter == UUID.Zero)
3194 return; 3474 return;
@@ -3265,10 +3545,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3265 3545
3266 TaskInventoryItem item; 3546 TaskInventoryItem item;
3267 3547
3268 lock (m_host.TaskInventory) 3548
3549 m_host.TaskInventory.LockItemsForRead(true);
3550 if (!m_host.TaskInventory.ContainsKey(invItemID))
3551 {
3552 m_host.TaskInventory.LockItemsForRead(false);
3553 return;
3554 }
3555 else
3269 { 3556 {
3270 item = m_host.TaskInventory[invItemID]; 3557 item = m_host.TaskInventory[invItemID];
3271 } 3558 }
3559 m_host.TaskInventory.LockItemsForRead(false);
3272 3560
3273 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3561 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3274 { 3562 {
@@ -3300,11 +3588,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3300 3588
3301 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3589 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3302 { 3590 {
3303 lock (m_host.TaskInventory) 3591 m_host.TaskInventory.LockItemsForWrite(true);
3304 { 3592 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3305 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3593 m_host.TaskInventory[invItemID].PermsMask = perm;
3306 m_host.TaskInventory[invItemID].PermsMask = perm; 3594 m_host.TaskInventory.LockItemsForWrite(false);
3307 }
3308 3595
3309 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3596 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3310 "run_time_permissions", new Object[] { 3597 "run_time_permissions", new Object[] {
@@ -3324,11 +3611,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3324 3611
3325 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3612 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3326 { 3613 {
3327 lock (m_host.TaskInventory) 3614 m_host.TaskInventory.LockItemsForWrite(true);
3328 { 3615 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3329 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3616 m_host.TaskInventory[invItemID].PermsMask = perm;
3330 m_host.TaskInventory[invItemID].PermsMask = perm; 3617 m_host.TaskInventory.LockItemsForWrite(false);
3331 }
3332 3618
3333 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3619 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3334 "run_time_permissions", new Object[] { 3620 "run_time_permissions", new Object[] {
@@ -3349,11 +3635,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3349 3635
3350 if (!m_waitingForScriptAnswer) 3636 if (!m_waitingForScriptAnswer)
3351 { 3637 {
3352 lock (m_host.TaskInventory) 3638 m_host.TaskInventory.LockItemsForWrite(true);
3353 { 3639 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3354 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3640 m_host.TaskInventory[invItemID].PermsMask = 0;
3355 m_host.TaskInventory[invItemID].PermsMask = 0; 3641 m_host.TaskInventory.LockItemsForWrite(false);
3356 }
3357 3642
3358 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3643 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3359 m_waitingForScriptAnswer=true; 3644 m_waitingForScriptAnswer=true;
@@ -3388,10 +3673,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3388 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3673 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3389 llReleaseControls(); 3674 llReleaseControls();
3390 3675
3391 lock (m_host.TaskInventory) 3676
3392 { 3677 m_host.TaskInventory.LockItemsForWrite(true);
3393 m_host.TaskInventory[invItemID].PermsMask = answer; 3678 m_host.TaskInventory[invItemID].PermsMask = answer;
3394 } 3679 m_host.TaskInventory.LockItemsForWrite(false);
3680
3395 3681
3396 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3682 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3397 "run_time_permissions", new Object[] { 3683 "run_time_permissions", new Object[] {
@@ -3403,16 +3689,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3403 { 3689 {
3404 m_host.AddScriptLPS(1); 3690 m_host.AddScriptLPS(1);
3405 3691
3406 lock (m_host.TaskInventory) 3692 m_host.TaskInventory.LockItemsForRead(true);
3693
3694 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3407 { 3695 {
3408 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3696 if (item.Type == 10 && item.ItemID == m_itemID)
3409 { 3697 {
3410 if (item.Type == 10 && item.ItemID == m_itemID) 3698 m_host.TaskInventory.LockItemsForRead(false);
3411 { 3699 return item.PermsGranter.ToString();
3412 return item.PermsGranter.ToString();
3413 }
3414 } 3700 }
3415 } 3701 }
3702 m_host.TaskInventory.LockItemsForRead(false);
3416 3703
3417 return UUID.Zero.ToString(); 3704 return UUID.Zero.ToString();
3418 } 3705 }
@@ -3421,19 +3708,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3421 { 3708 {
3422 m_host.AddScriptLPS(1); 3709 m_host.AddScriptLPS(1);
3423 3710
3424 lock (m_host.TaskInventory) 3711 m_host.TaskInventory.LockItemsForRead(true);
3712
3713 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3425 { 3714 {
3426 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3715 if (item.Type == 10 && item.ItemID == m_itemID)
3427 { 3716 {
3428 if (item.Type == 10 && item.ItemID == m_itemID) 3717 int perms = item.PermsMask;
3429 { 3718 if (m_automaticLinkPermission)
3430 int perms = item.PermsMask; 3719 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3431 if (m_automaticLinkPermission) 3720 m_host.TaskInventory.LockItemsForRead(false);
3432 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3721 return perms;
3433 return perms;
3434 }
3435 } 3722 }
3436 } 3723 }
3724 m_host.TaskInventory.LockItemsForRead(false);
3437 3725
3438 return 0; 3726 return 0;
3439 } 3727 }
@@ -3455,9 +3743,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3455 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3743 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3456 { 3744 {
3457 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3745 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3458 3746 if (parts.Count > 0)
3459 foreach (SceneObjectPart part in parts) 3747 {
3460 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3748 try
3749 {
3750 parts[0].ParentGroup.areUpdatesSuspended = true;
3751 foreach (SceneObjectPart part in parts)
3752 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3753 }
3754 finally
3755 {
3756 parts[0].ParentGroup.areUpdatesSuspended = false;
3757 }
3758 }
3461 } 3759 }
3462 3760
3463 public void llCreateLink(string target, int parent) 3761 public void llCreateLink(string target, int parent)
@@ -3466,11 +3764,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3466 UUID invItemID = InventorySelf(); 3764 UUID invItemID = InventorySelf();
3467 3765
3468 TaskInventoryItem item; 3766 TaskInventoryItem item;
3469 lock (m_host.TaskInventory) 3767 m_host.TaskInventory.LockItemsForRead(true);
3470 { 3768 item = m_host.TaskInventory[invItemID];
3471 item = m_host.TaskInventory[invItemID]; 3769 m_host.TaskInventory.LockItemsForRead(false);
3472 } 3770
3473
3474 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3771 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3475 && !m_automaticLinkPermission) 3772 && !m_automaticLinkPermission)
3476 { 3773 {
@@ -3523,16 +3820,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3523 m_host.AddScriptLPS(1); 3820 m_host.AddScriptLPS(1);
3524 UUID invItemID = InventorySelf(); 3821 UUID invItemID = InventorySelf();
3525 3822
3526 lock (m_host.TaskInventory) 3823 m_host.TaskInventory.LockItemsForRead(true);
3527 {
3528 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3824 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3529 && !m_automaticLinkPermission) 3825 && !m_automaticLinkPermission)
3530 { 3826 {
3531 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3827 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3828 m_host.TaskInventory.LockItemsForRead(false);
3532 return; 3829 return;
3533 } 3830 }
3534 } 3831 m_host.TaskInventory.LockItemsForRead(false);
3535 3832
3536 if (linknum < ScriptBaseClass.LINK_THIS) 3833 if (linknum < ScriptBaseClass.LINK_THIS)
3537 return; 3834 return;
3538 3835
@@ -3571,10 +3868,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3571 // Restructuring Multiple Prims. 3868 // Restructuring Multiple Prims.
3572 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3869 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3573 parts.Remove(parentPrim.RootPart); 3870 parts.Remove(parentPrim.RootPart);
3574 foreach (SceneObjectPart part in parts) 3871 if (parts.Count > 0)
3575 { 3872 {
3576 parentPrim.DelinkFromGroup(part.LocalId, true); 3873 try
3874 {
3875 parts[0].ParentGroup.areUpdatesSuspended = true;
3876 foreach (SceneObjectPart part in parts)
3877 {
3878 parentPrim.DelinkFromGroup(part.LocalId, true);
3879 }
3880 }
3881 finally
3882 {
3883 parts[0].ParentGroup.areUpdatesSuspended = false;
3884 }
3577 } 3885 }
3886
3578 parentPrim.HasGroupChanged = true; 3887 parentPrim.HasGroupChanged = true;
3579 parentPrim.ScheduleGroupForFullUpdate(); 3888 parentPrim.ScheduleGroupForFullUpdate();
3580 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3889 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3583,11 +3892,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3583 { 3892 {
3584 SceneObjectPart newRoot = parts[0]; 3893 SceneObjectPart newRoot = parts[0];
3585 parts.Remove(newRoot); 3894 parts.Remove(newRoot);
3586 foreach (SceneObjectPart part in parts) 3895
3896 try
3587 { 3897 {
3588 part.UpdateFlag = 0; 3898 parts[0].ParentGroup.areUpdatesSuspended = true;
3589 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3899 foreach (SceneObjectPart part in parts)
3900 {
3901 part.UpdateFlag = 0;
3902 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3903 }
3590 } 3904 }
3905 finally
3906 {
3907 parts[0].ParentGroup.areUpdatesSuspended = false;
3908 }
3909
3910
3591 newRoot.ParentGroup.HasGroupChanged = true; 3911 newRoot.ParentGroup.HasGroupChanged = true;
3592 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3912 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3593 } 3913 }
@@ -3613,11 +3933,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3613 3933
3614 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3934 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3615 parts.Remove(parentPrim.RootPart); 3935 parts.Remove(parentPrim.RootPart);
3616 3936 if (parts.Count > 0)
3617 foreach (SceneObjectPart part in parts)
3618 { 3937 {
3619 parentPrim.DelinkFromGroup(part.LocalId, true); 3938 try
3620 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3939 {
3940 parts[0].ParentGroup.areUpdatesSuspended = true;
3941 foreach (SceneObjectPart part in parts)
3942 {
3943 parentPrim.DelinkFromGroup(part.LocalId, true);
3944 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3945 }
3946 }
3947 finally
3948 {
3949 parts[0].ParentGroup.areUpdatesSuspended = false;
3950 }
3621 } 3951 }
3622 parentPrim.HasGroupChanged = true; 3952 parentPrim.HasGroupChanged = true;
3623 parentPrim.ScheduleGroupForFullUpdate(); 3953 parentPrim.ScheduleGroupForFullUpdate();
@@ -3709,17 +4039,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3709 m_host.AddScriptLPS(1); 4039 m_host.AddScriptLPS(1);
3710 int count = 0; 4040 int count = 0;
3711 4041
3712 lock (m_host.TaskInventory) 4042 m_host.TaskInventory.LockItemsForRead(true);
4043 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3713 { 4044 {
3714 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4045 if (inv.Value.Type == type || type == -1)
3715 { 4046 {
3716 if (inv.Value.Type == type || type == -1) 4047 count = count + 1;
3717 {
3718 count = count + 1;
3719 }
3720 } 4048 }
3721 } 4049 }
3722 4050
4051 m_host.TaskInventory.LockItemsForRead(false);
3723 return count; 4052 return count;
3724 } 4053 }
3725 4054
@@ -3728,16 +4057,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3728 m_host.AddScriptLPS(1); 4057 m_host.AddScriptLPS(1);
3729 ArrayList keys = new ArrayList(); 4058 ArrayList keys = new ArrayList();
3730 4059
3731 lock (m_host.TaskInventory) 4060 m_host.TaskInventory.LockItemsForRead(true);
4061 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3732 { 4062 {
3733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4063 if (inv.Value.Type == type || type == -1)
3734 { 4064 {
3735 if (inv.Value.Type == type || type == -1) 4065 keys.Add(inv.Value.Name);
3736 {
3737 keys.Add(inv.Value.Name);
3738 }
3739 } 4066 }
3740 } 4067 }
4068 m_host.TaskInventory.LockItemsForRead(false);
3741 4069
3742 if (keys.Count == 0) 4070 if (keys.Count == 0)
3743 { 4071 {
@@ -3774,20 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 } 4102 }
3775 4103
3776 // move the first object found with this inventory name 4104 // move the first object found with this inventory name
3777 lock (m_host.TaskInventory) 4105 m_host.TaskInventory.LockItemsForRead(true);
4106 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3778 { 4107 {
3779 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4108 if (inv.Value.Name == inventory)
3780 { 4109 {
3781 if (inv.Value.Name == inventory) 4110 found = true;
3782 { 4111 objId = inv.Key;
3783 found = true; 4112 assetType = inv.Value.Type;
3784 objId = inv.Key; 4113 objName = inv.Value.Name;
3785 assetType = inv.Value.Type; 4114 break;
3786 objName = inv.Value.Name;
3787 break;
3788 }
3789 } 4115 }
3790 } 4116 }
4117 m_host.TaskInventory.LockItemsForRead(false);
3791 4118
3792 if (!found) 4119 if (!found)
3793 { 4120 {
@@ -3795,9 +4122,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3795 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4122 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3796 } 4123 }
3797 4124
3798 // check if destination is an avatar 4125 // check if destination is an object
3799 if (World.GetScenePresence(destId) != null) 4126 if (World.GetSceneObjectPart(destId) != null)
3800 { 4127 {
4128 // destination is an object
4129 World.MoveTaskInventoryItem(destId, m_host, objId);
4130 }
4131 else
4132 {
4133 ScenePresence presence = World.GetScenePresence(destId);
4134
4135 if (presence == null)
4136 {
4137 UserAccount account =
4138 World.UserAccountService.GetUserAccount(
4139 World.RegionInfo.ScopeID,
4140 destId);
4141
4142 if (account == null)
4143 {
4144 llSay(0, "Can't find destination "+destId.ToString());
4145 return;
4146 }
4147 }
4148
3801 // destination is an avatar 4149 // destination is an avatar
3802 InventoryItemBase agentItem = 4150 InventoryItemBase agentItem =
3803 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4151 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3823,33 +4171,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3823 4171
3824 if (m_TransferModule != null) 4172 if (m_TransferModule != null)
3825 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4173 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4174
4175 //This delay should only occur when giving inventory to avatars.
4176 ScriptSleep(3000);
3826 } 4177 }
3827 else
3828 {
3829 // destination is an object
3830 World.MoveTaskInventoryItem(destId, m_host, objId);
3831 }
3832 ScriptSleep(3000);
3833 } 4178 }
3834 4179
4180 [DebuggerNonUserCode]
3835 public void llRemoveInventory(string name) 4181 public void llRemoveInventory(string name)
3836 { 4182 {
3837 m_host.AddScriptLPS(1); 4183 m_host.AddScriptLPS(1);
3838 4184
3839 lock (m_host.TaskInventory) 4185 m_host.TaskInventory.LockItemsForRead(true);
4186 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3840 { 4187 {
3841 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4188 if (item.Name == name)
3842 { 4189 {
3843 if (item.Name == name) 4190 if (item.ItemID == m_itemID)
3844 { 4191 throw new ScriptDeleteException();
3845 if (item.ItemID == m_itemID) 4192 else
3846 throw new ScriptDeleteException(); 4193 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3847 else 4194
3848 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4195 m_host.TaskInventory.LockItemsForRead(false);
3849 return; 4196 return;
3850 }
3851 } 4197 }
3852 } 4198 }
4199 m_host.TaskInventory.LockItemsForRead(false);
3853 } 4200 }
3854 4201
3855 public void llSetText(string text, LSL_Vector color, double alpha) 4202 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3885,22 +4232,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 UUID uuid = (UUID)id; 4232 UUID uuid = (UUID)id;
3886 4233
3887 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4234 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4235 if (account == null)
4236 return UUID.Zero.ToString();
4237
3888 4238
3889 PresenceInfo pinfo = null; 4239 PresenceInfo pinfo = null;
3890 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4240 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3891 if (pinfos != null && pinfos.Length > 0) 4241 if (pinfos != null && pinfos.Length > 0)
3892 pinfo = pinfos[0]; 4242 pinfo = pinfos[0];
3893 4243
3894 if (pinfo == null)
3895 return UUID.Zero.ToString();
3896
3897 string reply = String.Empty; 4244 string reply = String.Empty;
3898 4245
3899 switch (data) 4246 switch (data)
3900 { 4247 {
3901 case 1: // DATA_ONLINE (0|1) 4248 case 1: // DATA_ONLINE (0|1)
3902 // TODO: implement fetching of this information 4249 if (pinfo != null && pinfo.RegionID != UUID.Zero)
3903 if (pinfo != null)
3904 reply = "1"; 4250 reply = "1";
3905 else 4251 else
3906 reply = "0"; 4252 reply = "0";
@@ -3940,6 +4286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3940 { 4286 {
3941 m_host.AddScriptLPS(1); 4287 m_host.AddScriptLPS(1);
3942 4288
4289 //Clone is thread safe
3943 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4290 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3944 4291
3945 foreach (TaskInventoryItem item in itemDictionary.Values) 4292 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -3993,6 +4340,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3993 ScenePresence presence = World.GetScenePresence(agentId); 4340 ScenePresence presence = World.GetScenePresence(agentId);
3994 if (presence != null) 4341 if (presence != null)
3995 { 4342 {
4343 // agent must not be a god
4344 if (presence.GodLevel >= 200) return;
4345
3996 // agent must be over the owners land 4346 // agent must be over the owners land
3997 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4347 if (m_host.OwnerID == World.LandChannel.GetLandObject(
3998 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4348 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4053,17 +4403,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4053 UUID soundId = UUID.Zero; 4403 UUID soundId = UUID.Zero;
4054 if (!UUID.TryParse(impact_sound, out soundId)) 4404 if (!UUID.TryParse(impact_sound, out soundId))
4055 { 4405 {
4056 lock (m_host.TaskInventory) 4406 m_host.TaskInventory.LockItemsForRead(true);
4407 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4057 { 4408 {
4058 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4409 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4059 { 4410 {
4060 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4411 soundId = item.AssetID;
4061 { 4412 break;
4062 soundId = item.AssetID;
4063 break;
4064 }
4065 } 4413 }
4066 } 4414 }
4415 m_host.TaskInventory.LockItemsForRead(false);
4067 } 4416 }
4068 m_host.CollisionSound = soundId; 4417 m_host.CollisionSound = soundId;
4069 m_host.CollisionSoundVolume = (float)impact_volume; 4418 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4109,6 +4458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4109 UUID partItemID; 4458 UUID partItemID;
4110 foreach (SceneObjectPart part in parts) 4459 foreach (SceneObjectPart part in parts)
4111 { 4460 {
4461 //Clone is thread safe
4112 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4462 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4113 4463
4114 foreach (TaskInventoryItem item in itemsDictionary.Values) 4464 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4323,17 +4673,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4323 4673
4324 m_host.AddScriptLPS(1); 4674 m_host.AddScriptLPS(1);
4325 4675
4326 lock (m_host.TaskInventory) 4676 m_host.TaskInventory.LockItemsForRead(true);
4677 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4327 { 4678 {
4328 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4679 if (item.Type == 10 && item.ItemID == m_itemID)
4329 { 4680 {
4330 if (item.Type == 10 && item.ItemID == m_itemID) 4681 result = item.Name!=null?item.Name:String.Empty;
4331 { 4682 break;
4332 result = item.Name != null ? item.Name : String.Empty;
4333 break;
4334 }
4335 } 4683 }
4336 } 4684 }
4685 m_host.TaskInventory.LockItemsForRead(false);
4337 4686
4338 return result; 4687 return result;
4339 } 4688 }
@@ -4486,23 +4835,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4486 { 4835 {
4487 m_host.AddScriptLPS(1); 4836 m_host.AddScriptLPS(1);
4488 4837
4489 lock (m_host.TaskInventory) 4838 m_host.TaskInventory.LockItemsForRead(true);
4839 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4490 { 4840 {
4491 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4841 if (inv.Value.Name == name)
4492 { 4842 {
4493 if (inv.Value.Name == name) 4843 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4494 { 4844 {
4495 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4845 m_host.TaskInventory.LockItemsForRead(false);
4496 { 4846 return inv.Value.AssetID.ToString();
4497 return inv.Value.AssetID.ToString(); 4847 }
4498 } 4848 else
4499 else 4849 {
4500 { 4850 m_host.TaskInventory.LockItemsForRead(false);
4501 return UUID.Zero.ToString(); 4851 return UUID.Zero.ToString();
4502 }
4503 } 4852 }
4504 } 4853 }
4505 } 4854 }
4855 m_host.TaskInventory.LockItemsForRead(false);
4506 4856
4507 return UUID.Zero.ToString(); 4857 return UUID.Zero.ToString();
4508 } 4858 }
@@ -5438,10 +5788,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5438 m_host.AddScriptLPS(1); 5788 m_host.AddScriptLPS(1);
5439 5789
5440 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5790 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5441 5791 if (parts.Count > 0)
5442 foreach (var part in parts)
5443 { 5792 {
5444 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5793 try
5794 {
5795 parts[0].ParentGroup.areUpdatesSuspended = true;
5796 foreach (var part in parts)
5797 {
5798 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5799 }
5800 }
5801 finally
5802 {
5803 parts[0].ParentGroup.areUpdatesSuspended = false;
5804 }
5445 } 5805 }
5446 } 5806 }
5447 5807
@@ -6020,6 +6380,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6020 tempf = (float)rules.GetLSLFloatItem(i + 1); 6380 tempf = (float)rules.GetLSLFloatItem(i + 1);
6021 prules.OuterAngle = (float)tempf; 6381 prules.OuterAngle = (float)tempf;
6022 break; 6382 break;
6383
6384 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6385 tempf = (float)rules.GetLSLFloatItem(i + 1);
6386 prules.InnerAngle = (float)tempf;
6387 break;
6388
6389 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6390 tempf = (float)rules.GetLSLFloatItem(i + 1);
6391 prules.OuterAngle = (float)tempf;
6392 break;
6023 } 6393 }
6024 6394
6025 } 6395 }
@@ -6058,14 +6428,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6058 6428
6059 protected UUID GetTaskInventoryItem(string name) 6429 protected UUID GetTaskInventoryItem(string name)
6060 { 6430 {
6061 lock (m_host.TaskInventory) 6431 m_host.TaskInventory.LockItemsForRead(true);
6432 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6062 { 6433 {
6063 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6434 if (inv.Value.Name == name)
6064 { 6435 {
6065 if (inv.Value.Name == name) 6436 m_host.TaskInventory.LockItemsForRead(false);
6066 return inv.Key; 6437 return inv.Key;
6067 } 6438 }
6068 } 6439 }
6440 m_host.TaskInventory.LockItemsForRead(false);
6069 6441
6070 return UUID.Zero; 6442 return UUID.Zero;
6071 } 6443 }
@@ -6393,22 +6765,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6393 } 6765 }
6394 6766
6395 // copy the first script found with this inventory name 6767 // copy the first script found with this inventory name
6396 lock (m_host.TaskInventory) 6768 m_host.TaskInventory.LockItemsForRead(true);
6769 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6397 { 6770 {
6398 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6771 if (inv.Value.Name == name)
6399 { 6772 {
6400 if (inv.Value.Name == name) 6773 // make sure the object is a script
6774 if (10 == inv.Value.Type)
6401 { 6775 {
6402 // make sure the object is a script 6776 found = true;
6403 if (10 == inv.Value.Type) 6777 srcId = inv.Key;
6404 { 6778 break;
6405 found = true;
6406 srcId = inv.Key;
6407 break;
6408 }
6409 } 6779 }
6410 } 6780 }
6411 } 6781 }
6782 m_host.TaskInventory.LockItemsForRead(false);
6412 6783
6413 if (!found) 6784 if (!found)
6414 { 6785 {
@@ -6492,6 +6863,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6492 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6863 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6493 { 6864 {
6494 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6865 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6866 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6867 return shapeBlock;
6495 6868
6496 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6869 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6497 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6870 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6567,6 +6940,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6567 6940
6568 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6941 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6569 { 6942 {
6943 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6944 return;
6945
6570 ObjectShapePacket.ObjectDataBlock shapeBlock; 6946 ObjectShapePacket.ObjectDataBlock shapeBlock;
6571 6947
6572 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6948 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6616,6 +6992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6616 6992
6617 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6993 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6618 { 6994 {
6995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6996 return;
6997
6619 ObjectShapePacket.ObjectDataBlock shapeBlock; 6998 ObjectShapePacket.ObjectDataBlock shapeBlock;
6620 6999
6621 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7000 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6658,6 +7037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6658 7037
6659 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) 7038 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)
6660 { 7039 {
7040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7041 return;
7042
6661 ObjectShapePacket.ObjectDataBlock shapeBlock; 7043 ObjectShapePacket.ObjectDataBlock shapeBlock;
6662 7044
6663 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7045 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6784,6 +7166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6784 7166
6785 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7167 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6786 { 7168 {
7169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7170 return;
7171
6787 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7172 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6788 UUID sculptId; 7173 UUID sculptId;
6789 7174
@@ -6799,13 +7184,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 shapeBlock.PathScaleX = 100; 7184 shapeBlock.PathScaleX = 100;
6800 shapeBlock.PathScaleY = 150; 7185 shapeBlock.PathScaleY = 150;
6801 7186
6802 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7187 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6803 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7188 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6804 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7189 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6805 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7190 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6806 { 7191 {
6807 // default 7192 // default
6808 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7193 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6809 } 7194 }
6810 7195
6811 // retain pathcurve 7196 // retain pathcurve
@@ -6824,12 +7209,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6824 7209
6825 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7210 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6826 { 7211 {
6827 m_host.AddScriptLPS(1); 7212 m_host.AddScriptLPS(1);
6828 7213
6829 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7214 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6830 7215 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
6831 foreach (SceneObjectPart part in parts) 7216 if (parts.Count>0)
6832 SetPrimParams(part, rules); 7217 {
7218 try
7219 {
7220 parts[0].ParentGroup.areUpdatesSuspended = true;
7221 foreach (SceneObjectPart part in parts)
7222 SetPrimParams(part, rules);
7223 }
7224 finally
7225 {
7226 parts[0].ParentGroup.areUpdatesSuspended = false;
7227 }
7228 }
7229 if (avatars.Count > 0)
7230 {
7231 foreach (ScenePresence avatar in avatars)
7232 SetPrimParams(avatar, rules);
7233 }
6833 } 7234 }
6834 7235
6835 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7236 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
@@ -6837,8 +7238,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6837 llSetLinkPrimitiveParams(linknumber, rules); 7238 llSetLinkPrimitiveParams(linknumber, rules);
6838 } 7239 }
6839 7240
7241 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7242 {
7243 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7244 //We only support PRIM_POSITION and PRIM_ROTATION
7245
7246 int idx = 0;
7247
7248 while (idx < rules.Length)
7249 {
7250 int code = rules.GetLSLIntegerItem(idx++);
7251
7252 int remain = rules.Length - idx;
7253
7254
7255
7256 switch (code)
7257 {
7258 case (int)ScriptBaseClass.PRIM_POSITION:
7259 if (remain < 1)
7260 return;
7261 LSL_Vector v;
7262 v = rules.GetVector3Item(idx++);
7263 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7264 av.SendFullUpdateToAllClients();
7265
7266 break;
7267
7268 case (int)ScriptBaseClass.PRIM_ROTATION:
7269 if (remain < 1)
7270 return;
7271 LSL_Rotation r;
7272 r = rules.GetQuaternionItem(idx++);
7273 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7274 av.SendFullUpdateToAllClients();
7275 break;
7276 }
7277 }
7278
7279 }
7280
6840 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7281 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6841 { 7282 {
7283 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7284 return;
7285
6842 int idx = 0; 7286 int idx = 0;
6843 7287
6844 while (idx < rules.Length) 7288 while (idx < rules.Length)
@@ -7670,24 +8114,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7670 break; 8114 break;
7671 8115
7672 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8116 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7673 // TODO--------------
7674 if (remain < 1) 8117 if (remain < 1)
7675 return res; 8118 return res;
8119 face = (int)rules.GetLSLIntegerItem(idx++);
7676 8120
7677 face=(int)rules.GetLSLIntegerItem(idx++); 8121 tex = part.Shape.Textures;
7678 8122 int shiny;
7679 res.Add(new LSL_Integer(0)); 8123 if (face == ScriptBaseClass.ALL_SIDES)
7680 res.Add(new LSL_Integer(0)); 8124 {
8125 for (face = 0; face < GetNumberOfSides(part); face++)
8126 {
8127 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8128 if (shinyness == Shininess.High)
8129 {
8130 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8131 }
8132 else if (shinyness == Shininess.Medium)
8133 {
8134 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8135 }
8136 else if (shinyness == Shininess.Low)
8137 {
8138 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8139 }
8140 else
8141 {
8142 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8143 }
8144 res.Add(new LSL_Integer(shiny));
8145 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8146 }
8147 }
8148 else
8149 {
8150 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8151 if (shinyness == Shininess.High)
8152 {
8153 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8154 }
8155 else if (shinyness == Shininess.Medium)
8156 {
8157 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8158 }
8159 else if (shinyness == Shininess.Low)
8160 {
8161 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8162 }
8163 else
8164 {
8165 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8166 }
8167 res.Add(new LSL_Integer(shiny));
8168 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8169 }
7681 break; 8170 break;
7682 8171
7683 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8172 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7684 // TODO--------------
7685 if (remain < 1) 8173 if (remain < 1)
7686 return res; 8174 return res;
8175 face = (int)rules.GetLSLIntegerItem(idx++);
7687 8176
7688 face=(int)rules.GetLSLIntegerItem(idx++); 8177 tex = part.Shape.Textures;
7689 8178 int fullbright;
7690 res.Add(new LSL_Integer(0)); 8179 if (face == ScriptBaseClass.ALL_SIDES)
8180 {
8181 for (face = 0; face < GetNumberOfSides(part); face++)
8182 {
8183 if (tex.GetFace((uint)face).Fullbright == true)
8184 {
8185 fullbright = ScriptBaseClass.TRUE;
8186 }
8187 else
8188 {
8189 fullbright = ScriptBaseClass.FALSE;
8190 }
8191 res.Add(new LSL_Integer(fullbright));
8192 }
8193 }
8194 else
8195 {
8196 if (tex.GetFace((uint)face).Fullbright == true)
8197 {
8198 fullbright = ScriptBaseClass.TRUE;
8199 }
8200 else
8201 {
8202 fullbright = ScriptBaseClass.FALSE;
8203 }
8204 res.Add(new LSL_Integer(fullbright));
8205 }
7691 break; 8206 break;
7692 8207
7693 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8208 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7708,14 +8223,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7708 break; 8223 break;
7709 8224
7710 case (int)ScriptBaseClass.PRIM_TEXGEN: 8225 case (int)ScriptBaseClass.PRIM_TEXGEN:
7711 // TODO--------------
7712 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8226 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7713 if (remain < 1) 8227 if (remain < 1)
7714 return res; 8228 return res;
8229 face = (int)rules.GetLSLIntegerItem(idx++);
7715 8230
7716 face=(int)rules.GetLSLIntegerItem(idx++); 8231 tex = part.Shape.Textures;
7717 8232 if (face == ScriptBaseClass.ALL_SIDES)
7718 res.Add(new LSL_Integer(0)); 8233 {
8234 for (face = 0; face < GetNumberOfSides(part); face++)
8235 {
8236 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8237 {
8238 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8239 }
8240 else
8241 {
8242 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8243 }
8244 }
8245 }
8246 else
8247 {
8248 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8249 {
8250 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8251 }
8252 else
8253 {
8254 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8255 }
8256 }
7719 break; 8257 break;
7720 8258
7721 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8259 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7734,13 +8272,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7734 break; 8272 break;
7735 8273
7736 case (int)ScriptBaseClass.PRIM_GLOW: 8274 case (int)ScriptBaseClass.PRIM_GLOW:
7737 // TODO--------------
7738 if (remain < 1) 8275 if (remain < 1)
7739 return res; 8276 return res;
8277 face = (int)rules.GetLSLIntegerItem(idx++);
7740 8278
7741 face=(int)rules.GetLSLIntegerItem(idx++); 8279 tex = part.Shape.Textures;
7742 8280 float primglow;
7743 res.Add(new LSL_Float(0)); 8281 if (face == ScriptBaseClass.ALL_SIDES)
8282 {
8283 for (face = 0; face < GetNumberOfSides(part); face++)
8284 {
8285 primglow = tex.GetFace((uint)face).Glow;
8286 res.Add(new LSL_Float(primglow));
8287 }
8288 }
8289 else
8290 {
8291 primglow = tex.GetFace((uint)face).Glow;
8292 res.Add(new LSL_Float(primglow));
8293 }
7744 break; 8294 break;
7745 case (int)ScriptBaseClass.PRIM_TEXT: 8295 case (int)ScriptBaseClass.PRIM_TEXT:
7746 Color4 textColor = part.GetTextColor(); 8296 Color4 textColor = part.GetTextColor();
@@ -8277,28 +8827,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8277 { 8827 {
8278 m_host.AddScriptLPS(1); 8828 m_host.AddScriptLPS(1);
8279 8829
8280 lock (m_host.TaskInventory) 8830 m_host.TaskInventory.LockItemsForRead(true);
8831 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8281 { 8832 {
8282 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8833 if (inv.Value.Name == item)
8283 { 8834 {
8284 if (inv.Value.Name == item) 8835 m_host.TaskInventory.LockItemsForRead(false);
8836 switch (mask)
8285 { 8837 {
8286 switch (mask) 8838 case 0:
8287 { 8839 return (int)inv.Value.BasePermissions;
8288 case 0: 8840 case 1:
8289 return (int)inv.Value.BasePermissions; 8841 return (int)inv.Value.CurrentPermissions;
8290 case 1: 8842 case 2:
8291 return (int)inv.Value.CurrentPermissions; 8843 return (int)inv.Value.GroupPermissions;
8292 case 2: 8844 case 3:
8293 return (int)inv.Value.GroupPermissions; 8845 return (int)inv.Value.EveryonePermissions;
8294 case 3: 8846 case 4:
8295 return (int)inv.Value.EveryonePermissions; 8847 return (int)inv.Value.NextPermissions;
8296 case 4:
8297 return (int)inv.Value.NextPermissions;
8298 }
8299 } 8848 }
8300 } 8849 }
8301 } 8850 }
8851 m_host.TaskInventory.LockItemsForRead(false);
8302 8852
8303 return -1; 8853 return -1;
8304 } 8854 }
@@ -8345,16 +8895,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8345 { 8895 {
8346 m_host.AddScriptLPS(1); 8896 m_host.AddScriptLPS(1);
8347 8897
8348 lock (m_host.TaskInventory) 8898 m_host.TaskInventory.LockItemsForRead(true);
8899 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8349 { 8900 {
8350 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8901 if (inv.Value.Name == item)
8351 { 8902 {
8352 if (inv.Value.Name == item) 8903 m_host.TaskInventory.LockItemsForRead(false);
8353 { 8904 return inv.Value.CreatorID.ToString();
8354 return inv.Value.CreatorID.ToString();
8355 }
8356 } 8905 }
8357 } 8906 }
8907 m_host.TaskInventory.LockItemsForRead(false);
8358 8908
8359 llSay(0, "No item name '" + item + "'"); 8909 llSay(0, "No item name '" + item + "'");
8360 8910
@@ -8614,17 +9164,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8614 int width = 0; 9164 int width = 0;
8615 int height = 0; 9165 int height = 0;
8616 9166
8617 ParcelMediaCommandEnum? commandToSend = null; 9167 uint commandToSend = 0;
8618 float time = 0.0f; // default is from start 9168 float time = 0.0f; // default is from start
8619 9169
8620 ScenePresence presence = null; 9170 ScenePresence presence = null;
8621 9171
8622 for (int i = 0; i < commandList.Data.Length; i++) 9172 for (int i = 0; i < commandList.Data.Length; i++)
8623 { 9173 {
8624 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9174 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8625 switch (command) 9175 switch (command)
8626 { 9176 {
8627 case ParcelMediaCommandEnum.Agent: 9177 case (uint)ParcelMediaCommandEnum.Agent:
8628 // we send only to one agent 9178 // we send only to one agent
8629 if ((i + 1) < commandList.Length) 9179 if ((i + 1) < commandList.Length)
8630 { 9180 {
@@ -8641,25 +9191,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8641 } 9191 }
8642 break; 9192 break;
8643 9193
8644 case ParcelMediaCommandEnum.Loop: 9194 case (uint)ParcelMediaCommandEnum.Loop:
8645 loop = 1; 9195 loop = 1;
8646 commandToSend = command; 9196 commandToSend = command;
8647 update = true; //need to send the media update packet to set looping 9197 update = true; //need to send the media update packet to set looping
8648 break; 9198 break;
8649 9199
8650 case ParcelMediaCommandEnum.Play: 9200 case (uint)ParcelMediaCommandEnum.Play:
8651 loop = 0; 9201 loop = 0;
8652 commandToSend = command; 9202 commandToSend = command;
8653 update = true; //need to send the media update packet to make sure it doesn't loop 9203 update = true; //need to send the media update packet to make sure it doesn't loop
8654 break; 9204 break;
8655 9205
8656 case ParcelMediaCommandEnum.Pause: 9206 case (uint)ParcelMediaCommandEnum.Pause:
8657 case ParcelMediaCommandEnum.Stop: 9207 case (uint)ParcelMediaCommandEnum.Stop:
8658 case ParcelMediaCommandEnum.Unload: 9208 case (uint)ParcelMediaCommandEnum.Unload:
8659 commandToSend = command; 9209 commandToSend = command;
8660 break; 9210 break;
8661 9211
8662 case ParcelMediaCommandEnum.Url: 9212 case (uint)ParcelMediaCommandEnum.Url:
8663 if ((i + 1) < commandList.Length) 9213 if ((i + 1) < commandList.Length)
8664 { 9214 {
8665 if (commandList.Data[i + 1] is LSL_String) 9215 if (commandList.Data[i + 1] is LSL_String)
@@ -8672,7 +9222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8672 } 9222 }
8673 break; 9223 break;
8674 9224
8675 case ParcelMediaCommandEnum.Texture: 9225 case (uint)ParcelMediaCommandEnum.Texture:
8676 if ((i + 1) < commandList.Length) 9226 if ((i + 1) < commandList.Length)
8677 { 9227 {
8678 if (commandList.Data[i + 1] is LSL_String) 9228 if (commandList.Data[i + 1] is LSL_String)
@@ -8685,7 +9235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8685 } 9235 }
8686 break; 9236 break;
8687 9237
8688 case ParcelMediaCommandEnum.Time: 9238 case (uint)ParcelMediaCommandEnum.Time:
8689 if ((i + 1) < commandList.Length) 9239 if ((i + 1) < commandList.Length)
8690 { 9240 {
8691 if (commandList.Data[i + 1] is LSL_Float) 9241 if (commandList.Data[i + 1] is LSL_Float)
@@ -8697,7 +9247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8697 } 9247 }
8698 break; 9248 break;
8699 9249
8700 case ParcelMediaCommandEnum.AutoAlign: 9250 case (uint)ParcelMediaCommandEnum.AutoAlign:
8701 if ((i + 1) < commandList.Length) 9251 if ((i + 1) < commandList.Length)
8702 { 9252 {
8703 if (commandList.Data[i + 1] is LSL_Integer) 9253 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8711,7 +9261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8711 } 9261 }
8712 break; 9262 break;
8713 9263
8714 case ParcelMediaCommandEnum.Type: 9264 case (uint)ParcelMediaCommandEnum.Type:
8715 if ((i + 1) < commandList.Length) 9265 if ((i + 1) < commandList.Length)
8716 { 9266 {
8717 if (commandList.Data[i + 1] is LSL_String) 9267 if (commandList.Data[i + 1] is LSL_String)
@@ -8724,7 +9274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8724 } 9274 }
8725 break; 9275 break;
8726 9276
8727 case ParcelMediaCommandEnum.Desc: 9277 case (uint)ParcelMediaCommandEnum.Desc:
8728 if ((i + 1) < commandList.Length) 9278 if ((i + 1) < commandList.Length)
8729 { 9279 {
8730 if (commandList.Data[i + 1] is LSL_String) 9280 if (commandList.Data[i + 1] is LSL_String)
@@ -8737,7 +9287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8737 } 9287 }
8738 break; 9288 break;
8739 9289
8740 case ParcelMediaCommandEnum.Size: 9290 case (uint)ParcelMediaCommandEnum.Size:
8741 if ((i + 2) < commandList.Length) 9291 if ((i + 2) < commandList.Length)
8742 { 9292 {
8743 if (commandList.Data[i + 1] is LSL_Integer) 9293 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8807,7 +9357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8807 } 9357 }
8808 } 9358 }
8809 9359
8810 if (commandToSend != null) 9360 if (commandToSend != 0)
8811 { 9361 {
8812 // the commandList contained a start/stop/... command, too 9362 // the commandList contained a start/stop/... command, too
8813 if (presence == null) 9363 if (presence == null)
@@ -8887,16 +9437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8887 { 9437 {
8888 m_host.AddScriptLPS(1); 9438 m_host.AddScriptLPS(1);
8889 9439
8890 lock (m_host.TaskInventory) 9440 m_host.TaskInventory.LockItemsForRead(true);
9441 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8891 { 9442 {
8892 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9443 if (inv.Value.Name == name)
8893 { 9444 {
8894 if (inv.Value.Name == name) 9445 m_host.TaskInventory.LockItemsForRead(false);
8895 { 9446 return inv.Value.Type;
8896 return inv.Value.Type;
8897 }
8898 } 9447 }
8899 } 9448 }
9449 m_host.TaskInventory.LockItemsForRead(false);
8900 9450
8901 return -1; 9451 return -1;
8902 } 9452 }
@@ -8907,15 +9457,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8907 9457
8908 if (quick_pay_buttons.Data.Length < 4) 9458 if (quick_pay_buttons.Data.Length < 4)
8909 { 9459 {
8910 LSLError("List must have at least 4 elements"); 9460 int x;
8911 return; 9461 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9462 {
9463 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9464 }
8912 } 9465 }
8913 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9466 int[] nPrice = new int[5];
8914 9467 nPrice[0]=price;
8915 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9468 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8916 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9469 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8917 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9470 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8918 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9471 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9472 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8919 m_host.ParentGroup.HasGroupChanged = true; 9473 m_host.ParentGroup.HasGroupChanged = true;
8920 } 9474 }
8921 9475
@@ -8927,17 +9481,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8927 if (invItemID == UUID.Zero) 9481 if (invItemID == UUID.Zero)
8928 return new LSL_Vector(); 9482 return new LSL_Vector();
8929 9483
8930 lock (m_host.TaskInventory) 9484 m_host.TaskInventory.LockItemsForRead(true);
9485 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8931 { 9486 {
8932 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9487 m_host.TaskInventory.LockItemsForRead(false);
8933 return new LSL_Vector(); 9488 return new LSL_Vector();
9489 }
8934 9490
8935 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9491 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8936 { 9492 {
8937 ShoutError("No permissions to track the camera"); 9493 ShoutError("No permissions to track the camera");
8938 return new LSL_Vector(); 9494 m_host.TaskInventory.LockItemsForRead(false);
8939 } 9495 return new LSL_Vector();
8940 } 9496 }
9497 m_host.TaskInventory.LockItemsForRead(false);
8941 9498
8942 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9499 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8943 if (presence != null) 9500 if (presence != null)
@@ -8955,17 +9512,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8955 if (invItemID == UUID.Zero) 9512 if (invItemID == UUID.Zero)
8956 return new LSL_Rotation(); 9513 return new LSL_Rotation();
8957 9514
8958 lock (m_host.TaskInventory) 9515 m_host.TaskInventory.LockItemsForRead(true);
9516 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8959 { 9517 {
8960 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9518 m_host.TaskInventory.LockItemsForRead(false);
8961 return new LSL_Rotation(); 9519 return new LSL_Rotation();
8962
8963 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8964 {
8965 ShoutError("No permissions to track the camera");
8966 return new LSL_Rotation();
8967 }
8968 } 9520 }
9521 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9522 {
9523 ShoutError("No permissions to track the camera");
9524 m_host.TaskInventory.LockItemsForRead(false);
9525 return new LSL_Rotation();
9526 }
9527 m_host.TaskInventory.LockItemsForRead(false);
8969 9528
8970 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9529 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8971 if (presence != null) 9530 if (presence != null)
@@ -9027,8 +9586,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9027 { 9586 {
9028 m_host.AddScriptLPS(1); 9587 m_host.AddScriptLPS(1);
9029 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9588 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9030 if (detectedParams == null) return; // only works on the first detected avatar 9589 if (detectedParams == null)
9031 9590 {
9591 if (m_host.IsAttachment == true)
9592 {
9593 detectedParams = new DetectParams();
9594 detectedParams.Key = m_host.OwnerID;
9595 }
9596 else
9597 {
9598 return;
9599 }
9600 }
9601
9032 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9602 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9033 if (avatar != null) 9603 if (avatar != null)
9034 { 9604 {
@@ -9036,6 +9606,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9036 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9606 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9037 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9607 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9038 } 9608 }
9609
9039 ScriptSleep(1000); 9610 ScriptSleep(1000);
9040 } 9611 }
9041 9612
@@ -9115,14 +9686,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9115 if (objectID == UUID.Zero) return; 9686 if (objectID == UUID.Zero) return;
9116 9687
9117 UUID agentID; 9688 UUID agentID;
9118 lock (m_host.TaskInventory) 9689 m_host.TaskInventory.LockItemsForRead(true);
9119 { 9690 // we need the permission first, to know which avatar we want to set the camera for
9120 // we need the permission first, to know which avatar we want to set the camera for 9691 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9121 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9122 9692
9123 if (agentID == UUID.Zero) return; 9693 if (agentID == UUID.Zero)
9124 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9694 {
9695 m_host.TaskInventory.LockItemsForRead(false);
9696 return;
9697 }
9698 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9699 {
9700 m_host.TaskInventory.LockItemsForRead(false);
9701 return;
9125 } 9702 }
9703 m_host.TaskInventory.LockItemsForRead(false);
9126 9704
9127 ScenePresence presence = World.GetScenePresence(agentID); 9705 ScenePresence presence = World.GetScenePresence(agentID);
9128 9706
@@ -9172,12 +9750,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9172 9750
9173 // we need the permission first, to know which avatar we want to clear the camera for 9751 // we need the permission first, to know which avatar we want to clear the camera for
9174 UUID agentID; 9752 UUID agentID;
9175 lock (m_host.TaskInventory) 9753 m_host.TaskInventory.LockItemsForRead(true);
9754 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9755 if (agentID == UUID.Zero)
9176 { 9756 {
9177 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9757 m_host.TaskInventory.LockItemsForRead(false);
9178 if (agentID == UUID.Zero) return; 9758 return;
9179 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9759 }
9760 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9761 {
9762 m_host.TaskInventory.LockItemsForRead(false);
9763 return;
9180 } 9764 }
9765 m_host.TaskInventory.LockItemsForRead(false);
9181 9766
9182 ScenePresence presence = World.GetScenePresence(agentID); 9767 ScenePresence presence = World.GetScenePresence(agentID);
9183 9768
@@ -9634,15 +10219,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9634 10219
9635 internal UUID ScriptByName(string name) 10220 internal UUID ScriptByName(string name)
9636 { 10221 {
9637 lock (m_host.TaskInventory) 10222 m_host.TaskInventory.LockItemsForRead(true);
10223
10224 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9638 { 10225 {
9639 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10226 if (item.Type == 10 && item.Name == name)
9640 { 10227 {
9641 if (item.Type == 10 && item.Name == name) 10228 m_host.TaskInventory.LockItemsForRead(false);
9642 return item.ItemID; 10229 return item.ItemID;
9643 } 10230 }
9644 } 10231 }
9645 10232
10233 m_host.TaskInventory.LockItemsForRead(false);
10234
9646 return UUID.Zero; 10235 return UUID.Zero;
9647 } 10236 }
9648 10237
@@ -9683,6 +10272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9683 { 10272 {
9684 m_host.AddScriptLPS(1); 10273 m_host.AddScriptLPS(1);
9685 10274
10275 //Clone is thread safe
9686 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10276 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9687 10277
9688 UUID assetID = UUID.Zero; 10278 UUID assetID = UUID.Zero;
@@ -9745,6 +10335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9745 { 10335 {
9746 m_host.AddScriptLPS(1); 10336 m_host.AddScriptLPS(1);
9747 10337
10338 //Clone is thread safe
9748 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10339 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9749 10340
9750 UUID assetID = UUID.Zero; 10341 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 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 1ea52c5..212dbe3 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
@@ -337,19 +337,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
337 337
338 public override string ToString() 338 public override string ToString()
339 { 339 {
340 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 340 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
341 return st; 341 return st;
342 } 342 }
343 343
344 public static explicit operator string(Quaternion r) 344 public static explicit operator string(Quaternion r)
345 { 345 {
346 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 346 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
347 return s; 347 return s;
348 } 348 }
349 349
350 public static explicit operator LSLString(Quaternion r) 350 public static explicit operator LSLString(Quaternion r)
351 { 351 {
352 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 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
353 return new LSLString(s); 353 return new LSLString(s);
354 } 354 }
355 355
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 61a2088..30e127d 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 }
@@ -696,111 +764,117 @@ namespace OpenSim.Region.ScriptEngine.XEngine
696 } 764 }
697 } 765 }
698 766
699 lock (m_Scripts) 767
768
769 ScriptInstance instance = null;
770 // Create the object record
771 lockScriptsForRead(true);
772 if ((!m_Scripts.ContainsKey(itemID)) ||
773 (m_Scripts[itemID].AssetID != assetID))
700 { 774 {
701 ScriptInstance instance = null; 775 lockScriptsForRead(false);
702 // Create the object record
703 776
704 if ((!m_Scripts.ContainsKey(itemID)) || 777 UUID appDomain = assetID;
705 (m_Scripts[itemID].AssetID != assetID))
706 {
707 UUID appDomain = assetID;
708 778
709 if (part.ParentGroup.IsAttachment) 779 if (part.ParentGroup.IsAttachment)
710 appDomain = part.ParentGroup.RootPart.UUID; 780 appDomain = part.ParentGroup.RootPart.UUID;
711 781
712 if (!m_AppDomains.ContainsKey(appDomain)) 782 if (!m_AppDomains.ContainsKey(appDomain))
783 {
784 try
713 { 785 {
714 try 786 AppDomainSetup appSetup = new AppDomainSetup();
715 { 787 // appSetup.ApplicationBase = Path.Combine(
716 AppDomainSetup appSetup = new AppDomainSetup(); 788 // "ScriptEngines",
717// appSetup.ApplicationBase = Path.Combine( 789 // m_Scene.RegionInfo.RegionID.ToString());
718// "ScriptEngines", 790
719// m_Scene.RegionInfo.RegionID.ToString()); 791 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
720 792 Evidence evidence = new Evidence(baseEvidence);
721 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 793
722 Evidence evidence = new Evidence(baseEvidence); 794 AppDomain sandbox;
723 795 if (m_AppDomainLoading)
724 AppDomain sandbox; 796 sandbox = AppDomain.CreateDomain(
725 if (m_AppDomainLoading) 797 m_Scene.RegionInfo.RegionID.ToString(),
726 sandbox = AppDomain.CreateDomain( 798 evidence, appSetup);
727 m_Scene.RegionInfo.RegionID.ToString(), 799 else
728 evidence, appSetup); 800 sandbox = AppDomain.CurrentDomain;
729 else 801
730 sandbox = AppDomain.CurrentDomain; 802 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
731 803 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
732 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 804 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
733 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 805 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
734 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 806 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
735 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 807 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
736 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 808 //sandbox.SetAppDomainPolicy(sandboxPolicy);
737 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 809
738 //sandbox.SetAppDomainPolicy(sandboxPolicy); 810 m_AppDomains[appDomain] = sandbox;
739 811
740 m_AppDomains[appDomain] = sandbox; 812 m_AppDomains[appDomain].AssemblyResolve +=
741 813 new ResolveEventHandler(
742 m_AppDomains[appDomain].AssemblyResolve += 814 AssemblyResolver.OnAssemblyResolve);
743 new ResolveEventHandler( 815 m_DomainScripts[appDomain] = new List<UUID>();
744 AssemblyResolver.OnAssemblyResolve);
745 m_DomainScripts[appDomain] = new List<UUID>();
746 }
747 catch (Exception e)
748 {
749 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
750 m_ScriptErrorMessage += "Exception creating app domain:\n";
751 m_ScriptFailCount++;
752 lock (m_AddingAssemblies)
753 {
754 m_AddingAssemblies[assembly]--;
755 }
756 return false;
757 }
758 } 816 }
759 m_DomainScripts[appDomain].Add(itemID); 817 catch (Exception e)
760
761 instance = new ScriptInstance(this, part,
762 itemID, assetID, assembly,
763 m_AppDomains[appDomain],
764 part.ParentGroup.RootPart.Name,
765 item.Name, startParam, postOnRez,
766 stateSource, m_MaxScriptQueue);
767
768 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
769 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
770
771 if (presence != null)
772 { 818 {
773 ShowScriptSaveResponse(item.OwnerID, 819 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
774 assetID, "Compile successful", true); 820 m_ScriptErrorMessage += "Exception creating app domain:\n";
821 m_ScriptFailCount++;
822 lock (m_AddingAssemblies)
823 {
824 m_AddingAssemblies[assembly]--;
825 }
826 return false;
775 } 827 }
828 }
829 m_DomainScripts[appDomain].Add(itemID);
776 830
777 instance.AppDomain = appDomain; 831 instance = new ScriptInstance(this, part,
778 instance.LineMap = linemap; 832 itemID, assetID, assembly,
833 m_AppDomains[appDomain],
834 part.ParentGroup.RootPart.Name,
835 item.Name, startParam, postOnRez,
836 stateSource, m_MaxScriptQueue);
779 837
780 m_Scripts[itemID] = instance; 838 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
781 } 839 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
782 840
783 lock (m_PrimObjects) 841 if (presence != null)
784 { 842 {
785 if (!m_PrimObjects.ContainsKey(localID)) 843 ShowScriptSaveResponse(item.OwnerID,
786 m_PrimObjects[localID] = new List<UUID>(); 844 assetID, "Compile successful", true);
845 }
787 846
788 if (!m_PrimObjects[localID].Contains(itemID)) 847 instance.AppDomain = appDomain;
789 m_PrimObjects[localID].Add(itemID); 848 instance.LineMap = linemap;
849 lockScriptsForWrite(true);
850 m_Scripts[itemID] = instance;
851 lockScriptsForWrite(false);
852 }
853 else
854 {
855 lockScriptsForRead(false);
856 }
857 lock (m_PrimObjects)
858 {
859 if (!m_PrimObjects.ContainsKey(localID))
860 m_PrimObjects[localID] = new List<UUID>();
790 861
791 } 862 if (!m_PrimObjects[localID].Contains(itemID))
863 m_PrimObjects[localID].Add(itemID);
792 864
793 if (!m_Assemblies.ContainsKey(assetID)) 865 }
794 m_Assemblies[assetID] = assembly;
795 866
796 lock (m_AddingAssemblies) 867 if (!m_Assemblies.ContainsKey(assetID))
797 { 868 m_Assemblies[assetID] = assembly;
798 m_AddingAssemblies[assembly]--;
799 }
800 869
801 if (instance!=null) 870 lock (m_AddingAssemblies)
802 instance.Init(); 871 {
872 m_AddingAssemblies[assembly]--;
803 } 873 }
874
875 if (instance!=null)
876 instance.Init();
877
804 return true; 878 return true;
805 } 879 }
806 880
@@ -813,60 +887,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine
813 m_CompileDict.Remove(itemID); 887 m_CompileDict.Remove(itemID);
814 } 888 }
815 889
816 lock (m_Scripts) 890 lockScriptsForRead(true);
891 // Do we even have it?
892 if (!m_Scripts.ContainsKey(itemID))
817 { 893 {
818 // Do we even have it? 894 lockScriptsForRead(false);
819 if (!m_Scripts.ContainsKey(itemID)) 895 return;
820 return; 896 }
821 897
822 IScriptInstance instance=m_Scripts[itemID];
823 m_Scripts.Remove(itemID);
824 898
825 instance.ClearQueue(); 899 IScriptInstance instance=m_Scripts[itemID];
826 instance.Stop(0); 900 lockScriptsForRead(false);
901 lockScriptsForWrite(true);
902 m_Scripts.Remove(itemID);
903 lockScriptsForWrite(false);
904 instance.ClearQueue();
905 instance.Stop(0);
827 906
828// bool objectRemoved = false; 907// bool objectRemoved = false;
829 908
830 lock (m_PrimObjects) 909 lock (m_PrimObjects)
910 {
911 // Remove the script from it's prim
912 if (m_PrimObjects.ContainsKey(localID))
831 { 913 {
832 // Remove the script from it's prim 914 // Remove inventory item record
833 if (m_PrimObjects.ContainsKey(localID)) 915 if (m_PrimObjects[localID].Contains(itemID))
834 { 916 m_PrimObjects[localID].Remove(itemID);
835 // Remove inventory item record
836 if (m_PrimObjects[localID].Contains(itemID))
837 m_PrimObjects[localID].Remove(itemID);
838 917
839 // If there are no more scripts, remove prim 918 // If there are no more scripts, remove prim
840 if (m_PrimObjects[localID].Count == 0) 919 if (m_PrimObjects[localID].Count == 0)
841 { 920 {
842 m_PrimObjects.Remove(localID); 921 m_PrimObjects.Remove(localID);
843// objectRemoved = true; 922// objectRemoved = true;
844 }
845 } 923 }
846 } 924 }
925 }
847 926
848 instance.RemoveState(); 927 instance.RemoveState();
849 instance.DestroyScriptInstance(); 928 instance.DestroyScriptInstance();
850
851 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
852 if (m_DomainScripts[instance.AppDomain].Count == 0)
853 {
854 m_DomainScripts.Remove(instance.AppDomain);
855 UnloadAppDomain(instance.AppDomain);
856 }
857 929
858 instance = null; 930 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
931 if (m_DomainScripts[instance.AppDomain].Count == 0)
932 {
933 m_DomainScripts.Remove(instance.AppDomain);
934 UnloadAppDomain(instance.AppDomain);
935 }
859 936
860 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 937 instance = null;
861 if (handlerObjectRemoved != null)
862 {
863 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
864 handlerObjectRemoved(part.UUID);
865 }
866 938
867 CleanAssemblies(); 939 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
940 if (handlerObjectRemoved != null)
941 {
942 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
943 handlerObjectRemoved(part.UUID);
868 } 944 }
869 945
946 CleanAssemblies();
947
948
870 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 949 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
871 if (handlerScriptRemoved != null) 950 if (handlerScriptRemoved != null)
872 handlerScriptRemoved(itemID); 951 handlerScriptRemoved(itemID);
@@ -1118,12 +1197,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1118 private IScriptInstance GetInstance(UUID itemID) 1197 private IScriptInstance GetInstance(UUID itemID)
1119 { 1198 {
1120 IScriptInstance instance; 1199 IScriptInstance instance;
1121 lock (m_Scripts) 1200 lockScriptsForRead(true);
1201 if (!m_Scripts.ContainsKey(itemID))
1122 { 1202 {
1123 if (!m_Scripts.ContainsKey(itemID)) 1203 lockScriptsForRead(false);
1124 return null; 1204 return null;
1125 instance = m_Scripts[itemID];
1126 } 1205 }
1206 instance = m_Scripts[itemID];
1207 lockScriptsForRead(false);
1127 return instance; 1208 return instance;
1128 } 1209 }
1129 1210
@@ -1147,6 +1228,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1147 return false; 1228 return false;
1148 } 1229 }
1149 1230
1231 [DebuggerNonUserCode]
1150 public void ApiResetScript(UUID itemID) 1232 public void ApiResetScript(UUID itemID)
1151 { 1233 {
1152 IScriptInstance instance = GetInstance(itemID); 1234 IScriptInstance instance = GetInstance(itemID);
@@ -1198,6 +1280,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1198 return UUID.Zero; 1280 return UUID.Zero;
1199 } 1281 }
1200 1282
1283 [DebuggerNonUserCode]
1201 public void SetState(UUID itemID, string newState) 1284 public void SetState(UUID itemID, string newState)
1202 { 1285 {
1203 IScriptInstance instance = GetInstance(itemID); 1286 IScriptInstance instance = GetInstance(itemID);
@@ -1218,11 +1301,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1218 { 1301 {
1219 List<IScriptInstance> instances = new List<IScriptInstance>(); 1302 List<IScriptInstance> instances = new List<IScriptInstance>();
1220 1303
1221 lock (m_Scripts) 1304 lockScriptsForRead(true);
1222 { 1305 foreach (IScriptInstance instance in m_Scripts.Values)
1223 foreach (IScriptInstance instance in m_Scripts.Values)
1224 instances.Add(instance); 1306 instances.Add(instance);
1225 } 1307 lockScriptsForRead(false);
1226 1308
1227 foreach (IScriptInstance i in instances) 1309 foreach (IScriptInstance i in instances)
1228 { 1310 {