aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1737
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs338
15 files changed, 1451 insertions, 820 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 525f0f0..c08c246 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 /// </summary> 74 /// </summary>
74 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 75 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
75 { 76 {
76 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 protected IScriptEngine m_ScriptEngine; 78 protected IScriptEngine m_ScriptEngine;
78 protected SceneObjectPart m_host; 79 protected SceneObjectPart m_host;
79 protected uint m_localID; 80 protected uint m_localID;
@@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 get { return m_ScriptEngine.World; } 152 get { return m_ScriptEngine.World; }
152 } 153 }
153 154
155 [DebuggerNonUserCode]
154 public void state(string newState) 156 public void state(string newState)
155 { 157 {
156 m_ScriptEngine.SetState(m_itemID, newState); 158 m_ScriptEngine.SetState(m_itemID, newState);
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
160 /// Reset the named script. The script must be present 162 /// Reset the named script. The script must be present
161 /// in the same prim. 163 /// in the same prim.
162 /// </summary> 164 /// </summary>
165 [DebuggerNonUserCode]
163 public void llResetScript() 166 public void llResetScript()
164 { 167 {
165 m_host.AddScriptLPS(1); 168 m_host.AddScriptLPS(1);
@@ -216,9 +219,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
216 } 219 }
217 } 220 }
218 221
222 public List<ScenePresence> GetLinkAvatars(int linkType)
223 {
224 List<ScenePresence> ret = new List<ScenePresence>();
225 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
226 return ret;
227
228 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
229
230 switch (linkType)
231 {
232 case ScriptBaseClass.LINK_SET:
233 return avs;
234
235 case ScriptBaseClass.LINK_ROOT:
236 return ret;
237
238 case ScriptBaseClass.LINK_ALL_OTHERS:
239 return avs;
240
241 case ScriptBaseClass.LINK_ALL_CHILDREN:
242 return avs;
243
244 case ScriptBaseClass.LINK_THIS:
245 return ret;
246
247 default:
248 if (linkType < 0)
249 return ret;
250
251 int partCount = m_host.ParentGroup.GetPartCount();
252
253 if (linkType <= partCount)
254 {
255 return ret;
256 }
257 else
258 {
259 linkType = linkType - partCount;
260 if (linkType > avs.Count)
261 {
262 return ret;
263 }
264 else
265 {
266 ret.Add(avs[linkType-1]);
267 return ret;
268 }
269 }
270 }
271 }
272
219 public List<SceneObjectPart> GetLinkParts(int linkType) 273 public List<SceneObjectPart> GetLinkParts(int linkType)
220 { 274 {
221 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 275 List<SceneObjectPart> ret = new List<SceneObjectPart>();
276 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
277 return ret;
222 ret.Add(m_host); 278 ret.Add(m_host);
223 279
224 switch (linkType) 280 switch (linkType)
@@ -272,40 +328,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 328 protected UUID InventorySelf()
273 { 329 {
274 UUID invItemID = new UUID(); 330 UUID invItemID = new UUID();
275 331 bool unlock = false;
276 lock (m_host.TaskInventory) 332 if (!m_host.TaskInventory.IsReadLockedByMe())
333 {
334 m_host.TaskInventory.LockItemsForRead(true);
335 unlock = true;
336 }
337 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
277 { 338 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 339 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 340 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 341 invItemID = inv.Key;
281 { 342 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 343 }
286 } 344 }
287 345 if (unlock)
346 {
347 m_host.TaskInventory.LockItemsForRead(false);
348 }
288 return invItemID; 349 return invItemID;
289 } 350 }
290 351
291 protected UUID InventoryKey(string name, int type) 352 protected UUID InventoryKey(string name, int type)
292 { 353 {
293 m_host.AddScriptLPS(1); 354 m_host.AddScriptLPS(1);
294 355 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 356
357 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 358 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 359 if (inv.Value.Name == name)
298 { 360 {
299 if (inv.Value.Name == name) 361 m_host.TaskInventory.LockItemsForRead(false);
362
363 if (inv.Value.Type != type)
300 { 364 {
301 if (inv.Value.Type != type) 365 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 366 }
367
368 return inv.Value.AssetID;
306 } 369 }
307 } 370 }
308 371
372 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 373 return UUID.Zero;
310 } 374 }
311 375
@@ -313,17 +377,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 377 {
314 m_host.AddScriptLPS(1); 378 m_host.AddScriptLPS(1);
315 379
316 lock (m_host.TaskInventory) 380
381 m_host.TaskInventory.LockItemsForRead(true);
382
383 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 384 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 385 if (inv.Value.Name == name)
319 { 386 {
320 if (inv.Value.Name == name) 387 m_host.TaskInventory.LockItemsForRead(false);
321 { 388 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 389 }
325 } 390 }
326 391
392 m_host.TaskInventory.LockItemsForRead(false);
393
394
327 return UUID.Zero; 395 return UUID.Zero;
328 } 396 }
329 397
@@ -465,26 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 533
466 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
467 535
468 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 536 // Utility function for llRot2Euler
469 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
470 537
471 public LSL_Vector llRot2Euler(LSL_Rotation r) 538 // normalize an angle between -PI and PI (-180 to +180 degrees)
539 protected double NormalizeAngle(double angle)
540 {
541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
543
544 int numPis = (int)(Math.PI / angle);
545 double remainder = angle - Math.PI * numPis;
546 if (numPis % 2 == 1)
547 return Math.PI - angle;
548 return remainder;
549 }
550
551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
472 { 552 {
473 m_host.AddScriptLPS(1); 553 m_host.AddScriptLPS(1);
474 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 554 LSL_Vector eul = new LSL_Vector();
475 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 555
476 double m = (t.x + t.y + t.z + t.s); 556 double sqw = q1.s*q1.s;
477 if (m == 0) return new LSL_Vector(); 557 double sqx = q1.x*q1.x;
478 double n = 2 * (r.y * r.s + r.x * r.z); 558 double sqy = q1.z*q1.z;
479 double p = m * m - n * n; 559 double sqz = q1.y*q1.y;
480 if (p > 0) 560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
481 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 561 double test = q1.x*q1.z + q1.y*q1.s;
482 Math.Atan2(n, Math.Sqrt(p)), 562 if (test > 0.4999*unit) { // singularity at north pole
483 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
484 else if (n > 0) 564 eul.y = Math.PI/2;
485 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 565 eul.x = 0;
486 else 566 return eul;
487 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 567 }
568 if (test < -0.4999*unit) { // singularity at south pole
569 eul.z = -2 * Math.Atan2(q1.x,q1.s);
570 eul.y = -Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
488 } 578 }
489 579
490 /* From wiki: 580 /* From wiki:
@@ -686,77 +776,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
686 { 776 {
687 //A and B should both be normalized 777 //A and B should both be normalized
688 m_host.AddScriptLPS(1); 778 m_host.AddScriptLPS(1);
689 LSL_Rotation rotBetween; 779 /* This method is more accurate than the SL one, and thus causes problems
690 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 780 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
691 // continue calculation. 781
692 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 782 double dotProduct = LSL_Vector.Dot(a, b);
783 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
784 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
785 double angle = Math.Acos(dotProduct / magProduct);
786 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
787 double s = Math.Sin(angle / 2);
788
789 double x = axis.x * s;
790 double y = axis.y * s;
791 double z = axis.z * s;
792 double w = Math.Cos(angle / 2);
793
794 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
795 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
796
797 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
798 */
799
800 // This method mimics the 180 errors found in SL
801 // See www.euclideanspace.com... angleBetween
802 LSL_Vector vec_a = a;
803 LSL_Vector vec_b = b;
804
805 // Eliminate zero length
806 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
807 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
808 if (vec_a_mag < 0.00001 ||
809 vec_b_mag < 0.00001)
693 { 810 {
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
695 } 812 }
696 else 813
814 // Normalize
815 vec_a = llVecNorm(vec_a);
816 vec_b = llVecNorm(vec_b);
817
818 // Calculate axis and rotation angle
819 LSL_Vector axis = vec_a % vec_b;
820 LSL_Float cos_theta = vec_a * vec_b;
821
822 // Check if parallel
823 if (cos_theta > 0.99999)
697 { 824 {
698 a = LSL_Vector.Norm(a); 825 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
699 b = LSL_Vector.Norm(b); 826 }
700 double dotProduct = LSL_Vector.Dot(a, b); 827
701 // There are two degenerate cases possible. These are for vectors 180 or 828 // Check if anti-parallel
702 // 0 degrees apart. These have to be detected and handled individually. 829 else if (cos_theta < -0.99999)
703 // 830 {
704 // Check for vectors 180 degrees apart. 831 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
705 // A dot product of -1 would mean the angle between vectors is 180 degrees. 832 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
706 if (dotProduct < -0.9999999f) 833 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
707 { 834 }
708 // First assume X axis is orthogonal to the vectors. 835 else // other rotation
709 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 836 {
710 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 837 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
711 // Check for near zero vector. A very small non-zero number here will create 838 axis = llVecNorm(axis);
712 // a rotation in an undesired direction. 839 double x, y, z, s, t;
713 if (LSL_Vector.Mag(orthoVector) > 0.0001) 840 s = Math.Cos(theta);
714 { 841 t = Math.Sin(theta);
715 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 842 x = axis.x * t;
716 } 843 y = axis.y * t;
717 // If the magnitude of the vector was near zero, then assume the X axis is not 844 z = axis.z * t;
718 // orthogonal and use the Z axis instead. 845 return new LSL_Rotation(x,y,z,s);
719 else
720 {
721 // Set 180 z rotation.
722 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
723 }
724 }
725 // Check for parallel vectors.
726 // A dot product of 1 would mean the angle between vectors is 0 degrees.
727 else if (dotProduct > 0.9999999f)
728 {
729 // Set zero rotation.
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 else
733 {
734 // All special checks have been performed so get the axis of rotation.
735 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
736 // Quarternion s value is the length of the unit vector + dot product.
737 double qs = 1.0 + dotProduct;
738 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
739 // Normalize the rotation.
740 double mag = LSL_Rotation.Mag(rotBetween);
741 // We shouldn't have to worry about a divide by zero here. The qs value will be
742 // non-zero because we already know if we're here, then the dotProduct is not -1 so
743 // qs will not be zero. Also, we've already handled the input vectors being zero so the
744 // crossProduct vector should also not be zero.
745 rotBetween.x = rotBetween.x / mag;
746 rotBetween.y = rotBetween.y / mag;
747 rotBetween.z = rotBetween.z / mag;
748 rotBetween.s = rotBetween.s / mag;
749 // Check for undefined values and set zero rotation if any found. This code might not actually be required
750 // any longer since zero vectors are checked for at the top.
751 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
752 {
753 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
754 }
755 }
756 } 846 }
757 return rotBetween;
758 } 847 }
759 848
760 public void llWhisper(int channelID, string text) 849 public void llWhisper(int channelID, string text)
761 { 850 {
762 m_host.AddScriptLPS(1); 851 m_host.AddScriptLPS(1);
@@ -1080,10 +1169,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1169 return detectedParams.TouchUV;
1081 } 1170 }
1082 1171
1172 [DebuggerNonUserCode]
1083 public virtual void llDie() 1173 public virtual void llDie()
1084 { 1174 {
1085 m_host.AddScriptLPS(1); 1175 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1176 if (!m_host.IsAttachment) throw new SelfDeleteException();
1087 } 1177 }
1088 1178
1089 public LSL_Float llGround(LSL_Vector offset) 1179 public LSL_Float llGround(LSL_Vector offset)
@@ -1156,6 +1246,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 1246
1157 public void llSetStatus(int status, int value) 1247 public void llSetStatus(int status, int value)
1158 { 1248 {
1249 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1250 return;
1159 m_host.AddScriptLPS(1); 1251 m_host.AddScriptLPS(1);
1160 1252
1161 int statusrotationaxis = 0; 1253 int statusrotationaxis = 0;
@@ -1385,6 +1477,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1477 {
1386 m_host.AddScriptLPS(1); 1478 m_host.AddScriptLPS(1);
1387 1479
1480 SetColor(m_host, color, face);
1481 }
1482
1483 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1484 {
1485 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1486 return;
1487
1488 Primitive.TextureEntry tex = part.Shape.Textures;
1489 Color4 texcolor;
1490 if (face >= 0 && face < GetNumberOfSides(part))
1491 {
1492 texcolor = tex.CreateFace((uint)face).RGBA;
1493 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1494 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1495 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1496 tex.FaceTextures[face].RGBA = texcolor;
1497 part.UpdateTexture(tex);
1498 return;
1499 }
1500 else if (face == ScriptBaseClass.ALL_SIDES)
1501 {
1502 for (uint i = 0; i < GetNumberOfSides(part); i++)
1503 {
1504 if (tex.FaceTextures[i] != null)
1505 {
1506 texcolor = tex.FaceTextures[i].RGBA;
1507 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1508 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1509 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1510 tex.FaceTextures[i].RGBA = texcolor;
1511 }
1512 texcolor = tex.DefaultTexture.RGBA;
1513 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1514 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1515 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1516 tex.DefaultTexture.RGBA = texcolor;
1517 }
1518 part.UpdateTexture(tex);
1519 return;
1520 }
1521
1388 if (face == ScriptBaseClass.ALL_SIDES) 1522 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1523 face = SceneObjectPart.ALL_SIDES;
1390 1524
@@ -1393,6 +1527,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1527
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1528 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1529 {
1530 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1531 return;
1532
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1533 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1534 MappingType textype;
1398 textype = MappingType.Default; 1535 textype = MappingType.Default;
@@ -1423,6 +1560,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1560
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1561 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1562 {
1563 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1564 return;
1565
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1566 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1567 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1568 {
@@ -1448,6 +1588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1588
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1589 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1590 {
1591 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1592 return;
1451 1593
1452 Shininess sval = new Shininess(); 1594 Shininess sval = new Shininess();
1453 1595
@@ -1498,6 +1640,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1640
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1641 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1642 {
1643 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return;
1645
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1646 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1647 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1648 {
@@ -1558,13 +1703,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1703 m_host.AddScriptLPS(1);
1559 1704
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1705 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1706 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1707 {
1563 SetAlpha(part, alpha, face); 1708 try
1709 {
1710 parts[0].ParentGroup.areUpdatesSuspended = true;
1711 foreach (SceneObjectPart part in parts)
1712 SetAlpha(part, alpha, face);
1713 }
1714 finally
1715 {
1716 parts[0].ParentGroup.areUpdatesSuspended = false;
1717 }
1718 }
1564 } 1719 }
1565 1720
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1721 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1722 {
1723 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1724 return;
1725
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1726 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1727 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1728 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1610,7 +1768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1610 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1768 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1611 float wind, float tension, LSL_Vector Force) 1769 float wind, float tension, LSL_Vector Force)
1612 { 1770 {
1613 if (part == null) 1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1614 return; 1772 return;
1615 1773
1616 if (flexi) 1774 if (flexi)
@@ -1645,7 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1803 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1804 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1805 {
1648 if (part == null) 1806 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1807 return;
1650 1808
1651 if (light) 1809 if (light)
@@ -1722,15 +1880,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 m_host.AddScriptLPS(1); 1880 m_host.AddScriptLPS(1);
1723 1881
1724 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1882 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1725 1883 if (parts.Count > 0)
1726 foreach (SceneObjectPart part in parts) 1884 {
1727 SetTexture(part, texture, face); 1885 try
1728 1886 {
1887 parts[0].ParentGroup.areUpdatesSuspended = true;
1888 foreach (SceneObjectPart part in parts)
1889 SetTexture(part, texture, face);
1890 }
1891 finally
1892 {
1893 parts[0].ParentGroup.areUpdatesSuspended = false;
1894 }
1895 }
1729 ScriptSleep(200); 1896 ScriptSleep(200);
1730 } 1897 }
1731 1898
1732 protected void SetTexture(SceneObjectPart part, string texture, int face) 1899 protected void SetTexture(SceneObjectPart part, string texture, int face)
1733 { 1900 {
1901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1902 return;
1903
1734 UUID textureID=new UUID(); 1904 UUID textureID=new UUID();
1735 1905
1736 if (!UUID.TryParse(texture, out textureID)) 1906 if (!UUID.TryParse(texture, out textureID))
@@ -1776,6 +1946,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1776 1946
1777 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1778 { 1948 {
1949 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1950 return;
1951
1779 Primitive.TextureEntry tex = part.Shape.Textures; 1952 Primitive.TextureEntry tex = part.Shape.Textures;
1780 if (face >= 0 && face < GetNumberOfSides(part)) 1953 if (face >= 0 && face < GetNumberOfSides(part))
1781 { 1954 {
@@ -1812,6 +1985,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1812 1985
1813 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1986 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1814 { 1987 {
1988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1989 return;
1990
1815 Primitive.TextureEntry tex = part.Shape.Textures; 1991 Primitive.TextureEntry tex = part.Shape.Textures;
1816 if (face >= 0 && face < GetNumberOfSides(part)) 1992 if (face >= 0 && face < GetNumberOfSides(part))
1817 { 1993 {
@@ -1848,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 2024
1849 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2025 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1850 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1851 Primitive.TextureEntry tex = part.Shape.Textures; 2030 Primitive.TextureEntry tex = part.Shape.Textures;
1852 if (face >= 0 && face < GetNumberOfSides(part)) 2031 if (face >= 0 && face < GetNumberOfSides(part))
1853 { 2032 {
@@ -1918,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1918 2097
1919 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2098 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1920 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1921 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2103 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1922 LSL_Vector currentPos = llGetLocalPos(); 2104 LSL_Vector currentPos = llGetLocalPos();
1923 2105
@@ -1952,6 +2134,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1952 public LSL_Vector llGetLocalPos() 2134 public LSL_Vector llGetLocalPos()
1953 { 2135 {
1954 m_host.AddScriptLPS(1); 2136 m_host.AddScriptLPS(1);
2137 if (m_host.IsAttachment == true) {
2138 if (m_host.IsRoot == true)
2139 {
2140 return new LSL_Vector(m_host.AbsolutePosition.X,
2141 m_host.AbsolutePosition.Y,
2142 m_host.AbsolutePosition.Z);
2143
2144 }
2145 else
2146 {
2147 return new LSL_Vector(m_host.OffsetPosition.X,
2148 m_host.OffsetPosition.Y,
2149 m_host.OffsetPosition.Z);
2150 }
2151 }
2152
1955 if (m_host.ParentID != 0) 2153 if (m_host.ParentID != 0)
1956 { 2154 {
1957 return new LSL_Vector(m_host.OffsetPosition.X, 2155 return new LSL_Vector(m_host.OffsetPosition.X,
@@ -2002,6 +2200,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 2200
2003 protected void SetRot(SceneObjectPart part, Quaternion rot) 2201 protected void SetRot(SceneObjectPart part, Quaternion rot)
2004 { 2202 {
2203 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2204 return;
2205
2005 part.UpdateRotation(rot); 2206 part.UpdateRotation(rot);
2006 // Update rotation does not move the object in the physics scene if it's a linkset. 2207 // Update rotation does not move the object in the physics scene if it's a linkset.
2007 2208
@@ -2621,12 +2822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2621 2822
2622 m_host.AddScriptLPS(1); 2823 m_host.AddScriptLPS(1);
2623 2824
2825 m_host.TaskInventory.LockItemsForRead(true);
2624 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2826 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2625 2827 m_host.TaskInventory.LockItemsForRead(false);
2626 lock (m_host.TaskInventory)
2627 {
2628 item = m_host.TaskInventory[invItemID];
2629 }
2630 2828
2631 if (item.PermsGranter == UUID.Zero) 2829 if (item.PermsGranter == UUID.Zero)
2632 return 0; 2830 return 0;
@@ -2701,6 +2899,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2701 if (dist > m_ScriptDistanceFactor * 10.0f) 2899 if (dist > m_ScriptDistanceFactor * 10.0f)
2702 return; 2900 return;
2703 2901
2902 //Clone is thread-safe
2704 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2903 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2705 2904
2706 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2905 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2763,6 +2962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2763 2962
2764 public void llLookAt(LSL_Vector target, double strength, double damping) 2963 public void llLookAt(LSL_Vector target, double strength, double damping)
2765 { 2964 {
2965 /*
2766 m_host.AddScriptLPS(1); 2966 m_host.AddScriptLPS(1);
2767 // Determine where we are looking from 2967 // Determine where we are looking from
2768 LSL_Vector from = llGetPos(); 2968 LSL_Vector from = llGetPos();
@@ -2782,10 +2982,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2782 // the angles of rotation in radians into rotation value 2982 // the angles of rotation in radians into rotation value
2783 2983
2784 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2984 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2785 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2985
2786 m_host.startLookAt(rotation, (float)damping, (float)strength); 2986 // This would only work if your physics system contains an APID controller:
2987 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2988 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2989
2787 // Orient the object to the angle calculated 2990 // Orient the object to the angle calculated
2788 //llSetRot(rot); 2991 llSetRot(rot);
2992 */
2993
2994 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2995 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2996 // http://bugs.meta7.com/view.php?id=28
2997 // - Tom
2998
2999 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3000 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3001
3002 }
3003
3004 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3005 {
3006 m_host.AddScriptLPS(1);
3007// NotImplemented("llRotLookAt");
3008 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3009
2789 } 3010 }
2790 3011
2791 public void llStopLookAt() 3012 public void llStopLookAt()
@@ -2834,13 +3055,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2834 { 3055 {
2835 TaskInventoryItem item; 3056 TaskInventoryItem item;
2836 3057
2837 lock (m_host.TaskInventory) 3058 m_host.TaskInventory.LockItemsForRead(true);
3059 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2838 { 3060 {
2839 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3061 m_host.TaskInventory.LockItemsForRead(false);
2840 return; 3062 return;
2841 else
2842 item = m_host.TaskInventory[InventorySelf()];
2843 } 3063 }
3064 else
3065 {
3066 item = m_host.TaskInventory[InventorySelf()];
3067 }
3068 m_host.TaskInventory.LockItemsForRead(false);
2844 3069
2845 if (item.PermsGranter != UUID.Zero) 3070 if (item.PermsGranter != UUID.Zero)
2846 { 3071 {
@@ -2862,13 +3087,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2862 { 3087 {
2863 TaskInventoryItem item; 3088 TaskInventoryItem item;
2864 3089
3090 m_host.TaskInventory.LockItemsForRead(true);
2865 lock (m_host.TaskInventory) 3091 lock (m_host.TaskInventory)
2866 { 3092 {
3093
2867 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3094 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3095 {
3096 m_host.TaskInventory.LockItemsForRead(false);
2868 return; 3097 return;
3098 }
2869 else 3099 else
3100 {
2870 item = m_host.TaskInventory[InventorySelf()]; 3101 item = m_host.TaskInventory[InventorySelf()];
3102 }
2871 } 3103 }
3104 m_host.TaskInventory.LockItemsForRead(false);
2872 3105
2873 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
2874 3107
@@ -2900,19 +3133,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2900 { 3133 {
2901 m_host.AddScriptLPS(1); 3134 m_host.AddScriptLPS(1);
2902 3135
2903 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2904 return;
2905
2906 TaskInventoryItem item; 3136 TaskInventoryItem item;
2907 3137
2908 lock (m_host.TaskInventory) 3138 m_host.TaskInventory.LockItemsForRead(true);
3139
3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2909 { 3141 {
2910 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3142 m_host.TaskInventory.LockItemsForRead(false);
2911 return; 3143 return;
2912 else 3144 }
2913 item = m_host.TaskInventory[InventorySelf()]; 3145 else
3146 {
3147 item = m_host.TaskInventory[InventorySelf()];
2914 } 3148 }
2915 3149
3150 m_host.TaskInventory.LockItemsForRead(false);
3151
2916 if (item.PermsGranter != m_host.OwnerID) 3152 if (item.PermsGranter != m_host.OwnerID)
2917 return; 3153 return;
2918 3154
@@ -2922,10 +3158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 3158
2923 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3159 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2924 3160
2925 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3161 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2926 if (attachmentsModule != null)
2927 attachmentsModule.AttachObject(presence.ControllingClient,
2928 grp, (uint)attachment, false);
2929 } 3162 }
2930 } 3163 }
2931 3164
@@ -2938,13 +3171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 3171
2939 TaskInventoryItem item; 3172 TaskInventoryItem item;
2940 3173
2941 lock (m_host.TaskInventory) 3174 m_host.TaskInventory.LockItemsForRead(true);
3175
3176 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2942 { 3177 {
2943 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3178 m_host.TaskInventory.LockItemsForRead(false);
2944 return; 3179 return;
2945 else 3180 }
2946 item = m_host.TaskInventory[InventorySelf()]; 3181 else
3182 {
3183 item = m_host.TaskInventory[InventorySelf()];
2947 } 3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
3186
2948 3187
2949 if (item.PermsGranter != m_host.OwnerID) 3188 if (item.PermsGranter != m_host.OwnerID)
2950 return; 3189 return;
@@ -2981,8 +3220,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 return m_host.OwnerID.ToString(); 3220 return m_host.OwnerID.ToString();
2982 } 3221 }
2983 3222
3223 [DebuggerNonUserCode]
2984 public void llInstantMessage(string user, string message) 3224 public void llInstantMessage(string user, string message)
2985 { 3225 {
3226 UUID result;
3227 if (!UUID.TryParse(user, out result))
3228 {
3229 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3230 return;
3231 }
3232
3233
2986 m_host.AddScriptLPS(1); 3234 m_host.AddScriptLPS(1);
2987 3235
2988 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3236 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2997,14 +3245,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 UUID friendTransactionID = UUID.Random(); 3245 UUID friendTransactionID = UUID.Random();
2998 3246
2999 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3247 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3000 3248
3001 GridInstantMessage msg = new GridInstantMessage(); 3249 GridInstantMessage msg = new GridInstantMessage();
3002 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3250 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3003 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3251 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3004 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3252 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3005// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3253// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3006// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3254// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3007 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3255 DateTime dt = DateTime.UtcNow;
3256
3257 // Ticks from UtcNow, but make it look like local. Evil, huh?
3258 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3259
3260 try
3261 {
3262 // Convert that to the PST timezone
3263 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3264 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3265 }
3266 catch
3267 {
3268 // No logging here, as it could be VERY spammy
3269 }
3270
3271 // And make it look local again to fool the unix time util
3272 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3273
3274 msg.timestamp = (uint)Util.ToUnixTime(dt);
3275
3008 //if (client != null) 3276 //if (client != null)
3009 //{ 3277 //{
3010 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3278 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3018,13 +3286,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3018 msg.message = message.Substring(0, 1024); 3286 msg.message = message.Substring(0, 1024);
3019 else 3287 else
3020 msg.message = message; 3288 msg.message = message;
3021 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3289 msg.dialog = (byte)19; // MessageFromObject
3022 msg.fromGroup = false;// fromGroup; 3290 msg.fromGroup = false;// fromGroup;
3023 msg.offline = (byte)0; //offline; 3291 msg.offline = (byte)0; //offline;
3024 msg.ParentEstateID = 0; //ParentEstateID; 3292 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3025 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3293 msg.Position = new Vector3(m_host.AbsolutePosition);
3026 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3294 msg.RegionID = World.RegionInfo.RegionID.Guid;
3027 msg.binaryBucket = new byte[0];// binaryBucket; 3295 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3028 3296
3029 if (m_TransferModule != null) 3297 if (m_TransferModule != null)
3030 { 3298 {
@@ -3044,7 +3312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3044 } 3312 }
3045 3313
3046 emailModule.SendEmail(m_host.UUID, address, subject, message); 3314 emailModule.SendEmail(m_host.UUID, address, subject, message);
3047 ScriptSleep(20000); 3315 ScriptSleep(15000);
3048 } 3316 }
3049 3317
3050 public void llGetNextEmail(string address, string subject) 3318 public void llGetNextEmail(string address, string subject)
@@ -3146,13 +3414,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3146 m_host.AddScriptLPS(1); 3414 m_host.AddScriptLPS(1);
3147 } 3415 }
3148 3416
3149 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3150 {
3151 m_host.AddScriptLPS(1);
3152 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3153 m_host.RotLookAt(rot, (float)strength, (float)damping);
3154 }
3155
3156 public LSL_Integer llStringLength(string str) 3417 public LSL_Integer llStringLength(string str)
3157 { 3418 {
3158 m_host.AddScriptLPS(1); 3419 m_host.AddScriptLPS(1);
@@ -3176,14 +3437,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3176 3437
3177 TaskInventoryItem item; 3438 TaskInventoryItem item;
3178 3439
3179 lock (m_host.TaskInventory) 3440 m_host.TaskInventory.LockItemsForRead(true);
3441 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3180 { 3442 {
3181 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3443 m_host.TaskInventory.LockItemsForRead(false);
3182 return; 3444 return;
3183 else
3184 item = m_host.TaskInventory[InventorySelf()];
3185 } 3445 }
3186 3446 else
3447 {
3448 item = m_host.TaskInventory[InventorySelf()];
3449 }
3450 m_host.TaskInventory.LockItemsForRead(false);
3187 if (item.PermsGranter == UUID.Zero) 3451 if (item.PermsGranter == UUID.Zero)
3188 return; 3452 return;
3189 3453
@@ -3213,13 +3477,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3213 3477
3214 TaskInventoryItem item; 3478 TaskInventoryItem item;
3215 3479
3216 lock (m_host.TaskInventory) 3480 m_host.TaskInventory.LockItemsForRead(true);
3481 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3217 { 3482 {
3218 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3483 m_host.TaskInventory.LockItemsForRead(false);
3219 return; 3484 return;
3220 else 3485 }
3221 item = m_host.TaskInventory[InventorySelf()]; 3486 else
3487 {
3488 item = m_host.TaskInventory[InventorySelf()];
3222 } 3489 }
3490 m_host.TaskInventory.LockItemsForRead(false);
3491
3223 3492
3224 if (item.PermsGranter == UUID.Zero) 3493 if (item.PermsGranter == UUID.Zero)
3225 return; 3494 return;
@@ -3296,10 +3565,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3296 3565
3297 TaskInventoryItem item; 3566 TaskInventoryItem item;
3298 3567
3299 lock (m_host.TaskInventory) 3568
3569 m_host.TaskInventory.LockItemsForRead(true);
3570 if (!m_host.TaskInventory.ContainsKey(invItemID))
3571 {
3572 m_host.TaskInventory.LockItemsForRead(false);
3573 return;
3574 }
3575 else
3300 { 3576 {
3301 item = m_host.TaskInventory[invItemID]; 3577 item = m_host.TaskInventory[invItemID];
3302 } 3578 }
3579 m_host.TaskInventory.LockItemsForRead(false);
3303 3580
3304 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3581 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3305 { 3582 {
@@ -3331,11 +3608,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3331 3608
3332 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3609 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3333 { 3610 {
3334 lock (m_host.TaskInventory) 3611 m_host.TaskInventory.LockItemsForWrite(true);
3335 { 3612 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3336 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3613 m_host.TaskInventory[invItemID].PermsMask = perm;
3337 m_host.TaskInventory[invItemID].PermsMask = perm; 3614 m_host.TaskInventory.LockItemsForWrite(false);
3338 }
3339 3615
3340 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3616 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3341 "run_time_permissions", new Object[] { 3617 "run_time_permissions", new Object[] {
@@ -3355,11 +3631,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3355 3631
3356 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3632 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3357 { 3633 {
3358 lock (m_host.TaskInventory) 3634 m_host.TaskInventory.LockItemsForWrite(true);
3359 { 3635 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3360 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3636 m_host.TaskInventory[invItemID].PermsMask = perm;
3361 m_host.TaskInventory[invItemID].PermsMask = perm; 3637 m_host.TaskInventory.LockItemsForWrite(false);
3362 }
3363 3638
3364 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3639 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3365 "run_time_permissions", new Object[] { 3640 "run_time_permissions", new Object[] {
@@ -3380,11 +3655,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3380 3655
3381 if (!m_waitingForScriptAnswer) 3656 if (!m_waitingForScriptAnswer)
3382 { 3657 {
3383 lock (m_host.TaskInventory) 3658 m_host.TaskInventory.LockItemsForWrite(true);
3384 { 3659 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3385 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3660 m_host.TaskInventory[invItemID].PermsMask = 0;
3386 m_host.TaskInventory[invItemID].PermsMask = 0; 3661 m_host.TaskInventory.LockItemsForWrite(false);
3387 }
3388 3662
3389 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3663 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3390 m_waitingForScriptAnswer=true; 3664 m_waitingForScriptAnswer=true;
@@ -3419,10 +3693,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3419 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3693 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3420 llReleaseControls(); 3694 llReleaseControls();
3421 3695
3422 lock (m_host.TaskInventory) 3696
3423 { 3697 m_host.TaskInventory.LockItemsForWrite(true);
3424 m_host.TaskInventory[invItemID].PermsMask = answer; 3698 m_host.TaskInventory[invItemID].PermsMask = answer;
3425 } 3699 m_host.TaskInventory.LockItemsForWrite(false);
3700
3426 3701
3427 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3702 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3428 "run_time_permissions", new Object[] { 3703 "run_time_permissions", new Object[] {
@@ -3434,16 +3709,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3434 { 3709 {
3435 m_host.AddScriptLPS(1); 3710 m_host.AddScriptLPS(1);
3436 3711
3437 lock (m_host.TaskInventory) 3712 m_host.TaskInventory.LockItemsForRead(true);
3713
3714 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3438 { 3715 {
3439 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3716 if (item.Type == 10 && item.ItemID == m_itemID)
3440 { 3717 {
3441 if (item.Type == 10 && item.ItemID == m_itemID) 3718 m_host.TaskInventory.LockItemsForRead(false);
3442 { 3719 return item.PermsGranter.ToString();
3443 return item.PermsGranter.ToString();
3444 }
3445 } 3720 }
3446 } 3721 }
3722 m_host.TaskInventory.LockItemsForRead(false);
3447 3723
3448 return UUID.Zero.ToString(); 3724 return UUID.Zero.ToString();
3449 } 3725 }
@@ -3452,19 +3728,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3452 { 3728 {
3453 m_host.AddScriptLPS(1); 3729 m_host.AddScriptLPS(1);
3454 3730
3455 lock (m_host.TaskInventory) 3731 m_host.TaskInventory.LockItemsForRead(true);
3732
3733 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3456 { 3734 {
3457 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3735 if (item.Type == 10 && item.ItemID == m_itemID)
3458 { 3736 {
3459 if (item.Type == 10 && item.ItemID == m_itemID) 3737 int perms = item.PermsMask;
3460 { 3738 if (m_automaticLinkPermission)
3461 int perms = item.PermsMask; 3739 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3462 if (m_automaticLinkPermission) 3740 m_host.TaskInventory.LockItemsForRead(false);
3463 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3741 return perms;
3464 return perms;
3465 }
3466 } 3742 }
3467 } 3743 }
3744 m_host.TaskInventory.LockItemsForRead(false);
3468 3745
3469 return 0; 3746 return 0;
3470 } 3747 }
@@ -3486,9 +3763,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3486 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3763 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3487 { 3764 {
3488 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3765 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3489 3766 if (parts.Count > 0)
3490 foreach (SceneObjectPart part in parts) 3767 {
3491 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3768 try
3769 {
3770 parts[0].ParentGroup.areUpdatesSuspended = true;
3771 foreach (SceneObjectPart part in parts)
3772 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3773 }
3774 finally
3775 {
3776 parts[0].ParentGroup.areUpdatesSuspended = false;
3777 }
3778 }
3492 } 3779 }
3493 3780
3494 public void llCreateLink(string target, int parent) 3781 public void llCreateLink(string target, int parent)
@@ -3497,11 +3784,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3497 UUID invItemID = InventorySelf(); 3784 UUID invItemID = InventorySelf();
3498 3785
3499 TaskInventoryItem item; 3786 TaskInventoryItem item;
3500 lock (m_host.TaskInventory) 3787 m_host.TaskInventory.LockItemsForRead(true);
3501 { 3788 item = m_host.TaskInventory[invItemID];
3502 item = m_host.TaskInventory[invItemID]; 3789 m_host.TaskInventory.LockItemsForRead(false);
3503 } 3790
3504
3505 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3791 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3506 && !m_automaticLinkPermission) 3792 && !m_automaticLinkPermission)
3507 { 3793 {
@@ -3554,16 +3840,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3554 m_host.AddScriptLPS(1); 3840 m_host.AddScriptLPS(1);
3555 UUID invItemID = InventorySelf(); 3841 UUID invItemID = InventorySelf();
3556 3842
3557 lock (m_host.TaskInventory) 3843 m_host.TaskInventory.LockItemsForRead(true);
3558 {
3559 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3844 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3560 && !m_automaticLinkPermission) 3845 && !m_automaticLinkPermission)
3561 { 3846 {
3562 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3847 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3848 m_host.TaskInventory.LockItemsForRead(false);
3563 return; 3849 return;
3564 } 3850 }
3565 } 3851 m_host.TaskInventory.LockItemsForRead(false);
3566 3852
3567 if (linknum < ScriptBaseClass.LINK_THIS) 3853 if (linknum < ScriptBaseClass.LINK_THIS)
3568 return; 3854 return;
3569 3855
@@ -3602,10 +3888,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3602 // Restructuring Multiple Prims. 3888 // Restructuring Multiple Prims.
3603 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3889 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3604 parts.Remove(parentPrim.RootPart); 3890 parts.Remove(parentPrim.RootPart);
3605 foreach (SceneObjectPart part in parts) 3891 if (parts.Count > 0)
3606 { 3892 {
3607 parentPrim.DelinkFromGroup(part.LocalId, true); 3893 try
3894 {
3895 parts[0].ParentGroup.areUpdatesSuspended = true;
3896 foreach (SceneObjectPart part in parts)
3897 {
3898 parentPrim.DelinkFromGroup(part.LocalId, true);
3899 }
3900 }
3901 finally
3902 {
3903 parts[0].ParentGroup.areUpdatesSuspended = false;
3904 }
3608 } 3905 }
3906
3609 parentPrim.HasGroupChanged = true; 3907 parentPrim.HasGroupChanged = true;
3610 parentPrim.ScheduleGroupForFullUpdate(); 3908 parentPrim.ScheduleGroupForFullUpdate();
3611 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3909 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3614,11 +3912,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3614 { 3912 {
3615 SceneObjectPart newRoot = parts[0]; 3913 SceneObjectPart newRoot = parts[0];
3616 parts.Remove(newRoot); 3914 parts.Remove(newRoot);
3617 foreach (SceneObjectPart part in parts) 3915
3916 try
3618 { 3917 {
3619 part.UpdateFlag = 0; 3918 parts[0].ParentGroup.areUpdatesSuspended = true;
3620 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3919 foreach (SceneObjectPart part in parts)
3920 {
3921 part.UpdateFlag = 0;
3922 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3923 }
3621 } 3924 }
3925 finally
3926 {
3927 parts[0].ParentGroup.areUpdatesSuspended = false;
3928 }
3929
3930
3622 newRoot.ParentGroup.HasGroupChanged = true; 3931 newRoot.ParentGroup.HasGroupChanged = true;
3623 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3932 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3624 } 3933 }
@@ -3644,11 +3953,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3644 3953
3645 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3954 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3646 parts.Remove(parentPrim.RootPart); 3955 parts.Remove(parentPrim.RootPart);
3647 3956 if (parts.Count > 0)
3648 foreach (SceneObjectPart part in parts)
3649 { 3957 {
3650 parentPrim.DelinkFromGroup(part.LocalId, true); 3958 try
3651 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3959 {
3960 parts[0].ParentGroup.areUpdatesSuspended = true;
3961 foreach (SceneObjectPart part in parts)
3962 {
3963 parentPrim.DelinkFromGroup(part.LocalId, true);
3964 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3965 }
3966 }
3967 finally
3968 {
3969 parts[0].ParentGroup.areUpdatesSuspended = false;
3970 }
3652 } 3971 }
3653 parentPrim.HasGroupChanged = true; 3972 parentPrim.HasGroupChanged = true;
3654 parentPrim.ScheduleGroupForFullUpdate(); 3973 parentPrim.ScheduleGroupForFullUpdate();
@@ -3740,17 +4059,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3740 m_host.AddScriptLPS(1); 4059 m_host.AddScriptLPS(1);
3741 int count = 0; 4060 int count = 0;
3742 4061
3743 lock (m_host.TaskInventory) 4062 m_host.TaskInventory.LockItemsForRead(true);
4063 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3744 { 4064 {
3745 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4065 if (inv.Value.Type == type || type == -1)
3746 { 4066 {
3747 if (inv.Value.Type == type || type == -1) 4067 count = count + 1;
3748 {
3749 count = count + 1;
3750 }
3751 } 4068 }
3752 } 4069 }
3753 4070
4071 m_host.TaskInventory.LockItemsForRead(false);
3754 return count; 4072 return count;
3755 } 4073 }
3756 4074
@@ -3759,16 +4077,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3759 m_host.AddScriptLPS(1); 4077 m_host.AddScriptLPS(1);
3760 ArrayList keys = new ArrayList(); 4078 ArrayList keys = new ArrayList();
3761 4079
3762 lock (m_host.TaskInventory) 4080 m_host.TaskInventory.LockItemsForRead(true);
4081 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3763 { 4082 {
3764 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4083 if (inv.Value.Type == type || type == -1)
3765 { 4084 {
3766 if (inv.Value.Type == type || type == -1) 4085 keys.Add(inv.Value.Name);
3767 {
3768 keys.Add(inv.Value.Name);
3769 }
3770 } 4086 }
3771 } 4087 }
4088 m_host.TaskInventory.LockItemsForRead(false);
3772 4089
3773 if (keys.Count == 0) 4090 if (keys.Count == 0)
3774 { 4091 {
@@ -3805,20 +4122,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3805 } 4122 }
3806 4123
3807 // move the first object found with this inventory name 4124 // move the first object found with this inventory name
3808 lock (m_host.TaskInventory) 4125 m_host.TaskInventory.LockItemsForRead(true);
4126 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3809 { 4127 {
3810 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4128 if (inv.Value.Name == inventory)
3811 { 4129 {
3812 if (inv.Value.Name == inventory) 4130 found = true;
3813 { 4131 objId = inv.Key;
3814 found = true; 4132 assetType = inv.Value.Type;
3815 objId = inv.Key; 4133 objName = inv.Value.Name;
3816 assetType = inv.Value.Type; 4134 break;
3817 objName = inv.Value.Name;
3818 break;
3819 }
3820 } 4135 }
3821 } 4136 }
4137 m_host.TaskInventory.LockItemsForRead(false);
3822 4138
3823 if (!found) 4139 if (!found)
3824 { 4140 {
@@ -3826,9 +4142,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3826 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4142 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3827 } 4143 }
3828 4144
3829 // check if destination is an avatar 4145 // check if destination is an object
3830 if (World.GetScenePresence(destId) != null) 4146 if (World.GetSceneObjectPart(destId) != null)
4147 {
4148 // destination is an object
4149 World.MoveTaskInventoryItem(destId, m_host, objId);
4150 }
4151 else
3831 { 4152 {
4153 ScenePresence presence = World.GetScenePresence(destId);
4154
4155 if (presence == null)
4156 {
4157 UserAccount account =
4158 World.UserAccountService.GetUserAccount(
4159 World.RegionInfo.ScopeID,
4160 destId);
4161
4162 if (account == null)
4163 {
4164 llSay(0, "Can't find destination "+destId.ToString());
4165 return;
4166 }
4167 }
4168
3832 // destination is an avatar 4169 // destination is an avatar
3833 InventoryItemBase agentItem = 4170 InventoryItemBase agentItem =
3834 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4171 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3838,7 +4175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3838 4175
3839 byte[] bucket = new byte[17]; 4176 byte[] bucket = new byte[17];
3840 bucket[0] = (byte)assetType; 4177 bucket[0] = (byte)assetType;
3841 byte[] objBytes = objId.GetBytes(); 4178 byte[] objBytes = agentItem.ID.GetBytes();
3842 Array.Copy(objBytes, 0, bucket, 1, 16); 4179 Array.Copy(objBytes, 0, bucket, 1, 16);
3843 4180
3844 Console.WriteLine("Giving inventory"); 4181 Console.WriteLine("Giving inventory");
@@ -3854,33 +4191,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3854 4191
3855 if (m_TransferModule != null) 4192 if (m_TransferModule != null)
3856 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4193 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4194
4195 //This delay should only occur when giving inventory to avatars.
4196 ScriptSleep(3000);
3857 } 4197 }
3858 else
3859 {
3860 // destination is an object
3861 World.MoveTaskInventoryItem(destId, m_host, objId);
3862 }
3863 ScriptSleep(3000);
3864 } 4198 }
3865 4199
4200 [DebuggerNonUserCode]
3866 public void llRemoveInventory(string name) 4201 public void llRemoveInventory(string name)
3867 { 4202 {
3868 m_host.AddScriptLPS(1); 4203 m_host.AddScriptLPS(1);
3869 4204
3870 lock (m_host.TaskInventory) 4205 m_host.TaskInventory.LockItemsForRead(true);
4206 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3871 { 4207 {
3872 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4208 if (item.Name == name)
3873 { 4209 {
3874 if (item.Name == name) 4210 if (item.ItemID == m_itemID)
3875 { 4211 throw new ScriptDeleteException();
3876 if (item.ItemID == m_itemID) 4212 else
3877 throw new ScriptDeleteException(); 4213 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3878 else 4214
3879 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4215 m_host.TaskInventory.LockItemsForRead(false);
3880 return; 4216 return;
3881 }
3882 } 4217 }
3883 } 4218 }
4219 m_host.TaskInventory.LockItemsForRead(false);
3884 } 4220 }
3885 4221
3886 public void llSetText(string text, LSL_Vector color, double alpha) 4222 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3970,6 +4306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3970 { 4306 {
3971 m_host.AddScriptLPS(1); 4307 m_host.AddScriptLPS(1);
3972 4308
4309 //Clone is thread safe
3973 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4310 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3974 4311
3975 foreach (TaskInventoryItem item in itemDictionary.Values) 4312 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4023,6 +4360,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4023 ScenePresence presence = World.GetScenePresence(agentId); 4360 ScenePresence presence = World.GetScenePresence(agentId);
4024 if (presence != null) 4361 if (presence != null)
4025 { 4362 {
4363 // agent must not be a god
4364 if (presence.GodLevel >= 200) return;
4365
4026 // agent must be over the owners land 4366 // agent must be over the owners land
4027 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4367 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4028 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4368 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4083,17 +4423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4083 UUID soundId = UUID.Zero; 4423 UUID soundId = UUID.Zero;
4084 if (!UUID.TryParse(impact_sound, out soundId)) 4424 if (!UUID.TryParse(impact_sound, out soundId))
4085 { 4425 {
4086 lock (m_host.TaskInventory) 4426 m_host.TaskInventory.LockItemsForRead(true);
4427 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4087 { 4428 {
4088 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4429 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4089 { 4430 {
4090 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4431 soundId = item.AssetID;
4091 { 4432 break;
4092 soundId = item.AssetID;
4093 break;
4094 }
4095 } 4433 }
4096 } 4434 }
4435 m_host.TaskInventory.LockItemsForRead(false);
4097 } 4436 }
4098 m_host.CollisionSound = soundId; 4437 m_host.CollisionSound = soundId;
4099 m_host.CollisionSoundVolume = (float)impact_volume; 4438 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4139,6 +4478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4139 UUID partItemID; 4478 UUID partItemID;
4140 foreach (SceneObjectPart part in parts) 4479 foreach (SceneObjectPart part in parts)
4141 { 4480 {
4481 //Clone is thread safe
4142 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4482 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4143 4483
4144 foreach (TaskInventoryItem item in itemsDictionary.Values) 4484 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4353,17 +4693,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4353 4693
4354 m_host.AddScriptLPS(1); 4694 m_host.AddScriptLPS(1);
4355 4695
4356 lock (m_host.TaskInventory) 4696 m_host.TaskInventory.LockItemsForRead(true);
4697 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4357 { 4698 {
4358 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4699 if (item.Type == 10 && item.ItemID == m_itemID)
4359 { 4700 {
4360 if (item.Type == 10 && item.ItemID == m_itemID) 4701 result = item.Name!=null?item.Name:String.Empty;
4361 { 4702 break;
4362 result = item.Name != null ? item.Name : String.Empty;
4363 break;
4364 }
4365 } 4703 }
4366 } 4704 }
4705 m_host.TaskInventory.LockItemsForRead(false);
4367 4706
4368 return result; 4707 return result;
4369 } 4708 }
@@ -4516,23 +4855,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4516 { 4855 {
4517 m_host.AddScriptLPS(1); 4856 m_host.AddScriptLPS(1);
4518 4857
4519 lock (m_host.TaskInventory) 4858 m_host.TaskInventory.LockItemsForRead(true);
4859 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4520 { 4860 {
4521 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4861 if (inv.Value.Name == name)
4522 { 4862 {
4523 if (inv.Value.Name == name) 4863 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4524 { 4864 {
4525 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4865 m_host.TaskInventory.LockItemsForRead(false);
4526 { 4866 return inv.Value.AssetID.ToString();
4527 return inv.Value.AssetID.ToString(); 4867 }
4528 } 4868 else
4529 else 4869 {
4530 { 4870 m_host.TaskInventory.LockItemsForRead(false);
4531 return UUID.Zero.ToString(); 4871 return UUID.Zero.ToString();
4532 }
4533 } 4872 }
4534 } 4873 }
4535 } 4874 }
4875 m_host.TaskInventory.LockItemsForRead(false);
4536 4876
4537 return UUID.Zero.ToString(); 4877 return UUID.Zero.ToString();
4538 } 4878 }
@@ -4685,14 +5025,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4685 { 5025 {
4686 m_host.AddScriptLPS(1); 5026 m_host.AddScriptLPS(1);
4687 5027
4688 if (src == null) 5028 return src.Length;
4689 {
4690 return 0;
4691 }
4692 else
4693 {
4694 return src.Length;
4695 }
4696 } 5029 }
4697 5030
4698 public LSL_Integer llList2Integer(LSL_List src, int index) 5031 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5468,10 +5801,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5468 m_host.AddScriptLPS(1); 5801 m_host.AddScriptLPS(1);
5469 5802
5470 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5803 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5471 5804 if (parts.Count > 0)
5472 foreach (var part in parts)
5473 { 5805 {
5474 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5806 try
5807 {
5808 parts[0].ParentGroup.areUpdatesSuspended = true;
5809 foreach (var part in parts)
5810 {
5811 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5812 }
5813 }
5814 finally
5815 {
5816 parts[0].ParentGroup.areUpdatesSuspended = false;
5817 }
5475 } 5818 }
5476 } 5819 }
5477 5820
@@ -5527,74 +5870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5527 5870
5528 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5871 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5529 { 5872 {
5530 m_host.AddScriptLPS(1); 5873 return ParseString2List(str, separators, in_spacers, false);
5531 LSL_List ret = new LSL_List();
5532 LSL_List spacers = new LSL_List();
5533 if (in_spacers.Length > 0 && separators.Length > 0)
5534 {
5535 for (int i = 0; i < in_spacers.Length; i++)
5536 {
5537 object s = in_spacers.Data[i];
5538 for (int j = 0; j < separators.Length; j++)
5539 {
5540 if (separators.Data[j].ToString() == s.ToString())
5541 {
5542 s = null;
5543 break;
5544 }
5545 }
5546 if (s != null)
5547 {
5548 spacers.Add(s);
5549 }
5550 }
5551 }
5552 object[] delimiters = new object[separators.Length + spacers.Length];
5553 separators.Data.CopyTo(delimiters, 0);
5554 spacers.Data.CopyTo(delimiters, separators.Length);
5555 bool dfound = false;
5556 do
5557 {
5558 dfound = false;
5559 int cindex = -1;
5560 string cdeli = "";
5561 for (int i = 0; i < delimiters.Length; i++)
5562 {
5563 int index = str.IndexOf(delimiters[i].ToString());
5564 bool found = index != -1;
5565 if (found && String.Empty != delimiters[i].ToString())
5566 {
5567 if ((cindex > index) || (cindex == -1))
5568 {
5569 cindex = index;
5570 cdeli = delimiters[i].ToString();
5571 }
5572 dfound = dfound || found;
5573 }
5574 }
5575 if (cindex != -1)
5576 {
5577 if (cindex > 0)
5578 {
5579 ret.Add(new LSL_String(str.Substring(0, cindex)));
5580 }
5581 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5582 for (int j = 0; j < spacers.Length; j++)
5583 {
5584 if (spacers.Data[j].ToString() == cdeli)
5585 {
5586 ret.Add(new LSL_String(cdeli));
5587 break;
5588 }
5589 }
5590 str = str.Substring(cindex + cdeli.Length);
5591 }
5592 } while (dfound);
5593 if (str != "")
5594 {
5595 ret.Add(new LSL_String(str));
5596 }
5597 return ret;
5598 } 5874 }
5599 5875
5600 public LSL_Integer llOverMyLand(string id) 5876 public LSL_Integer llOverMyLand(string id)
@@ -5797,7 +6073,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5797 return m_host.ParentGroup.RootPart.AttachmentPoint; 6073 return m_host.ParentGroup.RootPart.AttachmentPoint;
5798 } 6074 }
5799 6075
5800 public LSL_Integer llGetFreeMemory() 6076 public virtual LSL_Integer llGetFreeMemory()
5801 { 6077 {
5802 m_host.AddScriptLPS(1); 6078 m_host.AddScriptLPS(1);
5803 // Make scripts designed for LSO happy 6079 // Make scripts designed for LSO happy
@@ -6108,14 +6384,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6108 6384
6109 protected UUID GetTaskInventoryItem(string name) 6385 protected UUID GetTaskInventoryItem(string name)
6110 { 6386 {
6111 lock (m_host.TaskInventory) 6387 m_host.TaskInventory.LockItemsForRead(true);
6388 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6112 { 6389 {
6113 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6390 if (inv.Value.Name == name)
6114 { 6391 {
6115 if (inv.Value.Name == name) 6392 m_host.TaskInventory.LockItemsForRead(false);
6116 return inv.Key; 6393 return inv.Key;
6117 } 6394 }
6118 } 6395 }
6396 m_host.TaskInventory.LockItemsForRead(false);
6119 6397
6120 return UUID.Zero; 6398 return UUID.Zero;
6121 } 6399 }
@@ -6443,22 +6721,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6443 } 6721 }
6444 6722
6445 // copy the first script found with this inventory name 6723 // copy the first script found with this inventory name
6446 lock (m_host.TaskInventory) 6724 m_host.TaskInventory.LockItemsForRead(true);
6725 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6447 { 6726 {
6448 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6727 if (inv.Value.Name == name)
6449 { 6728 {
6450 if (inv.Value.Name == name) 6729 // make sure the object is a script
6730 if (10 == inv.Value.Type)
6451 { 6731 {
6452 // make sure the object is a script 6732 found = true;
6453 if (10 == inv.Value.Type) 6733 srcId = inv.Key;
6454 { 6734 break;
6455 found = true;
6456 srcId = inv.Key;
6457 break;
6458 }
6459 } 6735 }
6460 } 6736 }
6461 } 6737 }
6738 m_host.TaskInventory.LockItemsForRead(false);
6462 6739
6463 if (!found) 6740 if (!found)
6464 { 6741 {
@@ -6542,6 +6819,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6542 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6819 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6543 { 6820 {
6544 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6821 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6822 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6823 return shapeBlock;
6545 6824
6546 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6825 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6547 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6826 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6617,6 +6896,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6617 6896
6618 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6897 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6619 { 6898 {
6899 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6900 return;
6901
6620 ObjectShapePacket.ObjectDataBlock shapeBlock; 6902 ObjectShapePacket.ObjectDataBlock shapeBlock;
6621 6903
6622 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6904 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6666,6 +6948,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6666 6948
6667 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6949 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6668 { 6950 {
6951 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6952 return;
6953
6669 ObjectShapePacket.ObjectDataBlock shapeBlock; 6954 ObjectShapePacket.ObjectDataBlock shapeBlock;
6670 6955
6671 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6956 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6708,6 +6993,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6708 6993
6709 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) 6994 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)
6710 { 6995 {
6996 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6997 return;
6998
6711 ObjectShapePacket.ObjectDataBlock shapeBlock; 6999 ObjectShapePacket.ObjectDataBlock shapeBlock;
6712 7000
6713 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6834,6 +7122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6834 7122
6835 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7123 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6836 { 7124 {
7125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7126 return;
7127
6837 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7128 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6838 UUID sculptId; 7129 UUID sculptId;
6839 7130
@@ -6849,13 +7140,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6849 shapeBlock.PathScaleX = 100; 7140 shapeBlock.PathScaleX = 100;
6850 shapeBlock.PathScaleY = 150; 7141 shapeBlock.PathScaleY = 150;
6851 7142
6852 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7143 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6853 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7144 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6854 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7145 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6855 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7146 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6856 { 7147 {
6857 // default 7148 // default
6858 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7149 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6859 } 7150 }
6860 7151
6861 // retain pathcurve 7152 // retain pathcurve
@@ -6872,23 +7163,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6872 SetPrimParams(m_host, rules); 7163 SetPrimParams(m_host, rules);
6873 } 7164 }
6874 7165
6875 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7166 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6876 { 7167 {
6877 m_host.AddScriptLPS(1); 7168 m_host.AddScriptLPS(1);
6878 7169
6879 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7170 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7171 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7172 if (parts.Count>0)
7173 {
7174 try
7175 {
7176 parts[0].ParentGroup.areUpdatesSuspended = true;
7177 foreach (SceneObjectPart part in parts)
7178 SetPrimParams(part, rules);
7179 }
7180 finally
7181 {
7182 parts[0].ParentGroup.areUpdatesSuspended = false;
7183 }
7184 }
7185 if (avatars.Count > 0)
7186 {
7187 foreach (ScenePresence avatar in avatars)
7188 SetPrimParams(avatar, rules);
7189 }
7190 }
6880 7191
6881 foreach (SceneObjectPart part in parts) 7192 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6882 SetPrimParams(part, rules); 7193 {
7194 llSetLinkPrimitiveParamsFast(linknumber, rules);
7195 ScriptSleep(200);
6883 } 7196 }
6884 7197
6885 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7198 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6886 { 7199 {
6887 llSetLinkPrimitiveParams(linknumber, rules); 7200 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7201 //We only support PRIM_POSITION and PRIM_ROTATION
7202
7203 int idx = 0;
7204
7205 while (idx < rules.Length)
7206 {
7207 int code = rules.GetLSLIntegerItem(idx++);
7208
7209 int remain = rules.Length - idx;
7210
7211
7212
7213 switch (code)
7214 {
7215 case (int)ScriptBaseClass.PRIM_POSITION:
7216 if (remain < 1)
7217 return;
7218 LSL_Vector v;
7219 v = rules.GetVector3Item(idx++);
7220 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7221 av.SendFullUpdateToAllClients();
7222
7223 break;
7224
7225 case (int)ScriptBaseClass.PRIM_ROTATION:
7226 if (remain < 1)
7227 return;
7228 LSL_Rotation r;
7229 r = rules.GetQuaternionItem(idx++);
7230 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7231 av.SendFullUpdateToAllClients();
7232 break;
7233 }
7234 }
7235
6888 } 7236 }
6889 7237
6890 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7238 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6891 { 7239 {
7240 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7241 return;
7242
6892 int idx = 0; 7243 int idx = 0;
6893 7244
6894 while (idx < rules.Length) 7245 while (idx < rules.Length)
@@ -7720,24 +8071,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7720 break; 8071 break;
7721 8072
7722 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8073 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7723 // TODO--------------
7724 if (remain < 1) 8074 if (remain < 1)
7725 return res; 8075 return res;
8076 face = (int)rules.GetLSLIntegerItem(idx++);
7726 8077
7727 face=(int)rules.GetLSLIntegerItem(idx++); 8078 tex = part.Shape.Textures;
7728 8079 int shiny;
7729 res.Add(new LSL_Integer(0)); 8080 if (face == ScriptBaseClass.ALL_SIDES)
7730 res.Add(new LSL_Integer(0)); 8081 {
8082 for (face = 0; face < GetNumberOfSides(part); face++)
8083 {
8084 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8085 if (shinyness == Shininess.High)
8086 {
8087 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8088 }
8089 else if (shinyness == Shininess.Medium)
8090 {
8091 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8092 }
8093 else if (shinyness == Shininess.Low)
8094 {
8095 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8096 }
8097 else
8098 {
8099 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8100 }
8101 res.Add(new LSL_Integer(shiny));
8102 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8103 }
8104 }
8105 else
8106 {
8107 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8108 if (shinyness == Shininess.High)
8109 {
8110 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8111 }
8112 else if (shinyness == Shininess.Medium)
8113 {
8114 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8115 }
8116 else if (shinyness == Shininess.Low)
8117 {
8118 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8119 }
8120 else
8121 {
8122 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8123 }
8124 res.Add(new LSL_Integer(shiny));
8125 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8126 }
7731 break; 8127 break;
7732 8128
7733 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8129 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7734 // TODO--------------
7735 if (remain < 1) 8130 if (remain < 1)
7736 return res; 8131 return res;
8132 face = (int)rules.GetLSLIntegerItem(idx++);
7737 8133
7738 face=(int)rules.GetLSLIntegerItem(idx++); 8134 tex = part.Shape.Textures;
7739 8135 int fullbright;
7740 res.Add(new LSL_Integer(0)); 8136 if (face == ScriptBaseClass.ALL_SIDES)
8137 {
8138 for (face = 0; face < GetNumberOfSides(part); face++)
8139 {
8140 if (tex.GetFace((uint)face).Fullbright == true)
8141 {
8142 fullbright = ScriptBaseClass.TRUE;
8143 }
8144 else
8145 {
8146 fullbright = ScriptBaseClass.FALSE;
8147 }
8148 res.Add(new LSL_Integer(fullbright));
8149 }
8150 }
8151 else
8152 {
8153 if (tex.GetFace((uint)face).Fullbright == true)
8154 {
8155 fullbright = ScriptBaseClass.TRUE;
8156 }
8157 else
8158 {
8159 fullbright = ScriptBaseClass.FALSE;
8160 }
8161 res.Add(new LSL_Integer(fullbright));
8162 }
7741 break; 8163 break;
7742 8164
7743 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8165 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7758,14 +8180,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7758 break; 8180 break;
7759 8181
7760 case (int)ScriptBaseClass.PRIM_TEXGEN: 8182 case (int)ScriptBaseClass.PRIM_TEXGEN:
7761 // TODO--------------
7762 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8183 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7763 if (remain < 1) 8184 if (remain < 1)
7764 return res; 8185 return res;
8186 face = (int)rules.GetLSLIntegerItem(idx++);
7765 8187
7766 face=(int)rules.GetLSLIntegerItem(idx++); 8188 tex = part.Shape.Textures;
7767 8189 if (face == ScriptBaseClass.ALL_SIDES)
7768 res.Add(new LSL_Integer(0)); 8190 {
8191 for (face = 0; face < GetNumberOfSides(part); face++)
8192 {
8193 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8194 {
8195 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8196 }
8197 else
8198 {
8199 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8200 }
8201 }
8202 }
8203 else
8204 {
8205 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8206 {
8207 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8208 }
8209 else
8210 {
8211 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8212 }
8213 }
7769 break; 8214 break;
7770 8215
7771 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8216 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7784,13 +8229,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7784 break; 8229 break;
7785 8230
7786 case (int)ScriptBaseClass.PRIM_GLOW: 8231 case (int)ScriptBaseClass.PRIM_GLOW:
7787 // TODO--------------
7788 if (remain < 1) 8232 if (remain < 1)
7789 return res; 8233 return res;
8234 face = (int)rules.GetLSLIntegerItem(idx++);
7790 8235
7791 face=(int)rules.GetLSLIntegerItem(idx++); 8236 tex = part.Shape.Textures;
7792 8237 float primglow;
7793 res.Add(new LSL_Float(0)); 8238 if (face == ScriptBaseClass.ALL_SIDES)
8239 {
8240 for (face = 0; face < GetNumberOfSides(part); face++)
8241 {
8242 primglow = tex.GetFace((uint)face).Glow;
8243 res.Add(new LSL_Float(primglow));
8244 }
8245 }
8246 else
8247 {
8248 primglow = tex.GetFace((uint)face).Glow;
8249 res.Add(new LSL_Float(primglow));
8250 }
7794 break; 8251 break;
7795 case (int)ScriptBaseClass.PRIM_TEXT: 8252 case (int)ScriptBaseClass.PRIM_TEXT:
7796 Color4 textColor = part.GetTextColor(); 8253 Color4 textColor = part.GetTextColor();
@@ -8096,8 +8553,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8096 // The function returns an ordered list 8553 // The function returns an ordered list
8097 // representing the tokens found in the supplied 8554 // representing the tokens found in the supplied
8098 // sources string. If two successive tokenizers 8555 // sources string. If two successive tokenizers
8099 // are encountered, then a NULL entry is added 8556 // are encountered, then a null-string entry is
8100 // to the list. 8557 // added to the list.
8101 // 8558 //
8102 // It is a precondition that the source and 8559 // It is a precondition that the source and
8103 // toekizer lisst are non-null. If they are null, 8560 // toekizer lisst are non-null. If they are null,
@@ -8105,7 +8562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8105 // while their lengths are being determined. 8562 // while their lengths are being determined.
8106 // 8563 //
8107 // A small amount of working memoryis required 8564 // A small amount of working memoryis required
8108 // of approximately 8*#tokenizers. 8565 // of approximately 8*#tokenizers + 8*srcstrlen.
8109 // 8566 //
8110 // There are many ways in which this function 8567 // There are many ways in which this function
8111 // can be implemented, this implementation is 8568 // can be implemented, this implementation is
@@ -8121,136 +8578,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8121 // and eliminates redundant tokenizers as soon 8578 // and eliminates redundant tokenizers as soon
8122 // as is possible. 8579 // as is possible.
8123 // 8580 //
8124 // The implementation tries to avoid any copying 8581 // The implementation tries to minimize temporary
8125 // of arrays or other objects. 8582 // garbage generation.
8126 // </remarks> 8583 // </remarks>
8127 8584
8128 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8585 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8129 { 8586 {
8130 int beginning = 0; 8587 return ParseString2List(src, separators, spacers, true);
8131 int srclen = src.Length; 8588 }
8132 int seplen = separators.Length;
8133 object[] separray = separators.Data;
8134 int spclen = spacers.Length;
8135 object[] spcarray = spacers.Data;
8136 int mlen = seplen+spclen;
8137
8138 int[] offset = new int[mlen+1];
8139 bool[] active = new bool[mlen];
8140 8589
8141 int best; 8590 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8142 int j; 8591 {
8592 int srclen = src.Length;
8593 int seplen = separators.Length;
8594 object[] separray = separators.Data;
8595 int spclen = spacers.Length;
8596 object[] spcarray = spacers.Data;
8597 int dellen = 0;
8598 string[] delarray = new string[seplen+spclen];
8143 8599
8144 // Initial capacity reduces resize cost 8600 int outlen = 0;
8601 string[] outarray = new string[srclen*2+1];
8145 8602
8146 LSL_List tokens = new LSL_List(); 8603 int i, j;
8604 string d;
8147 8605
8148 m_host.AddScriptLPS(1); 8606 m_host.AddScriptLPS(1);
8149 8607
8150 // All entries are initially valid 8608 /*
8151 8609 * Convert separator and spacer lists to C# strings.
8152 for (int i = 0; i < mlen; i++) 8610 * Also filter out null strings so we don't hang.
8153 active[i] = true; 8611 */
8154 8612 for (i = 0; i < seplen; i ++) {
8155 offset[mlen] = srclen; 8613 d = separray[i].ToString();
8156 8614 if (d.Length > 0) {
8157 while (beginning < srclen) 8615 delarray[dellen++] = d;
8158 { 8616 }
8159 8617 }
8160 best = mlen; // as bad as it gets 8618 seplen = dellen;
8161
8162 // Scan for separators
8163 8619
8164 for (j = 0; j < seplen; j++) 8620 for (i = 0; i < spclen; i ++) {
8165 { 8621 d = spcarray[i].ToString();
8166 if (active[j]) 8622 if (d.Length > 0) {
8167 { 8623 delarray[dellen++] = d;
8168 // scan all of the markers
8169 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8170 {
8171 // not present at all
8172 active[j] = false;
8173 }
8174 else
8175 {
8176 // present and correct
8177 if (offset[j] < offset[best])
8178 {
8179 // closest so far
8180 best = j;
8181 if (offset[best] == beginning)
8182 break;
8183 }
8184 }
8185 }
8186 } 8624 }
8625 }
8187 8626
8188 // Scan for spacers 8627 /*
8628 * Scan through source string from beginning to end.
8629 */
8630 for (i = 0;;) {
8189 8631
8190 if (offset[best] != beginning) 8632 /*
8191 { 8633 * Find earliest delimeter in src starting at i (if any).
8192 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8634 */
8193 { 8635 int earliestDel = -1;
8194 if (active[j]) 8636 int earliestSrc = srclen;
8195 { 8637 string earliestStr = null;
8196 // scan all of the markers 8638 for (j = 0; j < dellen; j ++) {
8197 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8639 d = delarray[j];
8198 { 8640 if (d != null) {
8199 // not present at all 8641 int index = src.IndexOf(d, i);
8200 active[j] = false; 8642 if (index < 0) {
8201 } 8643 delarray[j] = null; // delim nowhere in src, don't check it anymore
8202 else 8644 } else if (index < earliestSrc) {
8203 { 8645 earliestSrc = index; // where delimeter starts in source string
8204 // present and correct 8646 earliestDel = j; // where delimeter is in delarray[]
8205 if (offset[j] < offset[best]) 8647 earliestStr = d; // the delimeter string from delarray[]
8206 { 8648 if (index == i) break; // can't do any better than found at beg of string
8207 // closest so far
8208 best = j;
8209 }
8210 }
8211 } 8649 }
8212 } 8650 }
8213 } 8651 }
8214 8652
8215 // This is the normal exit from the scanning loop 8653 /*
8216 8654 * Output source string starting at i through start of earliest delimeter.
8217 if (best == mlen) 8655 */
8218 { 8656 if (keepNulls || (earliestSrc > i)) {
8219 // no markers were found on this pass 8657 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8220 // so we're pretty much done
8221 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8222 break;
8223 } 8658 }
8224 8659
8225 // Otherwise we just add the newly delimited token 8660 /*
8226 // and recalculate where the search should continue. 8661 * If no delimeter found at or after i, we're done scanning.
8662 */
8663 if (earliestDel < 0) break;
8227 8664
8228 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8665 /*
8229 8666 * If delimeter was a spacer, output the spacer.
8230 if (best < seplen) 8667 */
8231 { 8668 if (earliestDel >= seplen) {
8232 beginning = offset[best] + (separray[best].ToString()).Length; 8669 outarray[outlen++] = earliestStr;
8233 } 8670 }
8234 else
8235 {
8236 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8237 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8238 }
8239 }
8240 8671
8241 // This an awkward an not very intuitive boundary case. If the 8672 /*
8242 // last substring is a tokenizer, then there is an implied trailing 8673 * Look at rest of src string following delimeter.
8243 // null list entry. Hopefully the single comparison will not be too 8674 */
8244 // arduous. Alternatively the 'break' could be replced with a return 8675 i = earliestSrc + earliestStr.Length;
8245 // but that's shabby programming.
8246
8247 if (beginning == srclen)
8248 {
8249 if (srclen != 0)
8250 tokens.Add(new LSL_String(""));
8251 } 8676 }
8252 8677
8253 return tokens; 8678 /*
8679 * Make up an exact-sized output array suitable for an LSL_List object.
8680 */
8681 object[] outlist = new object[outlen];
8682 for (i = 0; i < outlen; i ++) {
8683 outlist[i] = new LSL_String(outarray[i]);
8684 }
8685 return new LSL_List(outlist);
8254 } 8686 }
8255 8687
8256 public LSL_Integer llGetObjectPermMask(int mask) 8688 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8327,28 +8759,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8327 { 8759 {
8328 m_host.AddScriptLPS(1); 8760 m_host.AddScriptLPS(1);
8329 8761
8330 lock (m_host.TaskInventory) 8762 m_host.TaskInventory.LockItemsForRead(true);
8763 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8331 { 8764 {
8332 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8765 if (inv.Value.Name == item)
8333 { 8766 {
8334 if (inv.Value.Name == item) 8767 m_host.TaskInventory.LockItemsForRead(false);
8768 switch (mask)
8335 { 8769 {
8336 switch (mask) 8770 case 0:
8337 { 8771 return (int)inv.Value.BasePermissions;
8338 case 0: 8772 case 1:
8339 return (int)inv.Value.BasePermissions; 8773 return (int)inv.Value.CurrentPermissions;
8340 case 1: 8774 case 2:
8341 return (int)inv.Value.CurrentPermissions; 8775 return (int)inv.Value.GroupPermissions;
8342 case 2: 8776 case 3:
8343 return (int)inv.Value.GroupPermissions; 8777 return (int)inv.Value.EveryonePermissions;
8344 case 3: 8778 case 4:
8345 return (int)inv.Value.EveryonePermissions; 8779 return (int)inv.Value.NextPermissions;
8346 case 4:
8347 return (int)inv.Value.NextPermissions;
8348 }
8349 } 8780 }
8350 } 8781 }
8351 } 8782 }
8783 m_host.TaskInventory.LockItemsForRead(false);
8352 8784
8353 return -1; 8785 return -1;
8354 } 8786 }
@@ -8395,16 +8827,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8395 { 8827 {
8396 m_host.AddScriptLPS(1); 8828 m_host.AddScriptLPS(1);
8397 8829
8398 lock (m_host.TaskInventory) 8830 m_host.TaskInventory.LockItemsForRead(true);
8831 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8399 { 8832 {
8400 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8833 if (inv.Value.Name == item)
8401 { 8834 {
8402 if (inv.Value.Name == item) 8835 m_host.TaskInventory.LockItemsForRead(false);
8403 { 8836 return inv.Value.CreatorID.ToString();
8404 return inv.Value.CreatorID.ToString();
8405 }
8406 } 8837 }
8407 } 8838 }
8839 m_host.TaskInventory.LockItemsForRead(false);
8408 8840
8409 llSay(0, "No item name '" + item + "'"); 8841 llSay(0, "No item name '" + item + "'");
8410 8842
@@ -8664,17 +9096,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8664 int width = 0; 9096 int width = 0;
8665 int height = 0; 9097 int height = 0;
8666 9098
8667 ParcelMediaCommandEnum? commandToSend = null; 9099 uint commandToSend = 0;
8668 float time = 0.0f; // default is from start 9100 float time = 0.0f; // default is from start
8669 9101
8670 ScenePresence presence = null; 9102 ScenePresence presence = null;
8671 9103
8672 for (int i = 0; i < commandList.Data.Length; i++) 9104 for (int i = 0; i < commandList.Data.Length; i++)
8673 { 9105 {
8674 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9106 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8675 switch (command) 9107 switch (command)
8676 { 9108 {
8677 case ParcelMediaCommandEnum.Agent: 9109 case (uint)ParcelMediaCommandEnum.Agent:
8678 // we send only to one agent 9110 // we send only to one agent
8679 if ((i + 1) < commandList.Length) 9111 if ((i + 1) < commandList.Length)
8680 { 9112 {
@@ -8691,25 +9123,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8691 } 9123 }
8692 break; 9124 break;
8693 9125
8694 case ParcelMediaCommandEnum.Loop: 9126 case (uint)ParcelMediaCommandEnum.Loop:
8695 loop = 1; 9127 loop = 1;
8696 commandToSend = command; 9128 commandToSend = command;
8697 update = true; //need to send the media update packet to set looping 9129 update = true; //need to send the media update packet to set looping
8698 break; 9130 break;
8699 9131
8700 case ParcelMediaCommandEnum.Play: 9132 case (uint)ParcelMediaCommandEnum.Play:
8701 loop = 0; 9133 loop = 0;
8702 commandToSend = command; 9134 commandToSend = command;
8703 update = true; //need to send the media update packet to make sure it doesn't loop 9135 update = true; //need to send the media update packet to make sure it doesn't loop
8704 break; 9136 break;
8705 9137
8706 case ParcelMediaCommandEnum.Pause: 9138 case (uint)ParcelMediaCommandEnum.Pause:
8707 case ParcelMediaCommandEnum.Stop: 9139 case (uint)ParcelMediaCommandEnum.Stop:
8708 case ParcelMediaCommandEnum.Unload: 9140 case (uint)ParcelMediaCommandEnum.Unload:
8709 commandToSend = command; 9141 commandToSend = command;
8710 break; 9142 break;
8711 9143
8712 case ParcelMediaCommandEnum.Url: 9144 case (uint)ParcelMediaCommandEnum.Url:
8713 if ((i + 1) < commandList.Length) 9145 if ((i + 1) < commandList.Length)
8714 { 9146 {
8715 if (commandList.Data[i + 1] is LSL_String) 9147 if (commandList.Data[i + 1] is LSL_String)
@@ -8722,7 +9154,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8722 } 9154 }
8723 break; 9155 break;
8724 9156
8725 case ParcelMediaCommandEnum.Texture: 9157 case (uint)ParcelMediaCommandEnum.Texture:
8726 if ((i + 1) < commandList.Length) 9158 if ((i + 1) < commandList.Length)
8727 { 9159 {
8728 if (commandList.Data[i + 1] is LSL_String) 9160 if (commandList.Data[i + 1] is LSL_String)
@@ -8735,7 +9167,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8735 } 9167 }
8736 break; 9168 break;
8737 9169
8738 case ParcelMediaCommandEnum.Time: 9170 case (uint)ParcelMediaCommandEnum.Time:
8739 if ((i + 1) < commandList.Length) 9171 if ((i + 1) < commandList.Length)
8740 { 9172 {
8741 if (commandList.Data[i + 1] is LSL_Float) 9173 if (commandList.Data[i + 1] is LSL_Float)
@@ -8747,7 +9179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8747 } 9179 }
8748 break; 9180 break;
8749 9181
8750 case ParcelMediaCommandEnum.AutoAlign: 9182 case (uint)ParcelMediaCommandEnum.AutoAlign:
8751 if ((i + 1) < commandList.Length) 9183 if ((i + 1) < commandList.Length)
8752 { 9184 {
8753 if (commandList.Data[i + 1] is LSL_Integer) 9185 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8761,7 +9193,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8761 } 9193 }
8762 break; 9194 break;
8763 9195
8764 case ParcelMediaCommandEnum.Type: 9196 case (uint)ParcelMediaCommandEnum.Type:
8765 if ((i + 1) < commandList.Length) 9197 if ((i + 1) < commandList.Length)
8766 { 9198 {
8767 if (commandList.Data[i + 1] is LSL_String) 9199 if (commandList.Data[i + 1] is LSL_String)
@@ -8774,7 +9206,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8774 } 9206 }
8775 break; 9207 break;
8776 9208
8777 case ParcelMediaCommandEnum.Desc: 9209 case (uint)ParcelMediaCommandEnum.Desc:
8778 if ((i + 1) < commandList.Length) 9210 if ((i + 1) < commandList.Length)
8779 { 9211 {
8780 if (commandList.Data[i + 1] is LSL_String) 9212 if (commandList.Data[i + 1] is LSL_String)
@@ -8787,7 +9219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8787 } 9219 }
8788 break; 9220 break;
8789 9221
8790 case ParcelMediaCommandEnum.Size: 9222 case (uint)ParcelMediaCommandEnum.Size:
8791 if ((i + 2) < commandList.Length) 9223 if ((i + 2) < commandList.Length)
8792 { 9224 {
8793 if (commandList.Data[i + 1] is LSL_Integer) 9225 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8857,7 +9289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8857 } 9289 }
8858 } 9290 }
8859 9291
8860 if (commandToSend != null) 9292 if (commandToSend != 0)
8861 { 9293 {
8862 // the commandList contained a start/stop/... command, too 9294 // the commandList contained a start/stop/... command, too
8863 if (presence == null) 9295 if (presence == null)
@@ -8894,7 +9326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8894 9326
8895 if (aList.Data[i] != null) 9327 if (aList.Data[i] != null)
8896 { 9328 {
8897 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9329 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
8898 { 9330 {
8899 case ParcelMediaCommandEnum.Url: 9331 case ParcelMediaCommandEnum.Url:
8900 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9332 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -8937,16 +9369,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8937 { 9369 {
8938 m_host.AddScriptLPS(1); 9370 m_host.AddScriptLPS(1);
8939 9371
8940 lock (m_host.TaskInventory) 9372 m_host.TaskInventory.LockItemsForRead(true);
9373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8941 { 9374 {
8942 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9375 if (inv.Value.Name == name)
8943 { 9376 {
8944 if (inv.Value.Name == name) 9377 m_host.TaskInventory.LockItemsForRead(false);
8945 { 9378 return inv.Value.Type;
8946 return inv.Value.Type;
8947 }
8948 } 9379 }
8949 } 9380 }
9381 m_host.TaskInventory.LockItemsForRead(false);
8950 9382
8951 return -1; 9383 return -1;
8952 } 9384 }
@@ -8957,15 +9389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8957 9389
8958 if (quick_pay_buttons.Data.Length < 4) 9390 if (quick_pay_buttons.Data.Length < 4)
8959 { 9391 {
8960 LSLError("List must have at least 4 elements"); 9392 int x;
8961 return; 9393 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9394 {
9395 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9396 }
8962 } 9397 }
8963 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9398 int[] nPrice = new int[5];
8964 9399 nPrice[0]=price;
8965 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9400 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8966 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9401 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8967 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9402 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8968 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9403 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9404 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8969 m_host.ParentGroup.HasGroupChanged = true; 9405 m_host.ParentGroup.HasGroupChanged = true;
8970 } 9406 }
8971 9407
@@ -8977,17 +9413,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8977 if (invItemID == UUID.Zero) 9413 if (invItemID == UUID.Zero)
8978 return new LSL_Vector(); 9414 return new LSL_Vector();
8979 9415
8980 lock (m_host.TaskInventory) 9416 m_host.TaskInventory.LockItemsForRead(true);
9417 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8981 { 9418 {
8982 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9419 m_host.TaskInventory.LockItemsForRead(false);
8983 return new LSL_Vector(); 9420 return new LSL_Vector();
9421 }
8984 9422
8985 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9423 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8986 { 9424 {
8987 ShoutError("No permissions to track the camera"); 9425 ShoutError("No permissions to track the camera");
8988 return new LSL_Vector(); 9426 m_host.TaskInventory.LockItemsForRead(false);
8989 } 9427 return new LSL_Vector();
8990 } 9428 }
9429 m_host.TaskInventory.LockItemsForRead(false);
8991 9430
8992 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9431 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8993 if (presence != null) 9432 if (presence != null)
@@ -9005,17 +9444,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9005 if (invItemID == UUID.Zero) 9444 if (invItemID == UUID.Zero)
9006 return new LSL_Rotation(); 9445 return new LSL_Rotation();
9007 9446
9008 lock (m_host.TaskInventory) 9447 m_host.TaskInventory.LockItemsForRead(true);
9448 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9009 { 9449 {
9010 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9450 m_host.TaskInventory.LockItemsForRead(false);
9011 return new LSL_Rotation(); 9451 return new LSL_Rotation();
9012 9452 }
9013 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9453 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9014 { 9454 {
9015 ShoutError("No permissions to track the camera"); 9455 ShoutError("No permissions to track the camera");
9016 return new LSL_Rotation(); 9456 m_host.TaskInventory.LockItemsForRead(false);
9017 } 9457 return new LSL_Rotation();
9018 } 9458 }
9459 m_host.TaskInventory.LockItemsForRead(false);
9019 9460
9020 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9461 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9021 if (presence != null) 9462 if (presence != null)
@@ -9077,8 +9518,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9077 { 9518 {
9078 m_host.AddScriptLPS(1); 9519 m_host.AddScriptLPS(1);
9079 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9520 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9080 if (detectedParams == null) return; // only works on the first detected avatar 9521 if (detectedParams == null)
9081 9522 {
9523 if (m_host.IsAttachment == true)
9524 {
9525 detectedParams = new DetectParams();
9526 detectedParams.Key = m_host.OwnerID;
9527 }
9528 else
9529 {
9530 return;
9531 }
9532 }
9533
9082 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9534 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9083 if (avatar != null) 9535 if (avatar != null)
9084 { 9536 {
@@ -9086,6 +9538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9086 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9538 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9087 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9539 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9088 } 9540 }
9541
9089 ScriptSleep(1000); 9542 ScriptSleep(1000);
9090 } 9543 }
9091 9544
@@ -9165,14 +9618,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9165 if (objectID == UUID.Zero) return; 9618 if (objectID == UUID.Zero) return;
9166 9619
9167 UUID agentID; 9620 UUID agentID;
9168 lock (m_host.TaskInventory) 9621 m_host.TaskInventory.LockItemsForRead(true);
9169 { 9622 // we need the permission first, to know which avatar we want to set the camera for
9170 // we need the permission first, to know which avatar we want to set the camera for 9623 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9171 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9172 9624
9173 if (agentID == UUID.Zero) return; 9625 if (agentID == UUID.Zero)
9174 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9626 {
9627 m_host.TaskInventory.LockItemsForRead(false);
9628 return;
9629 }
9630 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9631 {
9632 m_host.TaskInventory.LockItemsForRead(false);
9633 return;
9175 } 9634 }
9635 m_host.TaskInventory.LockItemsForRead(false);
9176 9636
9177 ScenePresence presence = World.GetScenePresence(agentID); 9637 ScenePresence presence = World.GetScenePresence(agentID);
9178 9638
@@ -9222,12 +9682,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9222 9682
9223 // we need the permission first, to know which avatar we want to clear the camera for 9683 // we need the permission first, to know which avatar we want to clear the camera for
9224 UUID agentID; 9684 UUID agentID;
9225 lock (m_host.TaskInventory) 9685 m_host.TaskInventory.LockItemsForRead(true);
9686 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9687 if (agentID == UUID.Zero)
9688 {
9689 m_host.TaskInventory.LockItemsForRead(false);
9690 return;
9691 }
9692 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9226 { 9693 {
9227 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9694 m_host.TaskInventory.LockItemsForRead(false);
9228 if (agentID == UUID.Zero) return; 9695 return;
9229 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9230 } 9696 }
9697 m_host.TaskInventory.LockItemsForRead(false);
9231 9698
9232 ScenePresence presence = World.GetScenePresence(agentID); 9699 ScenePresence presence = World.GetScenePresence(agentID);
9233 9700
@@ -9294,19 +9761,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9294 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 9761 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9295 { 9762 {
9296 m_host.AddScriptLPS(1); 9763 m_host.AddScriptLPS(1);
9297 string ret = String.Empty; 9764
9298 string src1 = llBase64ToString(str1); 9765 if (str1 == String.Empty)
9299 string src2 = llBase64ToString(str2); 9766 return String.Empty;
9300 int c = 0; 9767 if (str2 == String.Empty)
9301 for (int i = 0; i < src1.Length; i++) 9768 return str1;
9769
9770 byte[] data1 = Convert.FromBase64String(str1);
9771 byte[] data2 = Convert.FromBase64String(str2);
9772
9773 byte[] d2 = new Byte[data1.Length];
9774 int pos = 0;
9775
9776 if (data1.Length <= data2.Length)
9302 { 9777 {
9303 ret += (char) (src1[i] ^ src2[c]); 9778 Array.Copy(data2, 0, d2, 0, data1.Length);
9779 }
9780 else
9781 {
9782 while (pos < data1.Length)
9783 {
9784 int len = data1.Length - pos;
9785 if (len > data2.Length)
9786 len = data2.Length;
9304 9787
9305 c++; 9788 Array.Copy(data2, 0, d2, pos, len);
9306 if (c >= src2.Length) 9789 pos += len;
9307 c = 0; 9790 }
9308 } 9791 }
9309 return llStringToBase64(ret); 9792
9793 for (pos = 0 ; pos < data1.Length ; pos++ )
9794 data1[pos] ^= d2[pos];
9795
9796 return Convert.ToBase64String(data1);
9310 } 9797 }
9311 9798
9312 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 9799 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9684,15 +10171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9684 10171
9685 internal UUID ScriptByName(string name) 10172 internal UUID ScriptByName(string name)
9686 { 10173 {
9687 lock (m_host.TaskInventory) 10174 m_host.TaskInventory.LockItemsForRead(true);
10175
10176 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9688 { 10177 {
9689 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10178 if (item.Type == 10 && item.Name == name)
9690 { 10179 {
9691 if (item.Type == 10 && item.Name == name) 10180 m_host.TaskInventory.LockItemsForRead(false);
9692 return item.ItemID; 10181 return item.ItemID;
9693 } 10182 }
9694 } 10183 }
9695 10184
10185 m_host.TaskInventory.LockItemsForRead(false);
10186
9696 return UUID.Zero; 10187 return UUID.Zero;
9697 } 10188 }
9698 10189
@@ -9733,6 +10224,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9733 { 10224 {
9734 m_host.AddScriptLPS(1); 10225 m_host.AddScriptLPS(1);
9735 10226
10227 //Clone is thread safe
9736 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10228 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9737 10229
9738 UUID assetID = UUID.Zero; 10230 UUID assetID = UUID.Zero;
@@ -9795,6 +10287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9795 { 10287 {
9796 m_host.AddScriptLPS(1); 10288 m_host.AddScriptLPS(1);
9797 10289
10290 //Clone is thread safe
9798 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10291 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9799 10292
9800 UUID assetID = UUID.Zero; 10293 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index fe71ed5..1fa8c30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -73,6 +73,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 74 m_LSFunctionsEnabled = true;
75 75
76 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
77 m_LSFunctionsEnabled = true;
78
76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); 79 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
77 if (m_comms == null) 80 if (m_comms == null)
78 m_LSFunctionsEnabled = false; 81 m_LSFunctionsEnabled = false;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 01b64eb..db43902 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -769,18 +769,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
769 if (target != null) 769 if (target != null)
770 { 770 {
771 UUID animID=UUID.Zero; 771 UUID animID=UUID.Zero;
772 lock (m_host.TaskInventory) 772 m_host.TaskInventory.LockItemsForRead(true);
773 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
773 { 774 {
774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 775 if (inv.Value.Name == animation)
775 { 776 {
776 if (inv.Value.Name == animation) 777 if (inv.Value.Type == (int)AssetType.Animation)
777 { 778 animID = inv.Value.AssetID;
778 if (inv.Value.Type == (int)AssetType.Animation) 779 continue;
779 animID = inv.Value.AssetID;
780 continue;
781 }
782 } 780 }
783 } 781 }
782 m_host.TaskInventory.LockItemsForRead(false);
784 if (animID == UUID.Zero) 783 if (animID == UUID.Zero)
785 target.Animator.AddAnimation(animation, m_host.UUID); 784 target.Animator.AddAnimation(animation, m_host.UUID);
786 else 785 else
@@ -802,18 +801,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
802 if (target != null) 801 if (target != null)
803 { 802 {
804 UUID animID=UUID.Zero; 803 UUID animID=UUID.Zero;
805 lock (m_host.TaskInventory) 804 m_host.TaskInventory.LockItemsForRead(true);
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
806 { 806 {
807 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 807 if (inv.Value.Name == animation)
808 { 808 {
809 if (inv.Value.Name == animation) 809 if (inv.Value.Type == (int)AssetType.Animation)
810 { 810 animID = inv.Value.AssetID;
811 if (inv.Value.Type == (int)AssetType.Animation) 811 continue;
812 animID = inv.Value.AssetID;
813 continue;
814 }
815 } 812 }
816 } 813 }
814 m_host.TaskInventory.LockItemsForRead(false);
817 815
818 if (animID == UUID.Zero) 816 if (animID == UUID.Zero)
819 target.Animator.RemoveAnimation(animation); 817 target.Animator.RemoveAnimation(animation);
@@ -1664,6 +1662,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1664 1662
1665 if (!UUID.TryParse(name, out assetID)) 1663 if (!UUID.TryParse(name, out assetID))
1666 { 1664 {
1665 m_host.TaskInventory.LockItemsForRead(true);
1667 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1666 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1668 { 1667 {
1669 if (item.Type == 7 && item.Name == name) 1668 if (item.Type == 7 && item.Name == name)
@@ -1671,6 +1670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1671 assetID = item.AssetID; 1670 assetID = item.AssetID;
1672 } 1671 }
1673 } 1672 }
1673 m_host.TaskInventory.LockItemsForRead(false);
1674 } 1674 }
1675 1675
1676 if (assetID == UUID.Zero) 1676 if (assetID == UUID.Zero)
@@ -1717,6 +1717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1717 1717
1718 if (!UUID.TryParse(name, out assetID)) 1718 if (!UUID.TryParse(name, out assetID))
1719 { 1719 {
1720 m_host.TaskInventory.LockItemsForRead(true);
1720 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1721 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1721 { 1722 {
1722 if (item.Type == 7 && item.Name == name) 1723 if (item.Type == 7 && item.Name == name)
@@ -1724,6 +1725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 assetID = item.AssetID; 1725 assetID = item.AssetID;
1725 } 1726 }
1726 } 1727 }
1728 m_host.TaskInventory.LockItemsForRead(false);
1727 } 1729 }
1728 1730
1729 if (assetID == UUID.Zero) 1731 if (assetID == UUID.Zero)
@@ -1774,6 +1776,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1776
1775 if (!UUID.TryParse(name, out assetID)) 1777 if (!UUID.TryParse(name, out assetID))
1776 { 1778 {
1779 m_host.TaskInventory.LockItemsForRead(true);
1777 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1780 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1778 { 1781 {
1779 if (item.Type == 7 && item.Name == name) 1782 if (item.Type == 7 && item.Name == name)
@@ -1781,6 +1784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1781 assetID = item.AssetID; 1784 assetID = item.AssetID;
1782 } 1785 }
1783 } 1786 }
1787 m_host.TaskInventory.LockItemsForRead(false);
1784 } 1788 }
1785 1789
1786 if (assetID == UUID.Zero) 1790 if (assetID == UUID.Zero)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c2abd5..a5b1124 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 309 // in mouselook.
310 310
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
312 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 313 q = avatar.Rotation;
313 } 314 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 423 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 424 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment)
427 {
428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook.
431
432 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
433 fromRegionPos = avatar.AbsolutePosition;
434 q = avatar.Rotation;
435 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 436 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 437 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 438 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 78ee43c..c8f3623 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
81 // Avatar Info Commands 81 // Avatar Info Commands
82 string osGetAgentIP(string agent); 82 string osGetAgentIP(string agent);
83 LSL_List osGetAgents(); 83 LSL_List osGetAgents();
84 84
85 // Teleport commands 85 // Teleport commands
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dba6502..96f6486 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -274,6 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
274 public const int CHANGED_ALLOWED_DROP = 64; 274 public const int CHANGED_ALLOWED_DROP = 64;
275 public const int CHANGED_OWNER = 128; 275 public const int CHANGED_OWNER = 128;
276 public const int CHANGED_REGION_RESTART = 256; 276 public const int CHANGED_REGION_RESTART = 256;
277 public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART
277 public const int CHANGED_REGION = 512; 278 public const int CHANGED_REGION = 512;
278 public const int CHANGED_TELEPORT = 1024; 279 public const int CHANGED_TELEPORT = 1024;
279 public const int CHANGED_ANIMATION = 16384; 280 public const int CHANGED_ANIMATION = 16384;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3339995..e86d08c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index f8dbe03..8280ca5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,5 +72,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
76 public LSL_List cmGetWindlightScene(LSL_List rules)
77 {
78 return m_LS_Functions.lsGetWindlightScene(rules);
79 }
80
81 public int cmSetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsSetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
87 {
88 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
89 }
75 } 90 }
76} 91}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 3dd381d..b348403 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -429,14 +429,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 429 {
430 int permsMask; 430 int permsMask;
431 UUID permsGranter; 431 UUID permsGranter;
432 lock (part.TaskInventory) 432 part.TaskInventory.LockItemsForRead(true);
433 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 434 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 435 part.TaskInventory.LockItemsForRead(false);
435 return; 436 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 437 }
438 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
439 permsMask = part.TaskInventory[m_ItemID].PermsMask;
440 part.TaskInventory.LockItemsForRead(false);
440 441
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 442 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 443 {
@@ -545,6 +546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 546 return true;
546 } 547 }
547 548
549 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 550 public void SetState(string state)
549 { 551 {
550 if (state == State) 552 if (state == State)
@@ -556,7 +558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 558 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 559 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 560 new DetectParams[0]));
559 561
560 throw new EventAbortException(); 562 throw new EventAbortException();
561 } 563 }
562 564
@@ -639,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 641 /// <returns></returns>
640 public object EventProcessor() 642 public object EventProcessor()
641 { 643 {
642 if (m_Suspended) 644 EventParams data = null;
643 return 0;
644 645
645 lock (m_Script) 646 lock (m_EventQueue)
646 { 647 {
647 EventParams data = null; 648 if (m_Suspended)
649 return 0;
648 650
649 lock (m_EventQueue) 651 lock (m_Script)
650 { 652 {
651 data = (EventParams) m_EventQueue.Dequeue(); 653 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 654 if (data == null) // Shouldn't happen
@@ -672,6 +674,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 674 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 675 m_CollisionInQueue = false;
674 } 676 }
677 }
678 lock(m_Script)
679 {
675 680
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 682
@@ -828,6 +833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 833 new Object[0], new DetectParams[0]));
829 } 834 }
830 835
836 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 837 public void ApiResetScript()
832 { 838 {
833 // bool running = Running; 839 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index b050349..916e27f 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -263,43 +331,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
263 331
264 public void RemoveRegion(Scene scene) 332 public void RemoveRegion(Scene scene)
265 { 333 {
266 lock (m_Scripts) 334 lockScriptsForRead(true);
335 foreach (IScriptInstance instance in m_Scripts.Values)
267 { 336 {
268 foreach (IScriptInstance instance in m_Scripts.Values) 337 // Force a final state save
338 //
339 if (m_Assemblies.ContainsKey(instance.AssetID))
269 { 340 {
270 // Force a final state save 341 string assembly = m_Assemblies[instance.AssetID];
271 // 342 instance.SaveState(assembly);
272 if (m_Assemblies.ContainsKey(instance.AssetID)) 343 }
273 {
274 string assembly = m_Assemblies[instance.AssetID];
275 instance.SaveState(assembly);
276 }
277 344
278 // Clear the event queue and abort the instance thread 345 // Clear the event queue and abort the instance thread
279 // 346 //
280 instance.ClearQueue(); 347 instance.ClearQueue();
281 instance.Stop(0); 348 instance.Stop(0);
282 349
283 // Release events, timer, etc 350 // Release events, timer, etc
284 // 351 //
285 instance.DestroyScriptInstance(); 352 instance.DestroyScriptInstance();
286 353
287 // Unload scripts and app domains 354 // Unload scripts and app domains
288 // Must be done explicitly because they have infinite 355 // Must be done explicitly because they have infinite
289 // lifetime 356 // lifetime
290 // 357 //
291 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 358 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
292 if (m_DomainScripts[instance.AppDomain].Count == 0) 359 if (m_DomainScripts[instance.AppDomain].Count == 0)
293 { 360 {
294 m_DomainScripts.Remove(instance.AppDomain); 361 m_DomainScripts.Remove(instance.AppDomain);
295 UnloadAppDomain(instance.AppDomain); 362 UnloadAppDomain(instance.AppDomain);
296 }
297 } 363 }
298 m_Scripts.Clear();
299 m_PrimObjects.Clear();
300 m_Assemblies.Clear();
301 m_DomainScripts.Clear();
302 } 364 }
365 lockScriptsForRead(false);
366 lockScriptsForWrite(true);
367 m_Scripts.Clear();
368 lockScriptsForWrite(false);
369 m_PrimObjects.Clear();
370 m_Assemblies.Clear();
371 m_DomainScripts.Clear();
372
303 lock (m_ScriptEngines) 373 lock (m_ScriptEngines)
304 { 374 {
305 m_ScriptEngines.Remove(this); 375 m_ScriptEngines.Remove(this);
@@ -358,22 +428,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
358 428
359 List<IScriptInstance> instances = new List<IScriptInstance>(); 429 List<IScriptInstance> instances = new List<IScriptInstance>();
360 430
361 lock (m_Scripts) 431 lockScriptsForRead(true);
362 { 432 foreach (IScriptInstance instance in m_Scripts.Values)
363 foreach (IScriptInstance instance in m_Scripts.Values)
364 instances.Add(instance); 433 instances.Add(instance);
365 } 434 lockScriptsForRead(false);
366 435
367 foreach (IScriptInstance i in instances) 436 foreach (IScriptInstance i in instances)
368 { 437 {
369 string assembly = String.Empty; 438 string assembly = String.Empty;
370 439
371 lock (m_Scripts) 440
372 {
373 if (!m_Assemblies.ContainsKey(i.AssetID)) 441 if (!m_Assemblies.ContainsKey(i.AssetID))
374 continue; 442 continue;
375 assembly = m_Assemblies[i.AssetID]; 443 assembly = m_Assemblies[i.AssetID];
376 } 444
377 445
378 i.SaveState(assembly); 446 i.SaveState(assembly);
379 } 447 }
@@ -702,92 +770,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 } 770 }
703 771
704 ScriptInstance instance = null; 772 ScriptInstance instance = null;
705 lock (m_Scripts) 773 // Create the object record
774 lockScriptsForRead(true);
775 if ((!m_Scripts.ContainsKey(itemID)) ||
776 (m_Scripts[itemID].AssetID != assetID))
706 { 777 {
707 // Create the object record 778 lockScriptsForRead(false);
708 779
709 if ((!m_Scripts.ContainsKey(itemID)) || 780 UUID appDomain = assetID;
710 (m_Scripts[itemID].AssetID != assetID))
711 {
712 UUID appDomain = assetID;
713 781
714 if (part.ParentGroup.IsAttachment) 782 if (part.ParentGroup.IsAttachment)
715 appDomain = part.ParentGroup.RootPart.UUID; 783 appDomain = part.ParentGroup.RootPart.UUID;
716 784
717 if (!m_AppDomains.ContainsKey(appDomain)) 785 if (!m_AppDomains.ContainsKey(appDomain))
786 {
787 try
718 { 788 {
719 try 789 AppDomainSetup appSetup = new AppDomainSetup();
720 { 790 // appSetup.ApplicationBase = Path.Combine(
721 AppDomainSetup appSetup = new AppDomainSetup(); 791 // "ScriptEngines",
722// appSetup.ApplicationBase = Path.Combine( 792 // m_Scene.RegionInfo.RegionID.ToString());
723// "ScriptEngines", 793
724// m_Scene.RegionInfo.RegionID.ToString()); 794 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
725 795 Evidence evidence = new Evidence(baseEvidence);
726 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 796
727 Evidence evidence = new Evidence(baseEvidence); 797 AppDomain sandbox;
728 798 if (m_AppDomainLoading)
729 AppDomain sandbox; 799 sandbox = AppDomain.CreateDomain(
730 if (m_AppDomainLoading) 800 m_Scene.RegionInfo.RegionID.ToString(),
731 sandbox = AppDomain.CreateDomain( 801 evidence, appSetup);
732 m_Scene.RegionInfo.RegionID.ToString(), 802 else
733 evidence, appSetup); 803 sandbox = AppDomain.CurrentDomain;
734 else 804
735 sandbox = AppDomain.CurrentDomain; 805 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
736 806 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
737 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 807 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
738 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 808 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
739 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 809 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
740 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 810 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
741 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 811 //sandbox.SetAppDomainPolicy(sandboxPolicy);
742 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 812
743 //sandbox.SetAppDomainPolicy(sandboxPolicy); 813 m_AppDomains[appDomain] = sandbox;
744 814
745 m_AppDomains[appDomain] = sandbox; 815 m_AppDomains[appDomain].AssemblyResolve +=
746 816 new ResolveEventHandler(
747 m_AppDomains[appDomain].AssemblyResolve += 817 AssemblyResolver.OnAssemblyResolve);
748 new ResolveEventHandler( 818 m_DomainScripts[appDomain] = new List<UUID>();
749 AssemblyResolver.OnAssemblyResolve); 819 }
750 m_DomainScripts[appDomain] = new List<UUID>(); 820 catch (Exception e)
751 } 821 {
752 catch (Exception e) 822 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
823 m_ScriptErrorMessage += "Exception creating app domain:\n";
824 m_ScriptFailCount++;
825 lock (m_AddingAssemblies)
753 { 826 {
754 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 827 m_AddingAssemblies[assembly]--;
755 m_ScriptErrorMessage += "Exception creating app domain:\n";
756 m_ScriptFailCount++;
757 lock (m_AddingAssemblies)
758 {
759 m_AddingAssemblies[assembly]--;
760 }
761 return false;
762 } 828 }
829 return false;
763 } 830 }
764 m_DomainScripts[appDomain].Add(itemID); 831 }
765 832 m_DomainScripts[appDomain].Add(itemID);
766 instance = new ScriptInstance(this, part, 833
767 itemID, assetID, assembly, 834 instance = new ScriptInstance(this, part,
768 m_AppDomains[appDomain], 835 itemID, assetID, assembly,
769 part.ParentGroup.RootPart.Name, 836 m_AppDomains[appDomain],
770 item.Name, startParam, postOnRez, 837 part.ParentGroup.RootPart.Name,
771 stateSource, m_MaxScriptQueue); 838 item.Name, startParam, postOnRez,
772 839 stateSource, m_MaxScriptQueue);
773 m_log.DebugFormat( 840
841 m_log.DebugFormat(
774 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 842 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
775 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 843 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
776 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 844 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
777 845
778 if (presence != null) 846 if (presence != null)
779 { 847 {
780 ShowScriptSaveResponse(item.OwnerID, 848 ShowScriptSaveResponse(item.OwnerID,
781 assetID, "Compile successful", true); 849 assetID, "Compile successful", true);
782 }
783
784 instance.AppDomain = appDomain;
785 instance.LineMap = linemap;
786
787 m_Scripts[itemID] = instance;
788 } 850 }
789 }
790 851
852 instance.AppDomain = appDomain;
853 instance.LineMap = linemap;
854 lockScriptsForWrite(true);
855 m_Scripts[itemID] = instance;
856 lockScriptsForWrite(false);
857 }
858 else
859 {
860 lockScriptsForRead(false);
861 }
791 lock (m_PrimObjects) 862 lock (m_PrimObjects)
792 { 863 {
793 if (!m_PrimObjects.ContainsKey(localID)) 864 if (!m_PrimObjects.ContainsKey(localID))
@@ -806,9 +877,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
806 m_AddingAssemblies[assembly]--; 877 m_AddingAssemblies[assembly]--;
807 } 878 }
808 879
809 if (instance != null) 880 if (instance!=null)
810 instance.Init(); 881 instance.Init();
811 882
812 return true; 883 return true;
813 } 884 }
814 885
@@ -821,20 +892,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
821 m_CompileDict.Remove(itemID); 892 m_CompileDict.Remove(itemID);
822 } 893 }
823 894
824 IScriptInstance instance = null; 895 lockScriptsForRead(true);
825 896 // Do we even have it?
826 lock (m_Scripts) 897 if (!m_Scripts.ContainsKey(itemID))
827 { 898 {
828 // Do we even have it? 899 lockScriptsForRead(false);
829 if (!m_Scripts.ContainsKey(itemID)) 900 return;
830 return;
831
832 instance=m_Scripts[itemID];
833 m_Scripts.Remove(itemID);
834 } 901 }
902
835 903
904 IScriptInstance instance=m_Scripts[itemID];
905 lockScriptsForRead(false);
906 lockScriptsForWrite(true);
907 m_Scripts.Remove(itemID);
908 lockScriptsForWrite(false);
836 instance.ClearQueue(); 909 instance.ClearQueue();
837 instance.Stop(0); 910 instance.Stop(0);
911
838// bool objectRemoved = false; 912// bool objectRemoved = false;
839 913
840 lock (m_PrimObjects) 914 lock (m_PrimObjects)
@@ -870,11 +944,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
870 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 944 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
871 if (handlerObjectRemoved != null) 945 if (handlerObjectRemoved != null)
872 { 946 {
873 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 947 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
874 handlerObjectRemoved(part.UUID); 948 handlerObjectRemoved(part.UUID);
875 } 949 }
876 950
877 951 CleanAssemblies();
952
878 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 953 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
879 if (handlerScriptRemoved != null) 954 if (handlerScriptRemoved != null)
880 handlerScriptRemoved(itemID); 955 handlerScriptRemoved(itemID);
@@ -1133,12 +1208,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 private IScriptInstance GetInstance(UUID itemID) 1208 private IScriptInstance GetInstance(UUID itemID)
1134 { 1209 {
1135 IScriptInstance instance; 1210 IScriptInstance instance;
1136 lock (m_Scripts) 1211 lockScriptsForRead(true);
1212 if (!m_Scripts.ContainsKey(itemID))
1137 { 1213 {
1138 if (!m_Scripts.ContainsKey(itemID)) 1214 lockScriptsForRead(false);
1139 return null; 1215 return null;
1140 instance = m_Scripts[itemID];
1141 } 1216 }
1217 instance = m_Scripts[itemID];
1218 lockScriptsForRead(false);
1142 return instance; 1219 return instance;
1143 } 1220 }
1144 1221
@@ -1162,6 +1239,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1162 return false; 1239 return false;
1163 } 1240 }
1164 1241
1242 [DebuggerNonUserCode]
1165 public void ApiResetScript(UUID itemID) 1243 public void ApiResetScript(UUID itemID)
1166 { 1244 {
1167 IScriptInstance instance = GetInstance(itemID); 1245 IScriptInstance instance = GetInstance(itemID);
@@ -1213,6 +1291,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return UUID.Zero; 1291 return UUID.Zero;
1214 } 1292 }
1215 1293
1294 [DebuggerNonUserCode]
1216 public void SetState(UUID itemID, string newState) 1295 public void SetState(UUID itemID, string newState)
1217 { 1296 {
1218 IScriptInstance instance = GetInstance(itemID); 1297 IScriptInstance instance = GetInstance(itemID);
@@ -1233,11 +1312,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1233 { 1312 {
1234 List<IScriptInstance> instances = new List<IScriptInstance>(); 1313 List<IScriptInstance> instances = new List<IScriptInstance>();
1235 1314
1236 lock (m_Scripts) 1315 lockScriptsForRead(true);
1237 { 1316 foreach (IScriptInstance instance in m_Scripts.Values)
1238 foreach (IScriptInstance instance in m_Scripts.Values)
1239 instances.Add(instance); 1317 instances.Add(instance);
1240 } 1318 lockScriptsForRead(false);
1241 1319
1242 foreach (IScriptInstance i in instances) 1320 foreach (IScriptInstance i in instances)
1243 { 1321 {