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/CM_Api.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs949
-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/ICM_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs4
-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/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs422
14 files changed, 1029 insertions, 499 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
index 880ca1b..3e62c1a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -113,6 +113,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
113 } 113 }
114 114
115 /// <summary> 115 /// <summary>
116 /// Like osGetAgents but returns enough info for a radar
117 /// </summary>
118 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns>
119 public LSL_List cmGetAvatarList()
120 {
121 LSL_List result = new LSL_List();
122 World.ForEachScenePresence(delegate (ScenePresence avatar)
123 {
124 if (avatar != null && avatar.UUID != m_host.OwnerID)
125 {
126 if (avatar.IsChildAgent == false)
127 {
128 result.Add(avatar.UUID);
129 result.Add(avatar.PhysicsActor.Position);
130 result.Add(avatar.Name);
131 }
132 }
133 });
134 return result;
135 }
136
137 /// <summary>
116 /// Get the current Windlight scene 138 /// Get the current Windlight scene
117 /// </summary> 139 /// </summary>
118 /// <returns>List of windlight parameters</returns> 140 /// <returns>List of windlight parameters</returns>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7a9a92d..68f6e7b 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);
@@ -219,6 +222,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
219 public List<SceneObjectPart> GetLinkParts(int linkType) 222 public List<SceneObjectPart> GetLinkParts(int linkType)
220 { 223 {
221 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 224 List<SceneObjectPart> ret = new List<SceneObjectPart>();
225 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
226 return ret;
222 ret.Add(m_host); 227 ret.Add(m_host);
223 228
224 switch (linkType) 229 switch (linkType)
@@ -272,40 +277,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 277 protected UUID InventorySelf()
273 { 278 {
274 UUID invItemID = new UUID(); 279 UUID invItemID = new UUID();
275 280 bool unlock = false;
276 lock (m_host.TaskInventory) 281 if (!m_host.TaskInventory.IsReadLockedByMe())
277 { 282 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 283 m_host.TaskInventory.LockItemsForRead(true);
284 unlock = true;
285 }
286 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
287 {
288 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 289 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 290 invItemID = inv.Key;
281 { 291 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 292 }
286 } 293 }
287 294 if (unlock)
295 {
296 m_host.TaskInventory.LockItemsForRead(false);
297 }
288 return invItemID; 298 return invItemID;
289 } 299 }
290 300
291 protected UUID InventoryKey(string name, int type) 301 protected UUID InventoryKey(string name, int type)
292 { 302 {
293 m_host.AddScriptLPS(1); 303 m_host.AddScriptLPS(1);
294 304 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 305
306 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 307 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 308 if (inv.Value.Name == name)
298 { 309 {
299 if (inv.Value.Name == name) 310 m_host.TaskInventory.LockItemsForRead(false);
311
312 if (inv.Value.Type != type)
300 { 313 {
301 if (inv.Value.Type != type) 314 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 315 }
316
317 return inv.Value.AssetID;
306 } 318 }
307 } 319 }
308 320
321 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 322 return UUID.Zero;
310 } 323 }
311 324
@@ -313,17 +326,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 326 {
314 m_host.AddScriptLPS(1); 327 m_host.AddScriptLPS(1);
315 328
316 lock (m_host.TaskInventory) 329
330 m_host.TaskInventory.LockItemsForRead(true);
331
332 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 333 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 334 if (inv.Value.Name == name)
319 { 335 {
320 if (inv.Value.Name == name) 336 m_host.TaskInventory.LockItemsForRead(false);
321 { 337 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 338 }
325 } 339 }
326 340
341 m_host.TaskInventory.LockItemsForRead(false);
342
343
327 return UUID.Zero; 344 return UUID.Zero;
328 } 345 }
329 346
@@ -705,6 +722,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 722 {
706 //A and B should both be normalized 723 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 724 m_host.AddScriptLPS(1);
725 /* This method is more accurate than the SL one, and thus causes problems
726 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
727
708 double dotProduct = LSL_Vector.Dot(a, b); 728 double dotProduct = LSL_Vector.Dot(a, b);
709 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 729 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
710 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b); 730 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
@@ -721,8 +741,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
721 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 741 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
722 742
723 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w); 743 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
724 } 744 */
725 745
746 // This method mimics the 180 errors found in SL
747 // See www.euclideanspace.com... angleBetween
748 LSL_Vector vec_a = a;
749 LSL_Vector vec_b = b;
750
751 // Eliminate zero length
752 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
753 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
754 if (vec_a_mag < 0.00001 ||
755 vec_b_mag < 0.00001)
756 {
757 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
758 }
759
760 // Normalize
761 vec_a = llVecNorm(vec_a);
762 vec_b = llVecNorm(vec_b);
763
764 // Calculate axis and rotation angle
765 LSL_Vector axis = vec_a % vec_b;
766 LSL_Float cos_theta = vec_a * vec_b;
767
768 // Check if parallel
769 if (cos_theta > 0.99999)
770 {
771 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
772 }
773
774 // Check if anti-parallel
775 else if (cos_theta < -0.99999)
776 {
777 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
778 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
779 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
780 }
781 else // other rotation
782 {
783 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
784 axis = llVecNorm(axis);
785 double x, y, z, s, t;
786 s = Math.Cos(theta);
787 t = Math.Sin(theta);
788 x = axis.x * t;
789 y = axis.y * t;
790 z = axis.z * t;
791 return new LSL_Rotation(x,y,z,s);
792 }
793 }
794
726 public void llWhisper(int channelID, string text) 795 public void llWhisper(int channelID, string text)
727 { 796 {
728 m_host.AddScriptLPS(1); 797 m_host.AddScriptLPS(1);
@@ -1046,10 +1115,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1046 return detectedParams.TouchUV; 1115 return detectedParams.TouchUV;
1047 } 1116 }
1048 1117
1118 [DebuggerNonUserCode]
1049 public virtual void llDie() 1119 public virtual void llDie()
1050 { 1120 {
1051 m_host.AddScriptLPS(1); 1121 m_host.AddScriptLPS(1);
1052 throw new SelfDeleteException(); 1122 if (!m_host.IsAttachment) throw new SelfDeleteException();
1053 } 1123 }
1054 1124
1055 public LSL_Float llGround(LSL_Vector offset) 1125 public LSL_Float llGround(LSL_Vector offset)
@@ -1122,6 +1192,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1122 1192
1123 public void llSetStatus(int status, int value) 1193 public void llSetStatus(int status, int value)
1124 { 1194 {
1195 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1196 return;
1125 m_host.AddScriptLPS(1); 1197 m_host.AddScriptLPS(1);
1126 1198
1127 int statusrotationaxis = 0; 1199 int statusrotationaxis = 0;
@@ -1351,6 +1423,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1351 { 1423 {
1352 m_host.AddScriptLPS(1); 1424 m_host.AddScriptLPS(1);
1353 1425
1426 SetColor(m_host, color, face);
1427 }
1428
1429 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1430 {
1431 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1432 return;
1433
1434 Primitive.TextureEntry tex = part.Shape.Textures;
1435 Color4 texcolor;
1436 if (face >= 0 && face < GetNumberOfSides(part))
1437 {
1438 texcolor = tex.CreateFace((uint)face).RGBA;
1439 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1440 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1441 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1442 tex.FaceTextures[face].RGBA = texcolor;
1443 part.UpdateTexture(tex);
1444 return;
1445 }
1446 else if (face == ScriptBaseClass.ALL_SIDES)
1447 {
1448 for (uint i = 0; i < GetNumberOfSides(part); i++)
1449 {
1450 if (tex.FaceTextures[i] != null)
1451 {
1452 texcolor = tex.FaceTextures[i].RGBA;
1453 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1454 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1455 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1456 tex.FaceTextures[i].RGBA = texcolor;
1457 }
1458 texcolor = tex.DefaultTexture.RGBA;
1459 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1460 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1461 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1462 tex.DefaultTexture.RGBA = texcolor;
1463 }
1464 part.UpdateTexture(tex);
1465 return;
1466 }
1467
1354 if (face == ScriptBaseClass.ALL_SIDES) 1468 if (face == ScriptBaseClass.ALL_SIDES)
1355 face = SceneObjectPart.ALL_SIDES; 1469 face = SceneObjectPart.ALL_SIDES;
1356 1470
@@ -1359,6 +1473,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1359 1473
1360 public void SetTexGen(SceneObjectPart part, int face,int style) 1474 public void SetTexGen(SceneObjectPart part, int face,int style)
1361 { 1475 {
1476 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1477 return;
1478
1362 Primitive.TextureEntry tex = part.Shape.Textures; 1479 Primitive.TextureEntry tex = part.Shape.Textures;
1363 MappingType textype; 1480 MappingType textype;
1364 textype = MappingType.Default; 1481 textype = MappingType.Default;
@@ -1389,6 +1506,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1389 1506
1390 public void SetGlow(SceneObjectPart part, int face, float glow) 1507 public void SetGlow(SceneObjectPart part, int face, float glow)
1391 { 1508 {
1509 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1510 return;
1511
1392 Primitive.TextureEntry tex = part.Shape.Textures; 1512 Primitive.TextureEntry tex = part.Shape.Textures;
1393 if (face >= 0 && face < GetNumberOfSides(part)) 1513 if (face >= 0 && face < GetNumberOfSides(part))
1394 { 1514 {
@@ -1414,6 +1534,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1534
1415 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1535 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1416 { 1536 {
1537 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1538 return;
1417 1539
1418 Shininess sval = new Shininess(); 1540 Shininess sval = new Shininess();
1419 1541
@@ -1464,6 +1586,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1464 1586
1465 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1587 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1466 { 1588 {
1589 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1590 return;
1591
1467 Primitive.TextureEntry tex = part.Shape.Textures; 1592 Primitive.TextureEntry tex = part.Shape.Textures;
1468 if (face >= 0 && face < GetNumberOfSides(part)) 1593 if (face >= 0 && face < GetNumberOfSides(part))
1469 { 1594 {
@@ -1531,6 +1656,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1531 1656
1532 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1657 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1533 { 1658 {
1659 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1660 return;
1661
1534 Primitive.TextureEntry tex = part.Shape.Textures; 1662 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor; 1663 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part)) 1664 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1576,7 +1704,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1576 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1704 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1577 float wind, float tension, LSL_Vector Force) 1705 float wind, float tension, LSL_Vector Force)
1578 { 1706 {
1579 if (part == null) 1707 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1580 return; 1708 return;
1581 1709
1582 if (flexi) 1710 if (flexi)
@@ -1611,7 +1739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 /// <param name="falloff"></param> 1739 /// <param name="falloff"></param>
1612 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1740 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1613 { 1741 {
1614 if (part == null) 1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1743 return;
1616 1744
1617 if (light) 1745 if (light)
@@ -1697,6 +1825,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1697 1825
1698 protected void SetTexture(SceneObjectPart part, string texture, int face) 1826 protected void SetTexture(SceneObjectPart part, string texture, int face)
1699 { 1827 {
1828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1829 return;
1830
1700 UUID textureID=new UUID(); 1831 UUID textureID=new UUID();
1701 1832
1702 if (!UUID.TryParse(texture, out textureID)) 1833 if (!UUID.TryParse(texture, out textureID))
@@ -1742,6 +1873,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1742 1873
1743 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1874 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1744 { 1875 {
1876 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1877 return;
1878
1745 Primitive.TextureEntry tex = part.Shape.Textures; 1879 Primitive.TextureEntry tex = part.Shape.Textures;
1746 if (face >= 0 && face < GetNumberOfSides(part)) 1880 if (face >= 0 && face < GetNumberOfSides(part))
1747 { 1881 {
@@ -1778,6 +1912,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1778 1912
1779 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1913 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1780 { 1914 {
1915 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1916 return;
1917
1781 Primitive.TextureEntry tex = part.Shape.Textures; 1918 Primitive.TextureEntry tex = part.Shape.Textures;
1782 if (face >= 0 && face < GetNumberOfSides(part)) 1919 if (face >= 0 && face < GetNumberOfSides(part))
1783 { 1920 {
@@ -1814,6 +1951,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 1951
1815 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 1952 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1816 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1817 Primitive.TextureEntry tex = part.Shape.Textures; 1957 Primitive.TextureEntry tex = part.Shape.Textures;
1818 if (face >= 0 && face < GetNumberOfSides(part)) 1958 if (face >= 0 && face < GetNumberOfSides(part))
1819 { 1959 {
@@ -1884,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1884 2024
1885 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2025 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1886 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1887 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2030 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1888 LSL_Vector currentPos = llGetLocalPos(); 2031 LSL_Vector currentPos = llGetLocalPos();
1889 2032
@@ -1970,6 +2113,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1970 2113
1971 protected void SetRot(SceneObjectPart part, Quaternion rot) 2114 protected void SetRot(SceneObjectPart part, Quaternion rot)
1972 { 2115 {
2116 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2117 return;
2118
1973 part.UpdateRotation(rot); 2119 part.UpdateRotation(rot);
1974 // Update rotation does not move the object in the physics scene if it's a linkset. 2120 // Update rotation does not move the object in the physics scene if it's a linkset.
1975 2121
@@ -2589,12 +2735,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2589 2735
2590 m_host.AddScriptLPS(1); 2736 m_host.AddScriptLPS(1);
2591 2737
2738 m_host.TaskInventory.LockItemsForRead(true);
2592 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2739 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2593 2740 m_host.TaskInventory.LockItemsForRead(false);
2594 lock (m_host.TaskInventory)
2595 {
2596 item = m_host.TaskInventory[invItemID];
2597 }
2598 2741
2599 if (item.PermsGranter == UUID.Zero) 2742 if (item.PermsGranter == UUID.Zero)
2600 return 0; 2743 return 0;
@@ -2669,6 +2812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2669 if (dist > m_ScriptDistanceFactor * 10.0f) 2812 if (dist > m_ScriptDistanceFactor * 10.0f)
2670 return; 2813 return;
2671 2814
2815 //Clone is thread-safe
2672 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2816 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2673 2817
2674 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2818 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2729,6 +2873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2729 2873
2730 public void llLookAt(LSL_Vector target, double strength, double damping) 2874 public void llLookAt(LSL_Vector target, double strength, double damping)
2731 { 2875 {
2876 /*
2732 m_host.AddScriptLPS(1); 2877 m_host.AddScriptLPS(1);
2733 // Determine where we are looking from 2878 // Determine where we are looking from
2734 LSL_Vector from = llGetPos(); 2879 LSL_Vector from = llGetPos();
@@ -2748,10 +2893,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2748 // the angles of rotation in radians into rotation value 2893 // the angles of rotation in radians into rotation value
2749 2894
2750 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2895 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2751 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2896
2752 m_host.startLookAt(rotation, (float)damping, (float)strength); 2897 // This would only work if your physics system contains an APID controller:
2898 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2899 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2900
2753 // Orient the object to the angle calculated 2901 // Orient the object to the angle calculated
2754 //llSetRot(rot); 2902 llSetRot(rot);
2903 */
2904
2905 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2906 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2907 // http://bugs.meta7.com/view.php?id=28
2908 // - Tom
2909
2910 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
2911 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
2912
2913 }
2914
2915 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2916 {
2917 m_host.AddScriptLPS(1);
2918// NotImplemented("llRotLookAt");
2919 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
2920
2755 } 2921 }
2756 2922
2757 public void llStopLookAt() 2923 public void llStopLookAt()
@@ -2800,13 +2966,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2800 { 2966 {
2801 TaskInventoryItem item; 2967 TaskInventoryItem item;
2802 2968
2803 lock (m_host.TaskInventory) 2969 m_host.TaskInventory.LockItemsForRead(true);
2970 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2804 { 2971 {
2805 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2972 m_host.TaskInventory.LockItemsForRead(false);
2806 return; 2973 return;
2807 else 2974 }
2808 item = m_host.TaskInventory[InventorySelf()]; 2975 else
2976 {
2977 item = m_host.TaskInventory[InventorySelf()];
2809 } 2978 }
2979 m_host.TaskInventory.LockItemsForRead(false);
2810 2980
2811 if (item.PermsGranter != UUID.Zero) 2981 if (item.PermsGranter != UUID.Zero)
2812 { 2982 {
@@ -2828,13 +2998,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2828 { 2998 {
2829 TaskInventoryItem item; 2999 TaskInventoryItem item;
2830 3000
3001 m_host.TaskInventory.LockItemsForRead(true);
2831 lock (m_host.TaskInventory) 3002 lock (m_host.TaskInventory)
2832 { 3003 {
3004
2833 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3005 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3006 {
3007 m_host.TaskInventory.LockItemsForRead(false);
2834 return; 3008 return;
3009 }
2835 else 3010 else
3011 {
2836 item = m_host.TaskInventory[InventorySelf()]; 3012 item = m_host.TaskInventory[InventorySelf()];
3013 }
2837 } 3014 }
3015 m_host.TaskInventory.LockItemsForRead(false);
2838 3016
2839 m_host.AddScriptLPS(1); 3017 m_host.AddScriptLPS(1);
2840 3018
@@ -2871,14 +3049,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2871 3049
2872 TaskInventoryItem item; 3050 TaskInventoryItem item;
2873 3051
2874 lock (m_host.TaskInventory) 3052 m_host.TaskInventory.LockItemsForRead(true);
3053
3054 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2875 { 3055 {
2876 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3056 m_host.TaskInventory.LockItemsForRead(false);
2877 return; 3057 return;
2878 else 3058 }
2879 item = m_host.TaskInventory[InventorySelf()]; 3059 else
3060 {
3061 item = m_host.TaskInventory[InventorySelf()];
2880 } 3062 }
2881 3063
3064 m_host.TaskInventory.LockItemsForRead(false);
3065
2882 if (item.PermsGranter != m_host.OwnerID) 3066 if (item.PermsGranter != m_host.OwnerID)
2883 return; 3067 return;
2884 3068
@@ -2905,13 +3089,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2905 3089
2906 TaskInventoryItem item; 3090 TaskInventoryItem item;
2907 3091
2908 lock (m_host.TaskInventory) 3092 m_host.TaskInventory.LockItemsForRead(true);
3093
3094 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2909 { 3095 {
2910 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3096 m_host.TaskInventory.LockItemsForRead(false);
2911 return; 3097 return;
2912 else
2913 item = m_host.TaskInventory[InventorySelf()];
2914 } 3098 }
3099 else
3100 {
3101 item = m_host.TaskInventory[InventorySelf()];
3102 }
3103 m_host.TaskInventory.LockItemsForRead(false);
3104
2915 3105
2916 if (item.PermsGranter != m_host.OwnerID) 3106 if (item.PermsGranter != m_host.OwnerID)
2917 return; 3107 return;
@@ -2948,8 +3138,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2948 return m_host.OwnerID.ToString(); 3138 return m_host.OwnerID.ToString();
2949 } 3139 }
2950 3140
3141 [DebuggerNonUserCode]
2951 public void llInstantMessage(string user, string message) 3142 public void llInstantMessage(string user, string message)
2952 { 3143 {
3144 UUID result;
3145 if (!UUID.TryParse(user, out result))
3146 {
3147 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3148 return;
3149 }
3150
3151
2953 m_host.AddScriptLPS(1); 3152 m_host.AddScriptLPS(1);
2954 3153
2955 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3154 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2964,7 +3163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2964 UUID friendTransactionID = UUID.Random(); 3163 UUID friendTransactionID = UUID.Random();
2965 3164
2966 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3165 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
2967 3166
2968 GridInstantMessage msg = new GridInstantMessage(); 3167 GridInstantMessage msg = new GridInstantMessage();
2969 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3168 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
2970 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3169 msg.toAgentID = new Guid(user); // toAgentID.Guid;
@@ -3113,13 +3312,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3113 m_host.AddScriptLPS(1); 3312 m_host.AddScriptLPS(1);
3114 } 3313 }
3115 3314
3116 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3117 {
3118 m_host.AddScriptLPS(1);
3119 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3120 m_host.RotLookAt(rot, (float)strength, (float)damping);
3121 }
3122
3123 public LSL_Integer llStringLength(string str) 3315 public LSL_Integer llStringLength(string str)
3124 { 3316 {
3125 m_host.AddScriptLPS(1); 3317 m_host.AddScriptLPS(1);
@@ -3143,14 +3335,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3143 3335
3144 TaskInventoryItem item; 3336 TaskInventoryItem item;
3145 3337
3146 lock (m_host.TaskInventory) 3338 m_host.TaskInventory.LockItemsForRead(true);
3339 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3147 { 3340 {
3148 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3341 m_host.TaskInventory.LockItemsForRead(false);
3149 return; 3342 return;
3150 else
3151 item = m_host.TaskInventory[InventorySelf()];
3152 } 3343 }
3153 3344 else
3345 {
3346 item = m_host.TaskInventory[InventorySelf()];
3347 }
3348 m_host.TaskInventory.LockItemsForRead(false);
3154 if (item.PermsGranter == UUID.Zero) 3349 if (item.PermsGranter == UUID.Zero)
3155 return; 3350 return;
3156 3351
@@ -3180,13 +3375,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 3375
3181 TaskInventoryItem item; 3376 TaskInventoryItem item;
3182 3377
3183 lock (m_host.TaskInventory) 3378 m_host.TaskInventory.LockItemsForRead(true);
3379 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3184 { 3380 {
3185 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3381 m_host.TaskInventory.LockItemsForRead(false);
3186 return; 3382 return;
3187 else
3188 item = m_host.TaskInventory[InventorySelf()];
3189 } 3383 }
3384 else
3385 {
3386 item = m_host.TaskInventory[InventorySelf()];
3387 }
3388 m_host.TaskInventory.LockItemsForRead(false);
3389
3190 3390
3191 if (item.PermsGranter == UUID.Zero) 3391 if (item.PermsGranter == UUID.Zero)
3192 return; 3392 return;
@@ -3263,10 +3463,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3263 3463
3264 TaskInventoryItem item; 3464 TaskInventoryItem item;
3265 3465
3266 lock (m_host.TaskInventory) 3466
3467 m_host.TaskInventory.LockItemsForRead(true);
3468 if (!m_host.TaskInventory.ContainsKey(invItemID))
3469 {
3470 m_host.TaskInventory.LockItemsForRead(false);
3471 return;
3472 }
3473 else
3267 { 3474 {
3268 item = m_host.TaskInventory[invItemID]; 3475 item = m_host.TaskInventory[invItemID];
3269 } 3476 }
3477 m_host.TaskInventory.LockItemsForRead(false);
3270 3478
3271 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3479 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3272 { 3480 {
@@ -3298,11 +3506,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3298 3506
3299 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3507 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3300 { 3508 {
3301 lock (m_host.TaskInventory) 3509 m_host.TaskInventory.LockItemsForWrite(true);
3302 { 3510 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3303 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3511 m_host.TaskInventory[invItemID].PermsMask = perm;
3304 m_host.TaskInventory[invItemID].PermsMask = perm; 3512 m_host.TaskInventory.LockItemsForWrite(false);
3305 }
3306 3513
3307 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3514 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3308 "run_time_permissions", new Object[] { 3515 "run_time_permissions", new Object[] {
@@ -3322,11 +3529,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 3529
3323 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3530 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3324 { 3531 {
3325 lock (m_host.TaskInventory) 3532 m_host.TaskInventory.LockItemsForWrite(true);
3326 { 3533 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3327 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3534 m_host.TaskInventory[invItemID].PermsMask = perm;
3328 m_host.TaskInventory[invItemID].PermsMask = perm; 3535 m_host.TaskInventory.LockItemsForWrite(false);
3329 }
3330 3536
3331 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3537 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3332 "run_time_permissions", new Object[] { 3538 "run_time_permissions", new Object[] {
@@ -3347,11 +3553,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3347 3553
3348 if (!m_waitingForScriptAnswer) 3554 if (!m_waitingForScriptAnswer)
3349 { 3555 {
3350 lock (m_host.TaskInventory) 3556 m_host.TaskInventory.LockItemsForWrite(true);
3351 { 3557 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3352 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3558 m_host.TaskInventory[invItemID].PermsMask = 0;
3353 m_host.TaskInventory[invItemID].PermsMask = 0; 3559 m_host.TaskInventory.LockItemsForWrite(false);
3354 }
3355 3560
3356 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3561 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3357 m_waitingForScriptAnswer=true; 3562 m_waitingForScriptAnswer=true;
@@ -3386,10 +3591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3386 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3591 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3387 llReleaseControls(); 3592 llReleaseControls();
3388 3593
3389 lock (m_host.TaskInventory) 3594
3390 { 3595 m_host.TaskInventory.LockItemsForWrite(true);
3391 m_host.TaskInventory[invItemID].PermsMask = answer; 3596 m_host.TaskInventory[invItemID].PermsMask = answer;
3392 } 3597 m_host.TaskInventory.LockItemsForWrite(false);
3598
3393 3599
3394 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3600 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3395 "run_time_permissions", new Object[] { 3601 "run_time_permissions", new Object[] {
@@ -3401,16 +3607,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3401 { 3607 {
3402 m_host.AddScriptLPS(1); 3608 m_host.AddScriptLPS(1);
3403 3609
3404 lock (m_host.TaskInventory) 3610 m_host.TaskInventory.LockItemsForRead(true);
3611
3612 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3405 { 3613 {
3406 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3614 if (item.Type == 10 && item.ItemID == m_itemID)
3407 { 3615 {
3408 if (item.Type == 10 && item.ItemID == m_itemID) 3616 m_host.TaskInventory.LockItemsForRead(false);
3409 { 3617 return item.PermsGranter.ToString();
3410 return item.PermsGranter.ToString();
3411 }
3412 } 3618 }
3413 } 3619 }
3620 m_host.TaskInventory.LockItemsForRead(false);
3414 3621
3415 return UUID.Zero.ToString(); 3622 return UUID.Zero.ToString();
3416 } 3623 }
@@ -3419,19 +3626,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3419 { 3626 {
3420 m_host.AddScriptLPS(1); 3627 m_host.AddScriptLPS(1);
3421 3628
3422 lock (m_host.TaskInventory) 3629 m_host.TaskInventory.LockItemsForRead(true);
3630
3631 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3423 { 3632 {
3424 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3633 if (item.Type == 10 && item.ItemID == m_itemID)
3425 { 3634 {
3426 if (item.Type == 10 && item.ItemID == m_itemID) 3635 int perms = item.PermsMask;
3427 { 3636 if (m_automaticLinkPermission)
3428 int perms = item.PermsMask; 3637 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3429 if (m_automaticLinkPermission) 3638 m_host.TaskInventory.LockItemsForRead(false);
3430 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3639 return perms;
3431 return perms;
3432 }
3433 } 3640 }
3434 } 3641 }
3642 m_host.TaskInventory.LockItemsForRead(false);
3435 3643
3436 return 0; 3644 return 0;
3437 } 3645 }
@@ -3464,11 +3672,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3464 UUID invItemID = InventorySelf(); 3672 UUID invItemID = InventorySelf();
3465 3673
3466 TaskInventoryItem item; 3674 TaskInventoryItem item;
3467 lock (m_host.TaskInventory) 3675 m_host.TaskInventory.LockItemsForRead(true);
3468 { 3676 item = m_host.TaskInventory[invItemID];
3469 item = m_host.TaskInventory[invItemID]; 3677 m_host.TaskInventory.LockItemsForRead(false);
3470 } 3678
3471
3472 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3679 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3473 && !m_automaticLinkPermission) 3680 && !m_automaticLinkPermission)
3474 { 3681 {
@@ -3521,16 +3728,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3521 m_host.AddScriptLPS(1); 3728 m_host.AddScriptLPS(1);
3522 UUID invItemID = InventorySelf(); 3729 UUID invItemID = InventorySelf();
3523 3730
3524 lock (m_host.TaskInventory) 3731 m_host.TaskInventory.LockItemsForRead(true);
3525 {
3526 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3732 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3527 && !m_automaticLinkPermission) 3733 && !m_automaticLinkPermission)
3528 { 3734 {
3529 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3735 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3736 m_host.TaskInventory.LockItemsForRead(false);
3530 return; 3737 return;
3531 } 3738 }
3532 } 3739 m_host.TaskInventory.LockItemsForRead(false);
3533 3740
3534 if (linknum < ScriptBaseClass.LINK_THIS) 3741 if (linknum < ScriptBaseClass.LINK_THIS)
3535 return; 3742 return;
3536 3743
@@ -3707,17 +3914,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 m_host.AddScriptLPS(1); 3914 m_host.AddScriptLPS(1);
3708 int count = 0; 3915 int count = 0;
3709 3916
3710 lock (m_host.TaskInventory) 3917 m_host.TaskInventory.LockItemsForRead(true);
3918 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3711 { 3919 {
3712 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3920 if (inv.Value.Type == type || type == -1)
3713 { 3921 {
3714 if (inv.Value.Type == type || type == -1) 3922 count = count + 1;
3715 {
3716 count = count + 1;
3717 }
3718 } 3923 }
3719 } 3924 }
3720 3925
3926 m_host.TaskInventory.LockItemsForRead(false);
3721 return count; 3927 return count;
3722 } 3928 }
3723 3929
@@ -3726,16 +3932,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 m_host.AddScriptLPS(1); 3932 m_host.AddScriptLPS(1);
3727 ArrayList keys = new ArrayList(); 3933 ArrayList keys = new ArrayList();
3728 3934
3729 lock (m_host.TaskInventory) 3935 m_host.TaskInventory.LockItemsForRead(true);
3936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3730 { 3937 {
3731 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3938 if (inv.Value.Type == type || type == -1)
3732 { 3939 {
3733 if (inv.Value.Type == type || type == -1) 3940 keys.Add(inv.Value.Name);
3734 {
3735 keys.Add(inv.Value.Name);
3736 }
3737 } 3941 }
3738 } 3942 }
3943 m_host.TaskInventory.LockItemsForRead(false);
3739 3944
3740 if (keys.Count == 0) 3945 if (keys.Count == 0)
3741 { 3946 {
@@ -3772,20 +3977,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3772 } 3977 }
3773 3978
3774 // move the first object found with this inventory name 3979 // move the first object found with this inventory name
3775 lock (m_host.TaskInventory) 3980 m_host.TaskInventory.LockItemsForRead(true);
3981 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3776 { 3982 {
3777 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3983 if (inv.Value.Name == inventory)
3778 { 3984 {
3779 if (inv.Value.Name == inventory) 3985 found = true;
3780 { 3986 objId = inv.Key;
3781 found = true; 3987 assetType = inv.Value.Type;
3782 objId = inv.Key; 3988 objName = inv.Value.Name;
3783 assetType = inv.Value.Type; 3989 break;
3784 objName = inv.Value.Name;
3785 break;
3786 }
3787 } 3990 }
3788 } 3991 }
3992 m_host.TaskInventory.LockItemsForRead(false);
3789 3993
3790 if (!found) 3994 if (!found)
3791 { 3995 {
@@ -3793,9 +3997,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3793 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 3997 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3794 } 3998 }
3795 3999
3796 // check if destination is an avatar 4000 // check if destination is an object
3797 if (World.GetScenePresence(destId) != null) 4001 if (World.GetSceneObjectPart(destId) != null)
4002 {
4003 // destination is an object
4004 World.MoveTaskInventoryItem(destId, m_host, objId);
4005 }
4006 else
3798 { 4007 {
4008 ScenePresence presence = World.GetScenePresence(destId);
4009
4010 if (presence == null)
4011 {
4012 UserAccount account =
4013 World.UserAccountService.GetUserAccount(
4014 World.RegionInfo.ScopeID,
4015 destId);
4016
4017 if (account == null)
4018 {
4019 llSay(0, "Can't find destination "+destId.ToString());
4020 return;
4021 }
4022 }
4023
3799 // destination is an avatar 4024 // destination is an avatar
3800 InventoryItemBase agentItem = 4025 InventoryItemBase agentItem =
3801 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4026 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3821,33 +4046,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3821 4046
3822 if (m_TransferModule != null) 4047 if (m_TransferModule != null)
3823 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4048 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4049
4050 //This delay should only occur when giving inventory to avatars.
4051 ScriptSleep(3000);
3824 } 4052 }
3825 else
3826 {
3827 // destination is an object
3828 World.MoveTaskInventoryItem(destId, m_host, objId);
3829 }
3830 ScriptSleep(3000);
3831 } 4053 }
3832 4054
4055 [DebuggerNonUserCode]
3833 public void llRemoveInventory(string name) 4056 public void llRemoveInventory(string name)
3834 { 4057 {
3835 m_host.AddScriptLPS(1); 4058 m_host.AddScriptLPS(1);
3836 4059
3837 lock (m_host.TaskInventory) 4060 m_host.TaskInventory.LockItemsForRead(true);
4061 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3838 { 4062 {
3839 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4063 if (item.Name == name)
3840 { 4064 {
3841 if (item.Name == name) 4065 if (item.ItemID == m_itemID)
3842 { 4066 throw new ScriptDeleteException();
3843 if (item.ItemID == m_itemID) 4067 else
3844 throw new ScriptDeleteException(); 4068 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3845 else 4069
3846 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4070 m_host.TaskInventory.LockItemsForRead(false);
3847 return; 4071 return;
3848 }
3849 } 4072 }
3850 } 4073 }
4074 m_host.TaskInventory.LockItemsForRead(false);
3851 } 4075 }
3852 4076
3853 public void llSetText(string text, LSL_Vector color, double alpha) 4077 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3938,6 +4162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3938 { 4162 {
3939 m_host.AddScriptLPS(1); 4163 m_host.AddScriptLPS(1);
3940 4164
4165 //Clone is thread safe
3941 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4166 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3942 4167
3943 foreach (TaskInventoryItem item in itemDictionary.Values) 4168 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -3991,6 +4216,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3991 ScenePresence presence = World.GetScenePresence(agentId); 4216 ScenePresence presence = World.GetScenePresence(agentId);
3992 if (presence != null) 4217 if (presence != null)
3993 { 4218 {
4219 // agent must not be a god
4220 if (presence.GodLevel >= 200) return;
4221
3994 // agent must be over the owners land 4222 // agent must be over the owners land
3995 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4223 if (m_host.OwnerID == World.LandChannel.GetLandObject(
3996 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4224 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4051,17 +4279,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4051 UUID soundId = UUID.Zero; 4279 UUID soundId = UUID.Zero;
4052 if (!UUID.TryParse(impact_sound, out soundId)) 4280 if (!UUID.TryParse(impact_sound, out soundId))
4053 { 4281 {
4054 lock (m_host.TaskInventory) 4282 m_host.TaskInventory.LockItemsForRead(true);
4283 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4055 { 4284 {
4056 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4285 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4057 { 4286 {
4058 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4287 soundId = item.AssetID;
4059 { 4288 break;
4060 soundId = item.AssetID;
4061 break;
4062 }
4063 } 4289 }
4064 } 4290 }
4291 m_host.TaskInventory.LockItemsForRead(false);
4065 } 4292 }
4066 m_host.CollisionSound = soundId; 4293 m_host.CollisionSound = soundId;
4067 m_host.CollisionSoundVolume = (float)impact_volume; 4294 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4107,6 +4334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4107 UUID partItemID; 4334 UUID partItemID;
4108 foreach (SceneObjectPart part in parts) 4335 foreach (SceneObjectPart part in parts)
4109 { 4336 {
4337 //Clone is thread safe
4110 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4338 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4111 4339
4112 foreach (TaskInventoryItem item in itemsDictionary.Values) 4340 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4321,17 +4549,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4321 4549
4322 m_host.AddScriptLPS(1); 4550 m_host.AddScriptLPS(1);
4323 4551
4324 lock (m_host.TaskInventory) 4552 m_host.TaskInventory.LockItemsForRead(true);
4553 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4325 { 4554 {
4326 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4555 if (item.Type == 10 && item.ItemID == m_itemID)
4327 { 4556 {
4328 if (item.Type == 10 && item.ItemID == m_itemID) 4557 result = item.Name!=null?item.Name:String.Empty;
4329 { 4558 break;
4330 result = item.Name != null ? item.Name : String.Empty;
4331 break;
4332 }
4333 } 4559 }
4334 } 4560 }
4561 m_host.TaskInventory.LockItemsForRead(false);
4335 4562
4336 return result; 4563 return result;
4337 } 4564 }
@@ -4484,23 +4711,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4484 { 4711 {
4485 m_host.AddScriptLPS(1); 4712 m_host.AddScriptLPS(1);
4486 4713
4487 lock (m_host.TaskInventory) 4714 m_host.TaskInventory.LockItemsForRead(true);
4715 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4488 { 4716 {
4489 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4717 if (inv.Value.Name == name)
4490 { 4718 {
4491 if (inv.Value.Name == name) 4719 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4492 { 4720 {
4493 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4721 m_host.TaskInventory.LockItemsForRead(false);
4494 { 4722 return inv.Value.AssetID.ToString();
4495 return inv.Value.AssetID.ToString(); 4723 }
4496 } 4724 else
4497 else 4725 {
4498 { 4726 m_host.TaskInventory.LockItemsForRead(false);
4499 return UUID.Zero.ToString(); 4727 return UUID.Zero.ToString();
4500 }
4501 } 4728 }
4502 } 4729 }
4503 } 4730 }
4731 m_host.TaskInventory.LockItemsForRead(false);
4504 4732
4505 return UUID.Zero.ToString(); 4733 return UUID.Zero.ToString();
4506 } 4734 }
@@ -6018,6 +6246,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6018 tempf = (float)rules.GetLSLFloatItem(i + 1); 6246 tempf = (float)rules.GetLSLFloatItem(i + 1);
6019 prules.OuterAngle = (float)tempf; 6247 prules.OuterAngle = (float)tempf;
6020 break; 6248 break;
6249
6250 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6251 tempf = (float)rules.GetLSLFloatItem(i + 1);
6252 prules.InnerAngle = (float)tempf;
6253 break;
6254
6255 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6256 tempf = (float)rules.GetLSLFloatItem(i + 1);
6257 prules.OuterAngle = (float)tempf;
6258 break;
6021 } 6259 }
6022 6260
6023 } 6261 }
@@ -6056,14 +6294,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6056 6294
6057 protected UUID GetTaskInventoryItem(string name) 6295 protected UUID GetTaskInventoryItem(string name)
6058 { 6296 {
6059 lock (m_host.TaskInventory) 6297 m_host.TaskInventory.LockItemsForRead(true);
6298 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6060 { 6299 {
6061 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6300 if (inv.Value.Name == name)
6062 { 6301 {
6063 if (inv.Value.Name == name) 6302 m_host.TaskInventory.LockItemsForRead(false);
6064 return inv.Key; 6303 return inv.Key;
6065 } 6304 }
6066 } 6305 }
6306 m_host.TaskInventory.LockItemsForRead(false);
6067 6307
6068 return UUID.Zero; 6308 return UUID.Zero;
6069 } 6309 }
@@ -6391,22 +6631,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6391 } 6631 }
6392 6632
6393 // copy the first script found with this inventory name 6633 // copy the first script found with this inventory name
6394 lock (m_host.TaskInventory) 6634 m_host.TaskInventory.LockItemsForRead(true);
6635 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6395 { 6636 {
6396 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6637 if (inv.Value.Name == name)
6397 { 6638 {
6398 if (inv.Value.Name == name) 6639 // make sure the object is a script
6640 if (10 == inv.Value.Type)
6399 { 6641 {
6400 // make sure the object is a script 6642 found = true;
6401 if (10 == inv.Value.Type) 6643 srcId = inv.Key;
6402 { 6644 break;
6403 found = true;
6404 srcId = inv.Key;
6405 break;
6406 }
6407 } 6645 }
6408 } 6646 }
6409 } 6647 }
6648 m_host.TaskInventory.LockItemsForRead(false);
6410 6649
6411 if (!found) 6650 if (!found)
6412 { 6651 {
@@ -6490,6 +6729,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6490 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6729 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6491 { 6730 {
6492 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6731 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6732 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6733 return shapeBlock;
6493 6734
6494 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6735 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6495 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6736 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6560,6 +6801,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6560 6801
6561 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6802 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6562 { 6803 {
6804 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6805 return;
6806
6563 ObjectShapePacket.ObjectDataBlock shapeBlock; 6807 ObjectShapePacket.ObjectDataBlock shapeBlock;
6564 6808
6565 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6809 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6609,6 +6853,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6609 6853
6610 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6854 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6611 { 6855 {
6856 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6857 return;
6858
6612 ObjectShapePacket.ObjectDataBlock shapeBlock; 6859 ObjectShapePacket.ObjectDataBlock shapeBlock;
6613 6860
6614 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6861 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6651,6 +6898,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6651 6898
6652 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) 6899 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)
6653 { 6900 {
6901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6902 return;
6903
6654 ObjectShapePacket.ObjectDataBlock shapeBlock; 6904 ObjectShapePacket.ObjectDataBlock shapeBlock;
6655 6905
6656 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6906 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6772,6 +7022,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6772 7022
6773 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7023 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6774 { 7024 {
7025 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7026 return;
7027
6775 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7028 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6776 UUID sculptId; 7029 UUID sculptId;
6777 7030
@@ -6812,7 +7065,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6812 7065
6813 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7066 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6814 { 7067 {
6815 m_host.AddScriptLPS(1); 7068 m_host.AddScriptLPS(1);
6816 7069
6817 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7070 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6818 7071
@@ -6827,6 +7080,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6827 7080
6828 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7081 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6829 { 7082 {
7083 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7084 return;
7085
6830 int idx = 0; 7086 int idx = 0;
6831 7087
6832 while (idx < rules.Length) 7088 while (idx < rules.Length)
@@ -7658,24 +7914,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7658 break; 7914 break;
7659 7915
7660 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 7916 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7661 // TODO--------------
7662 if (remain < 1) 7917 if (remain < 1)
7663 return res; 7918 return res;
7919 face = (int)rules.GetLSLIntegerItem(idx++);
7664 7920
7665 face=(int)rules.GetLSLIntegerItem(idx++); 7921 tex = part.Shape.Textures;
7666 7922 int shiny;
7667 res.Add(new LSL_Integer(0)); 7923 if (face == ScriptBaseClass.ALL_SIDES)
7668 res.Add(new LSL_Integer(0)); 7924 {
7925 for (face = 0; face < GetNumberOfSides(part); face++)
7926 {
7927 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7928 if (shinyness == Shininess.High)
7929 {
7930 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7931 }
7932 else if (shinyness == Shininess.Medium)
7933 {
7934 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
7935 }
7936 else if (shinyness == Shininess.Low)
7937 {
7938 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
7939 }
7940 else
7941 {
7942 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7943 }
7944 res.Add(new LSL_Integer(shiny));
7945 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7946 }
7947 }
7948 else
7949 {
7950 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7951 if (shinyness == Shininess.High)
7952 {
7953 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7954 }
7955 else if (shinyness == Shininess.Medium)
7956 {
7957 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
7958 }
7959 else if (shinyness == Shininess.Low)
7960 {
7961 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
7962 }
7963 else
7964 {
7965 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7966 }
7967 res.Add(new LSL_Integer(shiny));
7968 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7969 }
7669 break; 7970 break;
7670 7971
7671 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 7972 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7672 // TODO--------------
7673 if (remain < 1) 7973 if (remain < 1)
7674 return res; 7974 return res;
7975 face = (int)rules.GetLSLIntegerItem(idx++);
7675 7976
7676 face=(int)rules.GetLSLIntegerItem(idx++); 7977 tex = part.Shape.Textures;
7677 7978 int fullbright;
7678 res.Add(new LSL_Integer(0)); 7979 if (face == ScriptBaseClass.ALL_SIDES)
7980 {
7981 for (face = 0; face < GetNumberOfSides(part); face++)
7982 {
7983 if (tex.GetFace((uint)face).Fullbright == true)
7984 {
7985 fullbright = ScriptBaseClass.TRUE;
7986 }
7987 else
7988 {
7989 fullbright = ScriptBaseClass.FALSE;
7990 }
7991 res.Add(new LSL_Integer(fullbright));
7992 }
7993 }
7994 else
7995 {
7996 if (tex.GetFace((uint)face).Fullbright == true)
7997 {
7998 fullbright = ScriptBaseClass.TRUE;
7999 }
8000 else
8001 {
8002 fullbright = ScriptBaseClass.FALSE;
8003 }
8004 res.Add(new LSL_Integer(fullbright));
8005 }
7679 break; 8006 break;
7680 8007
7681 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8008 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7696,14 +8023,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7696 break; 8023 break;
7697 8024
7698 case (int)ScriptBaseClass.PRIM_TEXGEN: 8025 case (int)ScriptBaseClass.PRIM_TEXGEN:
7699 // TODO--------------
7700 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8026 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7701 if (remain < 1) 8027 if (remain < 1)
7702 return res; 8028 return res;
8029 face = (int)rules.GetLSLIntegerItem(idx++);
7703 8030
7704 face=(int)rules.GetLSLIntegerItem(idx++); 8031 tex = part.Shape.Textures;
7705 8032 if (face == ScriptBaseClass.ALL_SIDES)
7706 res.Add(new LSL_Integer(0)); 8033 {
8034 for (face = 0; face < GetNumberOfSides(part); face++)
8035 {
8036 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8037 {
8038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8039 }
8040 else
8041 {
8042 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8043 }
8044 }
8045 }
8046 else
8047 {
8048 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8049 {
8050 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8051 }
8052 else
8053 {
8054 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8055 }
8056 }
7707 break; 8057 break;
7708 8058
7709 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8059 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7722,13 +8072,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7722 break; 8072 break;
7723 8073
7724 case (int)ScriptBaseClass.PRIM_GLOW: 8074 case (int)ScriptBaseClass.PRIM_GLOW:
7725 // TODO--------------
7726 if (remain < 1) 8075 if (remain < 1)
7727 return res; 8076 return res;
8077 face = (int)rules.GetLSLIntegerItem(idx++);
7728 8078
7729 face=(int)rules.GetLSLIntegerItem(idx++); 8079 tex = part.Shape.Textures;
7730 8080 float primglow;
7731 res.Add(new LSL_Float(0)); 8081 if (face == ScriptBaseClass.ALL_SIDES)
8082 {
8083 for (face = 0; face < GetNumberOfSides(part); face++)
8084 {
8085 primglow = tex.GetFace((uint)face).Glow;
8086 res.Add(new LSL_Float(primglow));
8087 }
8088 }
8089 else
8090 {
8091 primglow = tex.GetFace((uint)face).Glow;
8092 res.Add(new LSL_Float(primglow));
8093 }
7732 break; 8094 break;
7733 case (int)ScriptBaseClass.PRIM_TEXT: 8095 case (int)ScriptBaseClass.PRIM_TEXT:
7734 Color4 textColor = part.GetTextColor(); 8096 Color4 textColor = part.GetTextColor();
@@ -8265,28 +8627,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8265 { 8627 {
8266 m_host.AddScriptLPS(1); 8628 m_host.AddScriptLPS(1);
8267 8629
8268 lock (m_host.TaskInventory) 8630 m_host.TaskInventory.LockItemsForRead(true);
8631 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8269 { 8632 {
8270 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8633 if (inv.Value.Name == item)
8271 { 8634 {
8272 if (inv.Value.Name == item) 8635 m_host.TaskInventory.LockItemsForRead(false);
8636 switch (mask)
8273 { 8637 {
8274 switch (mask) 8638 case 0:
8275 { 8639 return (int)inv.Value.BasePermissions;
8276 case 0: 8640 case 1:
8277 return (int)inv.Value.BasePermissions; 8641 return (int)inv.Value.CurrentPermissions;
8278 case 1: 8642 case 2:
8279 return (int)inv.Value.CurrentPermissions; 8643 return (int)inv.Value.GroupPermissions;
8280 case 2: 8644 case 3:
8281 return (int)inv.Value.GroupPermissions; 8645 return (int)inv.Value.EveryonePermissions;
8282 case 3: 8646 case 4:
8283 return (int)inv.Value.EveryonePermissions; 8647 return (int)inv.Value.NextPermissions;
8284 case 4:
8285 return (int)inv.Value.NextPermissions;
8286 }
8287 } 8648 }
8288 } 8649 }
8289 } 8650 }
8651 m_host.TaskInventory.LockItemsForRead(false);
8290 8652
8291 return -1; 8653 return -1;
8292 } 8654 }
@@ -8333,16 +8695,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8333 { 8695 {
8334 m_host.AddScriptLPS(1); 8696 m_host.AddScriptLPS(1);
8335 8697
8336 lock (m_host.TaskInventory) 8698 m_host.TaskInventory.LockItemsForRead(true);
8699 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8337 { 8700 {
8338 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8701 if (inv.Value.Name == item)
8339 { 8702 {
8340 if (inv.Value.Name == item) 8703 m_host.TaskInventory.LockItemsForRead(false);
8341 { 8704 return inv.Value.CreatorID.ToString();
8342 return inv.Value.CreatorID.ToString();
8343 }
8344 } 8705 }
8345 } 8706 }
8707 m_host.TaskInventory.LockItemsForRead(false);
8346 8708
8347 llSay(0, "No item name '" + item + "'"); 8709 llSay(0, "No item name '" + item + "'");
8348 8710
@@ -8875,16 +9237,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8875 { 9237 {
8876 m_host.AddScriptLPS(1); 9238 m_host.AddScriptLPS(1);
8877 9239
8878 lock (m_host.TaskInventory) 9240 m_host.TaskInventory.LockItemsForRead(true);
9241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8879 { 9242 {
8880 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9243 if (inv.Value.Name == name)
8881 { 9244 {
8882 if (inv.Value.Name == name) 9245 m_host.TaskInventory.LockItemsForRead(false);
8883 { 9246 return inv.Value.Type;
8884 return inv.Value.Type;
8885 }
8886 } 9247 }
8887 } 9248 }
9249 m_host.TaskInventory.LockItemsForRead(false);
8888 9250
8889 return -1; 9251 return -1;
8890 } 9252 }
@@ -8895,15 +9257,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8895 9257
8896 if (quick_pay_buttons.Data.Length < 4) 9258 if (quick_pay_buttons.Data.Length < 4)
8897 { 9259 {
8898 LSLError("List must have at least 4 elements"); 9260 int x;
8899 return; 9261 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9262 {
9263 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9264 }
8900 } 9265 }
8901 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9266 int[] nPrice = new int[5];
8902 9267 nPrice[0]=price;
8903 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9268 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8904 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9269 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8905 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9270 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8906 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9271 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9272 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8907 m_host.ParentGroup.HasGroupChanged = true; 9273 m_host.ParentGroup.HasGroupChanged = true;
8908 } 9274 }
8909 9275
@@ -8915,17 +9281,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8915 if (invItemID == UUID.Zero) 9281 if (invItemID == UUID.Zero)
8916 return new LSL_Vector(); 9282 return new LSL_Vector();
8917 9283
8918 lock (m_host.TaskInventory) 9284 m_host.TaskInventory.LockItemsForRead(true);
9285 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8919 { 9286 {
8920 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9287 m_host.TaskInventory.LockItemsForRead(false);
8921 return new LSL_Vector(); 9288 return new LSL_Vector();
9289 }
8922 9290
8923 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9291 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8924 { 9292 {
8925 ShoutError("No permissions to track the camera"); 9293 ShoutError("No permissions to track the camera");
8926 return new LSL_Vector(); 9294 m_host.TaskInventory.LockItemsForRead(false);
8927 } 9295 return new LSL_Vector();
8928 } 9296 }
9297 m_host.TaskInventory.LockItemsForRead(false);
8929 9298
8930 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9299 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8931 if (presence != null) 9300 if (presence != null)
@@ -8943,17 +9312,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8943 if (invItemID == UUID.Zero) 9312 if (invItemID == UUID.Zero)
8944 return new LSL_Rotation(); 9313 return new LSL_Rotation();
8945 9314
8946 lock (m_host.TaskInventory) 9315 m_host.TaskInventory.LockItemsForRead(true);
9316 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8947 { 9317 {
8948 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9318 m_host.TaskInventory.LockItemsForRead(false);
8949 return new LSL_Rotation(); 9319 return new LSL_Rotation();
8950 9320 }
8951 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9321 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8952 { 9322 {
8953 ShoutError("No permissions to track the camera"); 9323 ShoutError("No permissions to track the camera");
8954 return new LSL_Rotation(); 9324 m_host.TaskInventory.LockItemsForRead(false);
8955 } 9325 return new LSL_Rotation();
8956 } 9326 }
9327 m_host.TaskInventory.LockItemsForRead(false);
8957 9328
8958 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9329 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8959 if (presence != null) 9330 if (presence != null)
@@ -9103,14 +9474,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9103 if (objectID == UUID.Zero) return; 9474 if (objectID == UUID.Zero) return;
9104 9475
9105 UUID agentID; 9476 UUID agentID;
9106 lock (m_host.TaskInventory) 9477 m_host.TaskInventory.LockItemsForRead(true);
9107 { 9478 // we need the permission first, to know which avatar we want to set the camera for
9108 // we need the permission first, to know which avatar we want to set the camera for 9479 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9109 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9110 9480
9111 if (agentID == UUID.Zero) return; 9481 if (agentID == UUID.Zero)
9112 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9482 {
9483 m_host.TaskInventory.LockItemsForRead(false);
9484 return;
9485 }
9486 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9487 {
9488 m_host.TaskInventory.LockItemsForRead(false);
9489 return;
9113 } 9490 }
9491 m_host.TaskInventory.LockItemsForRead(false);
9114 9492
9115 ScenePresence presence = World.GetScenePresence(agentID); 9493 ScenePresence presence = World.GetScenePresence(agentID);
9116 9494
@@ -9160,12 +9538,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9160 9538
9161 // we need the permission first, to know which avatar we want to clear the camera for 9539 // we need the permission first, to know which avatar we want to clear the camera for
9162 UUID agentID; 9540 UUID agentID;
9163 lock (m_host.TaskInventory) 9541 m_host.TaskInventory.LockItemsForRead(true);
9542 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9543 if (agentID == UUID.Zero)
9164 { 9544 {
9165 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9545 m_host.TaskInventory.LockItemsForRead(false);
9166 if (agentID == UUID.Zero) return; 9546 return;
9167 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9168 } 9547 }
9548 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9549 {
9550 m_host.TaskInventory.LockItemsForRead(false);
9551 return;
9552 }
9553 m_host.TaskInventory.LockItemsForRead(false);
9169 9554
9170 ScenePresence presence = World.GetScenePresence(agentID); 9555 ScenePresence presence = World.GetScenePresence(agentID);
9171 9556
@@ -9622,15 +10007,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9622 10007
9623 internal UUID ScriptByName(string name) 10008 internal UUID ScriptByName(string name)
9624 { 10009 {
9625 lock (m_host.TaskInventory) 10010 m_host.TaskInventory.LockItemsForRead(true);
10011
10012 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9626 { 10013 {
9627 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10014 if (item.Type == 10 && item.Name == name)
9628 { 10015 {
9629 if (item.Type == 10 && item.Name == name) 10016 m_host.TaskInventory.LockItemsForRead(false);
9630 return item.ItemID; 10017 return item.ItemID;
9631 } 10018 }
9632 } 10019 }
9633 10020
10021 m_host.TaskInventory.LockItemsForRead(false);
10022
9634 return UUID.Zero; 10023 return UUID.Zero;
9635 } 10024 }
9636 10025
@@ -9671,6 +10060,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9671 { 10060 {
9672 m_host.AddScriptLPS(1); 10061 m_host.AddScriptLPS(1);
9673 10062
10063 //Clone is thread safe
9674 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10064 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9675 10065
9676 UUID assetID = UUID.Zero; 10066 UUID assetID = UUID.Zero;
@@ -9733,6 +10123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9733 { 10123 {
9734 m_host.AddScriptLPS(1); 10124 m_host.AddScriptLPS(1);
9735 10125
10126 //Clone is thread safe
9736 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10127 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9737 10128
9738 UUID assetID = UUID.Zero; 10129 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 15469db..942e4ef 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -719,18 +719,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
719 if (target != null) 719 if (target != null)
720 { 720 {
721 UUID animID=UUID.Zero; 721 UUID animID=UUID.Zero;
722 lock (m_host.TaskInventory) 722 m_host.TaskInventory.LockItemsForRead(true);
723 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
723 { 724 {
724 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 725 if (inv.Value.Name == animation)
725 { 726 {
726 if (inv.Value.Name == animation) 727 if (inv.Value.Type == (int)AssetType.Animation)
727 { 728 animID = inv.Value.AssetID;
728 if (inv.Value.Type == (int)AssetType.Animation) 729 continue;
729 animID = inv.Value.AssetID;
730 continue;
731 }
732 } 730 }
733 } 731 }
732 m_host.TaskInventory.LockItemsForRead(false);
734 if (animID == UUID.Zero) 733 if (animID == UUID.Zero)
735 target.Animator.AddAnimation(animation, m_host.UUID); 734 target.Animator.AddAnimation(animation, m_host.UUID);
736 else 735 else
@@ -752,18 +751,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
752 if (target != null) 751 if (target != null)
753 { 752 {
754 UUID animID=UUID.Zero; 753 UUID animID=UUID.Zero;
755 lock (m_host.TaskInventory) 754 m_host.TaskInventory.LockItemsForRead(true);
755 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
756 { 756 {
757 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 757 if (inv.Value.Name == animation)
758 { 758 {
759 if (inv.Value.Name == animation) 759 if (inv.Value.Type == (int)AssetType.Animation)
760 { 760 animID = inv.Value.AssetID;
761 if (inv.Value.Type == (int)AssetType.Animation) 761 continue;
762 animID = inv.Value.AssetID;
763 continue;
764 }
765 } 762 }
766 } 763 }
764 m_host.TaskInventory.LockItemsForRead(false);
767 765
768 if (animID == UUID.Zero) 766 if (animID == UUID.Zero)
769 target.Animator.RemoveAnimation(animation); 767 target.Animator.RemoveAnimation(animation);
@@ -1614,6 +1612,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1614 1612
1615 if (!UUID.TryParse(name, out assetID)) 1613 if (!UUID.TryParse(name, out assetID))
1616 { 1614 {
1615 m_host.TaskInventory.LockItemsForRead(true);
1617 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1616 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1618 { 1617 {
1619 if (item.Type == 7 && item.Name == name) 1618 if (item.Type == 7 && item.Name == name)
@@ -1621,6 +1620,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1621 assetID = item.AssetID; 1620 assetID = item.AssetID;
1622 } 1621 }
1623 } 1622 }
1623 m_host.TaskInventory.LockItemsForRead(false);
1624 } 1624 }
1625 1625
1626 if (assetID == UUID.Zero) 1626 if (assetID == UUID.Zero)
@@ -1667,6 +1667,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1667 1667
1668 if (!UUID.TryParse(name, out assetID)) 1668 if (!UUID.TryParse(name, out assetID))
1669 { 1669 {
1670 m_host.TaskInventory.LockItemsForRead(true);
1670 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1671 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1671 { 1672 {
1672 if (item.Type == 7 && item.Name == name) 1673 if (item.Type == 7 && item.Name == name)
@@ -1674,6 +1675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1674 assetID = item.AssetID; 1675 assetID = item.AssetID;
1675 } 1676 }
1676 } 1677 }
1678 m_host.TaskInventory.LockItemsForRead(false);
1677 } 1679 }
1678 1680
1679 if (assetID == UUID.Zero) 1681 if (assetID == UUID.Zero)
@@ -1724,6 +1726,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 1726
1725 if (!UUID.TryParse(name, out assetID)) 1727 if (!UUID.TryParse(name, out assetID))
1726 { 1728 {
1729 m_host.TaskInventory.LockItemsForRead(true);
1727 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1730 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1728 { 1731 {
1729 if (item.Type == 7 && item.Name == name) 1732 if (item.Type == 7 && item.Name == name)
@@ -1731,6 +1734,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1731 assetID = item.AssetID; 1734 assetID = item.AssetID;
1732 } 1735 }
1733 } 1736 }
1737 m_host.TaskInventory.LockItemsForRead(false);
1734 } 1738 }
1735 1739
1736 if (assetID == UUID.Zero) 1740 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/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
index f13b6e5..fba27f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -44,5 +44,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
44 LSL_List cmGetWindlightScene(LSL_List rules); 44 LSL_List cmGetWindlightScene(LSL_List rules);
45 int cmSetWindlightScene(LSL_List rules); 45 int cmSetWindlightScene(LSL_List rules);
46 int cmSetWindlightSceneTargeted(LSL_List rules, key target); 46 int cmSetWindlightSceneTargeted(LSL_List rules, key target);
47 LSL_List cmGetAvatarList();
47 } 48 }
48} 49}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 7a8f469..9dbd369 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -80,7 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
80 // Avatar Info Commands 80 // Avatar Info Commands
81 string osGetAgentIP(string agent); 81 string osGetAgentIP(string agent);
82 LSL_List osGetAgents(); 82 LSL_List osGetAgents();
83 83
84 // Teleport commands 84 // Teleport commands
85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
86 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 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/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
index c0edaae..aaffbe4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -72,5 +72,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); 73 return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target);
74 } 74 }
75 public LSL_List cmGetAvatarList()
76 {
77 return m_CM_Functions.cmGetAvatarList();
78 }
75 } 79 }
76} 80}
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/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/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 54074ed..463b052 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 =
@@ -123,6 +126,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
123 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); 126 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 128
129 private void lockScriptsForRead(bool locked)
130 {
131 if (locked)
132 {
133 if (m_scriptsLock.RecursiveReadCount > 0)
134 {
135 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.");
136 m_scriptsLock.ExitReadLock();
137 }
138 if (m_scriptsLock.RecursiveWriteCount > 0)
139 {
140 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
141 m_scriptsLock.ExitWriteLock();
142 }
143
144 while (!m_scriptsLock.TryEnterReadLock(60000))
145 {
146 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.");
147 if (m_scriptsLock.IsWriteLockHeld)
148 {
149 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
150 }
151 }
152 }
153 else
154 {
155 if (m_scriptsLock.RecursiveReadCount > 0)
156 {
157 m_scriptsLock.ExitReadLock();
158 }
159 }
160 }
161 private void lockScriptsForWrite(bool locked)
162 {
163 if (locked)
164 {
165 if (m_scriptsLock.RecursiveReadCount > 0)
166 {
167 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.");
168 m_scriptsLock.ExitReadLock();
169 }
170 if (m_scriptsLock.RecursiveWriteCount > 0)
171 {
172 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
173 m_scriptsLock.ExitWriteLock();
174 }
175
176 while (!m_scriptsLock.TryEnterWriteLock(60000))
177 {
178 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.");
179 if (m_scriptsLock.IsWriteLockHeld)
180 {
181 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
182 }
183 }
184 }
185 else
186 {
187 if (m_scriptsLock.RecursiveWriteCount > 0)
188 {
189 m_scriptsLock.ExitWriteLock();
190 }
191 }
192 }
193
126 public string ScriptEngineName 194 public string ScriptEngineName
127 { 195 {
128 get { return "XEngine"; } 196 get { return "XEngine"; }
@@ -262,43 +330,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
262 330
263 public void RemoveRegion(Scene scene) 331 public void RemoveRegion(Scene scene)
264 { 332 {
265 lock (m_Scripts) 333 lockScriptsForRead(true);
334 foreach (IScriptInstance instance in m_Scripts.Values)
266 { 335 {
267 foreach (IScriptInstance instance in m_Scripts.Values) 336 // Force a final state save
337 //
338 if (m_Assemblies.ContainsKey(instance.AssetID))
268 { 339 {
269 // Force a final state save 340 string assembly = m_Assemblies[instance.AssetID];
270 // 341 instance.SaveState(assembly);
271 if (m_Assemblies.ContainsKey(instance.AssetID)) 342 }
272 {
273 string assembly = m_Assemblies[instance.AssetID];
274 instance.SaveState(assembly);
275 }
276 343
277 // Clear the event queue and abort the instance thread 344 // Clear the event queue and abort the instance thread
278 // 345 //
279 instance.ClearQueue(); 346 instance.ClearQueue();
280 instance.Stop(0); 347 instance.Stop(0);
281 348
282 // Release events, timer, etc 349 // Release events, timer, etc
283 // 350 //
284 instance.DestroyScriptInstance(); 351 instance.DestroyScriptInstance();
285 352
286 // Unload scripts and app domains 353 // Unload scripts and app domains
287 // Must be done explicitly because they have infinite 354 // Must be done explicitly because they have infinite
288 // lifetime 355 // lifetime
289 // 356 //
290 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 357 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
291 if (m_DomainScripts[instance.AppDomain].Count == 0) 358 if (m_DomainScripts[instance.AppDomain].Count == 0)
292 { 359 {
293 m_DomainScripts.Remove(instance.AppDomain); 360 m_DomainScripts.Remove(instance.AppDomain);
294 UnloadAppDomain(instance.AppDomain); 361 UnloadAppDomain(instance.AppDomain);
295 }
296 } 362 }
297 m_Scripts.Clear();
298 m_PrimObjects.Clear();
299 m_Assemblies.Clear();
300 m_DomainScripts.Clear();
301 } 363 }
364 lockScriptsForRead(false);
365 lockScriptsForWrite(true);
366 m_Scripts.Clear();
367 lockScriptsForWrite(false);
368 m_PrimObjects.Clear();
369 m_Assemblies.Clear();
370 m_DomainScripts.Clear();
371
302 lock (m_ScriptEngines) 372 lock (m_ScriptEngines)
303 { 373 {
304 m_ScriptEngines.Remove(this); 374 m_ScriptEngines.Remove(this);
@@ -357,22 +427,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
357 427
358 List<IScriptInstance> instances = new List<IScriptInstance>(); 428 List<IScriptInstance> instances = new List<IScriptInstance>();
359 429
360 lock (m_Scripts) 430 lockScriptsForRead(true);
361 { 431 foreach (IScriptInstance instance in m_Scripts.Values)
362 foreach (IScriptInstance instance in m_Scripts.Values)
363 instances.Add(instance); 432 instances.Add(instance);
364 } 433 lockScriptsForRead(false);
365 434
366 foreach (IScriptInstance i in instances) 435 foreach (IScriptInstance i in instances)
367 { 436 {
368 string assembly = String.Empty; 437 string assembly = String.Empty;
369 438
370 lock (m_Scripts) 439
371 {
372 if (!m_Assemblies.ContainsKey(i.AssetID)) 440 if (!m_Assemblies.ContainsKey(i.AssetID))
373 continue; 441 continue;
374 assembly = m_Assemblies[i.AssetID]; 442 assembly = m_Assemblies[i.AssetID];
375 } 443
376 444
377 i.SaveState(assembly); 445 i.SaveState(assembly);
378 } 446 }
@@ -684,170 +752,181 @@ namespace OpenSim.Region.ScriptEngine.XEngine
684 } 752 }
685 } 753 }
686 754
687 lock (m_Scripts) 755
756
757 ScriptInstance instance = null;
758 // Create the object record
759 lockScriptsForRead(true);
760 if ((!m_Scripts.ContainsKey(itemID)) ||
761 (m_Scripts[itemID].AssetID != assetID))
688 { 762 {
689 ScriptInstance instance = null; 763 lockScriptsForRead(false);
690 // Create the object record
691 764
692 if ((!m_Scripts.ContainsKey(itemID)) || 765 UUID appDomain = assetID;
693 (m_Scripts[itemID].AssetID != assetID))
694 {
695 UUID appDomain = assetID;
696 766
697 if (part.ParentGroup.IsAttachment) 767 if (part.ParentGroup.IsAttachment)
698 appDomain = part.ParentGroup.RootPart.UUID; 768 appDomain = part.ParentGroup.RootPart.UUID;
699 769
700 if (!m_AppDomains.ContainsKey(appDomain)) 770 if (!m_AppDomains.ContainsKey(appDomain))
771 {
772 try
701 { 773 {
702 try 774 AppDomainSetup appSetup = new AppDomainSetup();
703 { 775 // appSetup.ApplicationBase = Path.Combine(
704 AppDomainSetup appSetup = new AppDomainSetup(); 776 // "ScriptEngines",
705// appSetup.ApplicationBase = Path.Combine( 777 // m_Scene.RegionInfo.RegionID.ToString());
706// "ScriptEngines", 778
707// m_Scene.RegionInfo.RegionID.ToString()); 779 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
708 780 Evidence evidence = new Evidence(baseEvidence);
709 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 781
710 Evidence evidence = new Evidence(baseEvidence); 782 AppDomain sandbox;
711 783 if (m_AppDomainLoading)
712 AppDomain sandbox; 784 sandbox = AppDomain.CreateDomain(
713 if (m_AppDomainLoading) 785 m_Scene.RegionInfo.RegionID.ToString(),
714 sandbox = AppDomain.CreateDomain( 786 evidence, appSetup);
715 m_Scene.RegionInfo.RegionID.ToString(), 787 else
716 evidence, appSetup); 788 sandbox = AppDomain.CurrentDomain;
717 else 789
718 sandbox = AppDomain.CurrentDomain; 790 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
719 791 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
720 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 792 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
721 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 793 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
722 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 794 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
723 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 795 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
724 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 796 //sandbox.SetAppDomainPolicy(sandboxPolicy);
725 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 797
726 //sandbox.SetAppDomainPolicy(sandboxPolicy); 798 m_AppDomains[appDomain] = sandbox;
727 799
728 m_AppDomains[appDomain] = sandbox; 800 m_AppDomains[appDomain].AssemblyResolve +=
729 801 new ResolveEventHandler(
730 m_AppDomains[appDomain].AssemblyResolve += 802 AssemblyResolver.OnAssemblyResolve);
731 new ResolveEventHandler( 803 m_DomainScripts[appDomain] = new List<UUID>();
732 AssemblyResolver.OnAssemblyResolve);
733 m_DomainScripts[appDomain] = new List<UUID>();
734 }
735 catch (Exception e)
736 {
737 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
738 m_ScriptErrorMessage += "Exception creating app domain:\n";
739 m_ScriptFailCount++;
740 lock (m_AddingAssemblies)
741 {
742 m_AddingAssemblies[assembly]--;
743 }
744 return false;
745 }
746 } 804 }
747 m_DomainScripts[appDomain].Add(itemID); 805 catch (Exception e)
748
749 instance = new ScriptInstance(this, part,
750 itemID, assetID, assembly,
751 m_AppDomains[appDomain],
752 part.ParentGroup.RootPart.Name,
753 item.Name, startParam, postOnRez,
754 stateSource, m_MaxScriptQueue);
755
756 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
757 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
758
759 if (presence != null)
760 { 806 {
761 ShowScriptSaveResponse(item.OwnerID, 807 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
762 assetID, "Compile successful", true); 808 m_ScriptErrorMessage += "Exception creating app domain:\n";
809 m_ScriptFailCount++;
810 lock (m_AddingAssemblies)
811 {
812 m_AddingAssemblies[assembly]--;
813 }
814 return false;
763 } 815 }
816 }
817 m_DomainScripts[appDomain].Add(itemID);
764 818
765 instance.AppDomain = appDomain; 819 instance = new ScriptInstance(this, part,
766 instance.LineMap = linemap; 820 itemID, assetID, assembly,
821 m_AppDomains[appDomain],
822 part.ParentGroup.RootPart.Name,
823 item.Name, startParam, postOnRez,
824 stateSource, m_MaxScriptQueue);
767 825
768 m_Scripts[itemID] = instance; 826 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
769 } 827 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
770 828
771 lock (m_PrimObjects) 829 if (presence != null)
772 { 830 {
773 if (!m_PrimObjects.ContainsKey(localID)) 831 ShowScriptSaveResponse(item.OwnerID,
774 m_PrimObjects[localID] = new List<UUID>(); 832 assetID, "Compile successful", true);
833 }
775 834
776 if (!m_PrimObjects[localID].Contains(itemID)) 835 instance.AppDomain = appDomain;
777 m_PrimObjects[localID].Add(itemID); 836 instance.LineMap = linemap;
837 lockScriptsForWrite(true);
838 m_Scripts[itemID] = instance;
839 lockScriptsForWrite(false);
840 }
841 else
842 {
843 lockScriptsForRead(false);
844 }
845 lock (m_PrimObjects)
846 {
847 if (!m_PrimObjects.ContainsKey(localID))
848 m_PrimObjects[localID] = new List<UUID>();
778 849
779 } 850 if (!m_PrimObjects[localID].Contains(itemID))
851 m_PrimObjects[localID].Add(itemID);
780 852
781 if (!m_Assemblies.ContainsKey(assetID)) 853 }
782 m_Assemblies[assetID] = assembly;
783 854
784 lock (m_AddingAssemblies) 855 if (!m_Assemblies.ContainsKey(assetID))
785 { 856 m_Assemblies[assetID] = assembly;
786 m_AddingAssemblies[assembly]--;
787 }
788 857
789 if (instance!=null) 858 lock (m_AddingAssemblies)
790 instance.Init(); 859 {
860 m_AddingAssemblies[assembly]--;
791 } 861 }
862
863 if (instance!=null)
864 instance.Init();
865
792 return true; 866 return true;
793 } 867 }
794 868
795 public void OnRemoveScript(uint localID, UUID itemID) 869 public void OnRemoveScript(uint localID, UUID itemID)
796 { 870 {
797 lock (m_Scripts) 871 lockScriptsForRead(true);
872 // Do we even have it?
873 if (!m_Scripts.ContainsKey(itemID))
798 { 874 {
799 // Do we even have it? 875 lockScriptsForRead(false);
800 if (!m_Scripts.ContainsKey(itemID)) 876 return;
801 return; 877 }
802 878
803 IScriptInstance instance=m_Scripts[itemID];
804 m_Scripts.Remove(itemID);
805 879
806 instance.ClearQueue(); 880 IScriptInstance instance=m_Scripts[itemID];
807 instance.Stop(0); 881 lockScriptsForRead(false);
882 lockScriptsForWrite(true);
883 m_Scripts.Remove(itemID);
884 lockScriptsForWrite(false);
885 instance.ClearQueue();
886 instance.Stop(0);
808 887
809// bool objectRemoved = false; 888// bool objectRemoved = false;
810 889
811 lock (m_PrimObjects) 890 lock (m_PrimObjects)
891 {
892 // Remove the script from it's prim
893 if (m_PrimObjects.ContainsKey(localID))
812 { 894 {
813 // Remove the script from it's prim 895 // Remove inventory item record
814 if (m_PrimObjects.ContainsKey(localID)) 896 if (m_PrimObjects[localID].Contains(itemID))
815 { 897 m_PrimObjects[localID].Remove(itemID);
816 // Remove inventory item record
817 if (m_PrimObjects[localID].Contains(itemID))
818 m_PrimObjects[localID].Remove(itemID);
819 898
820 // If there are no more scripts, remove prim 899 // If there are no more scripts, remove prim
821 if (m_PrimObjects[localID].Count == 0) 900 if (m_PrimObjects[localID].Count == 0)
822 { 901 {
823 m_PrimObjects.Remove(localID); 902 m_PrimObjects.Remove(localID);
824// objectRemoved = true; 903// objectRemoved = true;
825 }
826 } 904 }
827 } 905 }
906 }
828 907
829 instance.RemoveState(); 908 instance.RemoveState();
830 instance.DestroyScriptInstance(); 909 instance.DestroyScriptInstance();
831
832 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
833 if (m_DomainScripts[instance.AppDomain].Count == 0)
834 {
835 m_DomainScripts.Remove(instance.AppDomain);
836 UnloadAppDomain(instance.AppDomain);
837 }
838 910
839 instance = null; 911 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
912 if (m_DomainScripts[instance.AppDomain].Count == 0)
913 {
914 m_DomainScripts.Remove(instance.AppDomain);
915 UnloadAppDomain(instance.AppDomain);
916 }
840 917
841 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 918 instance = null;
842 if (handlerObjectRemoved != null)
843 {
844 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
845 handlerObjectRemoved(part.UUID);
846 }
847 919
848 CleanAssemblies(); 920 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
921 if (handlerObjectRemoved != null)
922 {
923 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
924 handlerObjectRemoved(part.UUID);
849 } 925 }
850 926
927 CleanAssemblies();
928
929
851 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 930 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
852 if (handlerScriptRemoved != null) 931 if (handlerScriptRemoved != null)
853 handlerScriptRemoved(itemID); 932 handlerScriptRemoved(itemID);
@@ -1099,12 +1178,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1099 private IScriptInstance GetInstance(UUID itemID) 1178 private IScriptInstance GetInstance(UUID itemID)
1100 { 1179 {
1101 IScriptInstance instance; 1180 IScriptInstance instance;
1102 lock (m_Scripts) 1181 lockScriptsForRead(true);
1182 if (!m_Scripts.ContainsKey(itemID))
1103 { 1183 {
1104 if (!m_Scripts.ContainsKey(itemID)) 1184 lockScriptsForRead(false);
1105 return null; 1185 return null;
1106 instance = m_Scripts[itemID];
1107 } 1186 }
1187 instance = m_Scripts[itemID];
1188 lockScriptsForRead(false);
1108 return instance; 1189 return instance;
1109 } 1190 }
1110 1191
@@ -1128,6 +1209,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1128 return false; 1209 return false;
1129 } 1210 }
1130 1211
1212 [DebuggerNonUserCode]
1131 public void ApiResetScript(UUID itemID) 1213 public void ApiResetScript(UUID itemID)
1132 { 1214 {
1133 IScriptInstance instance = GetInstance(itemID); 1215 IScriptInstance instance = GetInstance(itemID);
@@ -1179,6 +1261,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1179 return UUID.Zero; 1261 return UUID.Zero;
1180 } 1262 }
1181 1263
1264 [DebuggerNonUserCode]
1182 public void SetState(UUID itemID, string newState) 1265 public void SetState(UUID itemID, string newState)
1183 { 1266 {
1184 IScriptInstance instance = GetInstance(itemID); 1267 IScriptInstance instance = GetInstance(itemID);
@@ -1199,11 +1282,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1199 { 1282 {
1200 List<IScriptInstance> instances = new List<IScriptInstance>(); 1283 List<IScriptInstance> instances = new List<IScriptInstance>();
1201 1284
1202 lock (m_Scripts) 1285 lockScriptsForRead(true);
1203 { 1286 foreach (IScriptInstance instance in m_Scripts.Values)
1204 foreach (IScriptInstance instance in m_Scripts.Values)
1205 instances.Add(instance); 1287 instances.Add(instance);
1206 } 1288 lockScriptsForRead(false);
1207 1289
1208 foreach (IScriptInstance i in instances) 1290 foreach (IScriptInstance i in instances)
1209 { 1291 {