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.cs1728
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs42
-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_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
14 files changed, 1441 insertions, 826 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 32e46ec..a711ebf 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;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -161,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 162 get { return m_ScriptEngine.World; }
162 } 163 }
163 164
165 [DebuggerNonUserCode]
164 public void state(string newState) 166 public void state(string newState)
165 { 167 {
166 m_ScriptEngine.SetState(m_itemID, newState); 168 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 172 /// Reset the named script. The script must be present
171 /// in the same prim. 173 /// in the same prim.
172 /// </summary> 174 /// </summary>
175 [DebuggerNonUserCode]
173 public void llResetScript() 176 public void llResetScript()
174 { 177 {
175 m_host.AddScriptLPS(1); 178 m_host.AddScriptLPS(1);
@@ -226,9 +229,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 229 }
227 } 230 }
228 231
232 public List<ScenePresence> GetLinkAvatars(int linkType)
233 {
234 List<ScenePresence> ret = new List<ScenePresence>();
235 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
236 return ret;
237
238 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
239
240 switch (linkType)
241 {
242 case ScriptBaseClass.LINK_SET:
243 return avs;
244
245 case ScriptBaseClass.LINK_ROOT:
246 return ret;
247
248 case ScriptBaseClass.LINK_ALL_OTHERS:
249 return avs;
250
251 case ScriptBaseClass.LINK_ALL_CHILDREN:
252 return avs;
253
254 case ScriptBaseClass.LINK_THIS:
255 return ret;
256
257 default:
258 if (linkType < 0)
259 return ret;
260
261 int partCount = m_host.ParentGroup.GetPartCount();
262
263 if (linkType <= partCount)
264 {
265 return ret;
266 }
267 else
268 {
269 linkType = linkType - partCount;
270 if (linkType > avs.Count)
271 {
272 return ret;
273 }
274 else
275 {
276 ret.Add(avs[linkType-1]);
277 return ret;
278 }
279 }
280 }
281 }
282
229 public List<SceneObjectPart> GetLinkParts(int linkType) 283 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 284 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 285 List<SceneObjectPart> ret = new List<SceneObjectPart>();
286 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
287 return ret;
232 ret.Add(m_host); 288 ret.Add(m_host);
233 289
234 switch (linkType) 290 switch (linkType)
@@ -282,40 +338,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 protected UUID InventorySelf() 338 protected UUID InventorySelf()
283 { 339 {
284 UUID invItemID = new UUID(); 340 UUID invItemID = new UUID();
285 341 bool unlock = false;
286 lock (m_host.TaskInventory) 342 if (!m_host.TaskInventory.IsReadLockedByMe())
343 {
344 m_host.TaskInventory.LockItemsForRead(true);
345 unlock = true;
346 }
347 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
287 { 348 {
288 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 349 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
289 { 350 {
290 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 351 invItemID = inv.Key;
291 { 352 break;
292 invItemID = inv.Key;
293 break;
294 }
295 } 353 }
296 } 354 }
297 355 if (unlock)
356 {
357 m_host.TaskInventory.LockItemsForRead(false);
358 }
298 return invItemID; 359 return invItemID;
299 } 360 }
300 361
301 protected UUID InventoryKey(string name, int type) 362 protected UUID InventoryKey(string name, int type)
302 { 363 {
303 m_host.AddScriptLPS(1); 364 m_host.AddScriptLPS(1);
304 365 m_host.TaskInventory.LockItemsForRead(true);
305 lock (m_host.TaskInventory) 366
367 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
306 { 368 {
307 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 369 if (inv.Value.Name == name)
308 { 370 {
309 if (inv.Value.Name == name) 371 m_host.TaskInventory.LockItemsForRead(false);
372
373 if (inv.Value.Type != type)
310 { 374 {
311 if (inv.Value.Type != type) 375 return UUID.Zero;
312 return UUID.Zero;
313
314 return inv.Value.AssetID;
315 } 376 }
377
378 return inv.Value.AssetID;
316 } 379 }
317 } 380 }
318 381
382 m_host.TaskInventory.LockItemsForRead(false);
319 return UUID.Zero; 383 return UUID.Zero;
320 } 384 }
321 385
@@ -323,17 +387,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
323 { 387 {
324 m_host.AddScriptLPS(1); 388 m_host.AddScriptLPS(1);
325 389
326 lock (m_host.TaskInventory) 390
391 m_host.TaskInventory.LockItemsForRead(true);
392
393 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
327 { 394 {
328 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 395 if (inv.Value.Name == name)
329 { 396 {
330 if (inv.Value.Name == name) 397 m_host.TaskInventory.LockItemsForRead(false);
331 { 398 return inv.Value.AssetID;
332 return inv.Value.AssetID;
333 }
334 } 399 }
335 } 400 }
336 401
402 m_host.TaskInventory.LockItemsForRead(false);
403
404
337 return UUID.Zero; 405 return UUID.Zero;
338 } 406 }
339 407
@@ -475,26 +543,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
475 543
476 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 544 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
477 545
478 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 546 // Utility function for llRot2Euler
479 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
480 547
481 public LSL_Vector llRot2Euler(LSL_Rotation r) 548 // normalize an angle between -PI and PI (-180 to +180 degrees)
549 protected double NormalizeAngle(double angle)
550 {
551 if (angle > -Math.PI && angle < Math.PI)
552 return angle;
553
554 int numPis = (int)(Math.PI / angle);
555 double remainder = angle - Math.PI * numPis;
556 if (numPis % 2 == 1)
557 return Math.PI - angle;
558 return remainder;
559 }
560
561 public LSL_Vector llRot2Euler(LSL_Rotation q1)
482 { 562 {
483 m_host.AddScriptLPS(1); 563 m_host.AddScriptLPS(1);
484 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 564 LSL_Vector eul = new LSL_Vector();
485 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 565
486 double m = (t.x + t.y + t.z + t.s); 566 double sqw = q1.s*q1.s;
487 if (m == 0) return new LSL_Vector(); 567 double sqx = q1.x*q1.x;
488 double n = 2 * (r.y * r.s + r.x * r.z); 568 double sqy = q1.z*q1.z;
489 double p = m * m - n * n; 569 double sqz = q1.y*q1.y;
490 if (p > 0) 570 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
491 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 571 double test = q1.x*q1.z + q1.y*q1.s;
492 Math.Atan2(n, Math.Sqrt(p)), 572 if (test > 0.4999*unit) { // singularity at north pole
493 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 573 eul.z = 2 * Math.Atan2(q1.x,q1.s);
494 else if (n > 0) 574 eul.y = Math.PI/2;
495 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)); 575 eul.x = 0;
496 else 576 return eul;
497 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)); 577 }
578 if (test < -0.4999*unit) { // singularity at south pole
579 eul.z = -2 * Math.Atan2(q1.x,q1.s);
580 eul.y = -Math.PI/2;
581 eul.x = 0;
582 return eul;
583 }
584 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
585 eul.y = Math.Asin(2*test/unit);
586 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
587 return eul;
498 } 588 }
499 589
500 /* From wiki: 590 /* From wiki:
@@ -696,77 +786,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
696 { 786 {
697 //A and B should both be normalized 787 //A and B should both be normalized
698 m_host.AddScriptLPS(1); 788 m_host.AddScriptLPS(1);
699 LSL_Rotation rotBetween; 789 /* This method is more accurate than the SL one, and thus causes problems
700 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 790 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
701 // continue calculation. 791
702 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 792 double dotProduct = LSL_Vector.Dot(a, b);
793 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
794 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
795 double angle = Math.Acos(dotProduct / magProduct);
796 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
797 double s = Math.Sin(angle / 2);
798
799 double x = axis.x * s;
800 double y = axis.y * s;
801 double z = axis.z * s;
802 double w = Math.Cos(angle / 2);
803
804 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
805 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
806
807 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
808 */
809
810 // This method mimics the 180 errors found in SL
811 // See www.euclideanspace.com... angleBetween
812 LSL_Vector vec_a = a;
813 LSL_Vector vec_b = b;
814
815 // Eliminate zero length
816 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
817 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
818 if (vec_a_mag < 0.00001 ||
819 vec_b_mag < 0.00001)
703 { 820 {
704 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 821 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
705 } 822 }
706 else 823
824 // Normalize
825 vec_a = llVecNorm(vec_a);
826 vec_b = llVecNorm(vec_b);
827
828 // Calculate axis and rotation angle
829 LSL_Vector axis = vec_a % vec_b;
830 LSL_Float cos_theta = vec_a * vec_b;
831
832 // Check if parallel
833 if (cos_theta > 0.99999)
707 { 834 {
708 a = LSL_Vector.Norm(a); 835 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
709 b = LSL_Vector.Norm(b); 836 }
710 double dotProduct = LSL_Vector.Dot(a, b); 837
711 // There are two degenerate cases possible. These are for vectors 180 or 838 // Check if anti-parallel
712 // 0 degrees apart. These have to be detected and handled individually. 839 else if (cos_theta < -0.99999)
713 // 840 {
714 // Check for vectors 180 degrees apart. 841 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
715 // A dot product of -1 would mean the angle between vectors is 180 degrees. 842 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
716 if (dotProduct < -0.9999999f) 843 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
717 { 844 }
718 // First assume X axis is orthogonal to the vectors. 845 else // other rotation
719 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 846 {
720 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 847 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
721 // Check for near zero vector. A very small non-zero number here will create 848 axis = llVecNorm(axis);
722 // a rotation in an undesired direction. 849 double x, y, z, s, t;
723 if (LSL_Vector.Mag(orthoVector) > 0.0001) 850 s = Math.Cos(theta);
724 { 851 t = Math.Sin(theta);
725 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 852 x = axis.x * t;
726 } 853 y = axis.y * t;
727 // If the magnitude of the vector was near zero, then assume the X axis is not 854 z = axis.z * t;
728 // orthogonal and use the Z axis instead. 855 return new LSL_Rotation(x,y,z,s);
729 else
730 {
731 // Set 180 z rotation.
732 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
733 }
734 }
735 // Check for parallel vectors.
736 // A dot product of 1 would mean the angle between vectors is 0 degrees.
737 else if (dotProduct > 0.9999999f)
738 {
739 // Set zero rotation.
740 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
741 }
742 else
743 {
744 // All special checks have been performed so get the axis of rotation.
745 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
746 // Quarternion s value is the length of the unit vector + dot product.
747 double qs = 1.0 + dotProduct;
748 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
749 // Normalize the rotation.
750 double mag = LSL_Rotation.Mag(rotBetween);
751 // We shouldn't have to worry about a divide by zero here. The qs value will be
752 // non-zero because we already know if we're here, then the dotProduct is not -1 so
753 // qs will not be zero. Also, we've already handled the input vectors being zero so the
754 // crossProduct vector should also not be zero.
755 rotBetween.x = rotBetween.x / mag;
756 rotBetween.y = rotBetween.y / mag;
757 rotBetween.z = rotBetween.z / mag;
758 rotBetween.s = rotBetween.s / mag;
759 // Check for undefined values and set zero rotation if any found. This code might not actually be required
760 // any longer since zero vectors are checked for at the top.
761 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
762 {
763 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
764 }
765 }
766 } 856 }
767 return rotBetween;
768 } 857 }
769 858
770 public void llWhisper(int channelID, string text) 859 public void llWhisper(int channelID, string text)
771 { 860 {
772 m_host.AddScriptLPS(1); 861 m_host.AddScriptLPS(1);
@@ -1090,10 +1179,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1090 return detectedParams.TouchUV; 1179 return detectedParams.TouchUV;
1091 } 1180 }
1092 1181
1182 [DebuggerNonUserCode]
1093 public virtual void llDie() 1183 public virtual void llDie()
1094 { 1184 {
1095 m_host.AddScriptLPS(1); 1185 m_host.AddScriptLPS(1);
1096 throw new SelfDeleteException(); 1186 if (!m_host.IsAttachment) throw new SelfDeleteException();
1097 } 1187 }
1098 1188
1099 public LSL_Float llGround(LSL_Vector offset) 1189 public LSL_Float llGround(LSL_Vector offset)
@@ -1166,6 +1256,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1166 1256
1167 public void llSetStatus(int status, int value) 1257 public void llSetStatus(int status, int value)
1168 { 1258 {
1259 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1260 return;
1169 m_host.AddScriptLPS(1); 1261 m_host.AddScriptLPS(1);
1170 1262
1171 int statusrotationaxis = 0; 1263 int statusrotationaxis = 0;
@@ -1395,6 +1487,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1395 { 1487 {
1396 m_host.AddScriptLPS(1); 1488 m_host.AddScriptLPS(1);
1397 1489
1490 SetColor(m_host, color, face);
1491 }
1492
1493 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1494 {
1495 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1496 return;
1497
1498 Primitive.TextureEntry tex = part.Shape.Textures;
1499 Color4 texcolor;
1500 if (face >= 0 && face < GetNumberOfSides(part))
1501 {
1502 texcolor = tex.CreateFace((uint)face).RGBA;
1503 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1504 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1505 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1506 tex.FaceTextures[face].RGBA = texcolor;
1507 part.UpdateTexture(tex);
1508 return;
1509 }
1510 else if (face == ScriptBaseClass.ALL_SIDES)
1511 {
1512 for (uint i = 0; i < GetNumberOfSides(part); i++)
1513 {
1514 if (tex.FaceTextures[i] != null)
1515 {
1516 texcolor = tex.FaceTextures[i].RGBA;
1517 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1518 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1519 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1520 tex.FaceTextures[i].RGBA = texcolor;
1521 }
1522 texcolor = tex.DefaultTexture.RGBA;
1523 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1524 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1525 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1526 tex.DefaultTexture.RGBA = texcolor;
1527 }
1528 part.UpdateTexture(tex);
1529 return;
1530 }
1531
1398 if (face == ScriptBaseClass.ALL_SIDES) 1532 if (face == ScriptBaseClass.ALL_SIDES)
1399 face = SceneObjectPart.ALL_SIDES; 1533 face = SceneObjectPart.ALL_SIDES;
1400 1534
@@ -1403,6 +1537,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1403 1537
1404 public void SetTexGen(SceneObjectPart part, int face,int style) 1538 public void SetTexGen(SceneObjectPart part, int face,int style)
1405 { 1539 {
1540 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1541 return;
1542
1406 Primitive.TextureEntry tex = part.Shape.Textures; 1543 Primitive.TextureEntry tex = part.Shape.Textures;
1407 MappingType textype; 1544 MappingType textype;
1408 textype = MappingType.Default; 1545 textype = MappingType.Default;
@@ -1433,6 +1570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1433 1570
1434 public void SetGlow(SceneObjectPart part, int face, float glow) 1571 public void SetGlow(SceneObjectPart part, int face, float glow)
1435 { 1572 {
1573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1574 return;
1575
1436 Primitive.TextureEntry tex = part.Shape.Textures; 1576 Primitive.TextureEntry tex = part.Shape.Textures;
1437 if (face >= 0 && face < GetNumberOfSides(part)) 1577 if (face >= 0 && face < GetNumberOfSides(part))
1438 { 1578 {
@@ -1458,6 +1598,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1458 1598
1459 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1599 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1460 { 1600 {
1601 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1602 return;
1461 1603
1462 Shininess sval = new Shininess(); 1604 Shininess sval = new Shininess();
1463 1605
@@ -1508,6 +1650,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1508 1650
1509 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1651 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1510 { 1652 {
1653 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1654 return;
1655
1511 Primitive.TextureEntry tex = part.Shape.Textures; 1656 Primitive.TextureEntry tex = part.Shape.Textures;
1512 if (face >= 0 && face < GetNumberOfSides(part)) 1657 if (face >= 0 && face < GetNumberOfSides(part))
1513 { 1658 {
@@ -1568,13 +1713,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1568 m_host.AddScriptLPS(1); 1713 m_host.AddScriptLPS(1);
1569 1714
1570 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1715 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1571 1716 if (parts.Count > 0)
1572 foreach (SceneObjectPart part in parts) 1717 {
1573 SetAlpha(part, alpha, face); 1718 try
1719 {
1720 parts[0].ParentGroup.areUpdatesSuspended = true;
1721 foreach (SceneObjectPart part in parts)
1722 SetAlpha(part, alpha, face);
1723 }
1724 finally
1725 {
1726 parts[0].ParentGroup.areUpdatesSuspended = false;
1727 }
1728 }
1574 } 1729 }
1575 1730
1576 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1731 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1577 { 1732 {
1733 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1734 return;
1735
1578 Primitive.TextureEntry tex = part.Shape.Textures; 1736 Primitive.TextureEntry tex = part.Shape.Textures;
1579 Color4 texcolor; 1737 Color4 texcolor;
1580 if (face >= 0 && face < GetNumberOfSides(part)) 1738 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1620,7 +1778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1620 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1778 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1621 float wind, float tension, LSL_Vector Force) 1779 float wind, float tension, LSL_Vector Force)
1622 { 1780 {
1623 if (part == null) 1781 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1624 return; 1782 return;
1625 1783
1626 if (flexi) 1784 if (flexi)
@@ -1655,7 +1813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1655 /// <param name="falloff"></param> 1813 /// <param name="falloff"></param>
1656 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1814 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1657 { 1815 {
1658 if (part == null) 1816 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1659 return; 1817 return;
1660 1818
1661 if (light) 1819 if (light)
@@ -1732,15 +1890,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1732 m_host.AddScriptLPS(1); 1890 m_host.AddScriptLPS(1);
1733 1891
1734 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1892 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1735 1893 if (parts.Count > 0)
1736 foreach (SceneObjectPart part in parts) 1894 {
1737 SetTexture(part, texture, face); 1895 try
1738 1896 {
1897 parts[0].ParentGroup.areUpdatesSuspended = true;
1898 foreach (SceneObjectPart part in parts)
1899 SetTexture(part, texture, face);
1900 }
1901 finally
1902 {
1903 parts[0].ParentGroup.areUpdatesSuspended = false;
1904 }
1905 }
1739 ScriptSleep(200); 1906 ScriptSleep(200);
1740 } 1907 }
1741 1908
1742 protected void SetTexture(SceneObjectPart part, string texture, int face) 1909 protected void SetTexture(SceneObjectPart part, string texture, int face)
1743 { 1910 {
1911 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1912 return;
1913
1744 UUID textureID=new UUID(); 1914 UUID textureID=new UUID();
1745 1915
1746 if (!UUID.TryParse(texture, out textureID)) 1916 if (!UUID.TryParse(texture, out textureID))
@@ -1786,6 +1956,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 1956
1787 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1957 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1788 { 1958 {
1959 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1960 return;
1961
1789 Primitive.TextureEntry tex = part.Shape.Textures; 1962 Primitive.TextureEntry tex = part.Shape.Textures;
1790 if (face >= 0 && face < GetNumberOfSides(part)) 1963 if (face >= 0 && face < GetNumberOfSides(part))
1791 { 1964 {
@@ -1822,6 +1995,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1822 1995
1823 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1996 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1824 { 1997 {
1998 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1999 return;
2000
1825 Primitive.TextureEntry tex = part.Shape.Textures; 2001 Primitive.TextureEntry tex = part.Shape.Textures;
1826 if (face >= 0 && face < GetNumberOfSides(part)) 2002 if (face >= 0 && face < GetNumberOfSides(part))
1827 { 2003 {
@@ -1858,6 +2034,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1858 2034
1859 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2035 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1860 { 2036 {
2037 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2038 return;
2039
1861 Primitive.TextureEntry tex = part.Shape.Textures; 2040 Primitive.TextureEntry tex = part.Shape.Textures;
1862 if (face >= 0 && face < GetNumberOfSides(part)) 2041 if (face >= 0 && face < GetNumberOfSides(part))
1863 { 2042 {
@@ -1928,6 +2107,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1928 2107
1929 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2108 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1930 { 2109 {
2110 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2111 return;
2112
1931 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2113 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1932 LSL_Vector currentPos = GetPartLocalPos(part); 2114 LSL_Vector currentPos = GetPartLocalPos(part);
1933 2115
@@ -1944,7 +2126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 } 2126 }
1945 else 2127 else
1946 { 2128 {
1947 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2129 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1948 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2130 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1949 SceneObjectGroup parent = part.ParentGroup; 2131 SceneObjectGroup parent = part.ParentGroup;
1950 parent.HasGroupChanged = true; 2132 parent.HasGroupChanged = true;
@@ -2018,6 +2200,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2200
2019 protected void SetRot(SceneObjectPart part, Quaternion rot) 2201 protected void SetRot(SceneObjectPart part, Quaternion rot)
2020 { 2202 {
2203 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2204 return;
2205
2021 part.UpdateRotation(rot); 2206 part.UpdateRotation(rot);
2022 // 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.
2023 2208
@@ -2637,12 +2822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2637 2822
2638 m_host.AddScriptLPS(1); 2823 m_host.AddScriptLPS(1);
2639 2824
2825 m_host.TaskInventory.LockItemsForRead(true);
2640 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2826 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2641 2827 m_host.TaskInventory.LockItemsForRead(false);
2642 lock (m_host.TaskInventory)
2643 {
2644 item = m_host.TaskInventory[invItemID];
2645 }
2646 2828
2647 if (item.PermsGranter == UUID.Zero) 2829 if (item.PermsGranter == UUID.Zero)
2648 return 0; 2830 return 0;
@@ -2717,6 +2899,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2717 if (dist > m_ScriptDistanceFactor * 10.0f) 2899 if (dist > m_ScriptDistanceFactor * 10.0f)
2718 return; 2900 return;
2719 2901
2902 //Clone is thread-safe
2720 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2903 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2721 2904
2722 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2905 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2779,6 +2962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2779 2962
2780 public void llLookAt(LSL_Vector target, double strength, double damping) 2963 public void llLookAt(LSL_Vector target, double strength, double damping)
2781 { 2964 {
2965 /*
2782 m_host.AddScriptLPS(1); 2966 m_host.AddScriptLPS(1);
2783 // Determine where we are looking from 2967 // Determine where we are looking from
2784 LSL_Vector from = llGetPos(); 2968 LSL_Vector from = llGetPos();
@@ -2798,10 +2982,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2798 // the angles of rotation in radians into rotation value 2982 // the angles of rotation in radians into rotation value
2799 2983
2800 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2984 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2801 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2985
2802 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
2803 // Orient the object to the angle calculated 2990 // Orient the object to the angle calculated
2804 //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
2805 } 3010 }
2806 3011
2807 public void llStopLookAt() 3012 public void llStopLookAt()
@@ -2850,13 +3055,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2850 { 3055 {
2851 TaskInventoryItem item; 3056 TaskInventoryItem item;
2852 3057
2853 lock (m_host.TaskInventory) 3058 m_host.TaskInventory.LockItemsForRead(true);
3059 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2854 { 3060 {
2855 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3061 m_host.TaskInventory.LockItemsForRead(false);
2856 return; 3062 return;
2857 else
2858 item = m_host.TaskInventory[InventorySelf()];
2859 } 3063 }
3064 else
3065 {
3066 item = m_host.TaskInventory[InventorySelf()];
3067 }
3068 m_host.TaskInventory.LockItemsForRead(false);
2860 3069
2861 if (item.PermsGranter != UUID.Zero) 3070 if (item.PermsGranter != UUID.Zero)
2862 { 3071 {
@@ -2878,13 +3087,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 { 3087 {
2879 TaskInventoryItem item; 3088 TaskInventoryItem item;
2880 3089
3090 m_host.TaskInventory.LockItemsForRead(true);
2881 lock (m_host.TaskInventory) 3091 lock (m_host.TaskInventory)
2882 { 3092 {
3093
2883 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3094 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3095 {
3096 m_host.TaskInventory.LockItemsForRead(false);
2884 return; 3097 return;
3098 }
2885 else 3099 else
3100 {
2886 item = m_host.TaskInventory[InventorySelf()]; 3101 item = m_host.TaskInventory[InventorySelf()];
3102 }
2887 } 3103 }
3104 m_host.TaskInventory.LockItemsForRead(false);
2888 3105
2889 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
2890 3107
@@ -2916,19 +3133,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3133 {
2917 m_host.AddScriptLPS(1); 3134 m_host.AddScriptLPS(1);
2918 3135
2919 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2920 return;
2921
2922 TaskInventoryItem item; 3136 TaskInventoryItem item;
2923 3137
2924 lock (m_host.TaskInventory) 3138 m_host.TaskInventory.LockItemsForRead(true);
3139
3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2925 { 3141 {
2926 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3142 m_host.TaskInventory.LockItemsForRead(false);
2927 return; 3143 return;
2928 else 3144 }
2929 item = m_host.TaskInventory[InventorySelf()]; 3145 else
3146 {
3147 item = m_host.TaskInventory[InventorySelf()];
2930 } 3148 }
2931 3149
3150 m_host.TaskInventory.LockItemsForRead(false);
3151
2932 if (item.PermsGranter != m_host.OwnerID) 3152 if (item.PermsGranter != m_host.OwnerID)
2933 return; 3153 return;
2934 3154
@@ -2938,10 +3158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 3158
2939 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3159 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2940 3160
2941 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3161 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2942 if (attachmentsModule != null)
2943 attachmentsModule.AttachObject(presence.ControllingClient,
2944 grp, (uint)attachment, false);
2945 } 3162 }
2946 } 3163 }
2947 3164
@@ -2954,13 +3171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3171
2955 TaskInventoryItem item; 3172 TaskInventoryItem item;
2956 3173
2957 lock (m_host.TaskInventory) 3174 m_host.TaskInventory.LockItemsForRead(true);
3175
3176 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2958 { 3177 {
2959 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3178 m_host.TaskInventory.LockItemsForRead(false);
2960 return; 3179 return;
2961 else 3180 }
2962 item = m_host.TaskInventory[InventorySelf()]; 3181 else
3182 {
3183 item = m_host.TaskInventory[InventorySelf()];
2963 } 3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
3186
2964 3187
2965 if (item.PermsGranter != m_host.OwnerID) 3188 if (item.PermsGranter != m_host.OwnerID)
2966 return; 3189 return;
@@ -2997,8 +3220,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 return m_host.OwnerID.ToString(); 3220 return m_host.OwnerID.ToString();
2998 } 3221 }
2999 3222
3223 [DebuggerNonUserCode]
3000 public void llInstantMessage(string user, string message) 3224 public void llInstantMessage(string user, string message)
3001 { 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
3002 m_host.AddScriptLPS(1); 3234 m_host.AddScriptLPS(1);
3003 3235
3004 // 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.
@@ -3013,14 +3245,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 UUID friendTransactionID = UUID.Random(); 3245 UUID friendTransactionID = UUID.Random();
3014 3246
3015 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3247 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3016 3248
3017 GridInstantMessage msg = new GridInstantMessage(); 3249 GridInstantMessage msg = new GridInstantMessage();
3018 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3250 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3019 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3251 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3020 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
3021// 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);
3022// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3254// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3023 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
3024 //if (client != null) 3276 //if (client != null)
3025 //{ 3277 //{
3026 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3278 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3034,13 +3286,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3034 msg.message = message.Substring(0, 1024); 3286 msg.message = message.Substring(0, 1024);
3035 else 3287 else
3036 msg.message = message; 3288 msg.message = message;
3037 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3289 msg.dialog = (byte)19; // MessageFromObject
3038 msg.fromGroup = false;// fromGroup; 3290 msg.fromGroup = false;// fromGroup;
3039 msg.offline = (byte)0; //offline; 3291 msg.offline = (byte)0; //offline;
3040 msg.ParentEstateID = 0; //ParentEstateID; 3292 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3041 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3293 msg.Position = new Vector3(m_host.AbsolutePosition);
3042 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3294 msg.RegionID = World.RegionInfo.RegionID.Guid;
3043 msg.binaryBucket = new byte[0];// binaryBucket; 3295 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3044 3296
3045 if (m_TransferModule != null) 3297 if (m_TransferModule != null)
3046 { 3298 {
@@ -3060,7 +3312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3060 } 3312 }
3061 3313
3062 emailModule.SendEmail(m_host.UUID, address, subject, message); 3314 emailModule.SendEmail(m_host.UUID, address, subject, message);
3063 ScriptSleep(20000); 3315 ScriptSleep(15000);
3064 } 3316 }
3065 3317
3066 public void llGetNextEmail(string address, string subject) 3318 public void llGetNextEmail(string address, string subject)
@@ -3162,13 +3414,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3162 m_host.AddScriptLPS(1); 3414 m_host.AddScriptLPS(1);
3163 } 3415 }
3164 3416
3165 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3166 {
3167 m_host.AddScriptLPS(1);
3168 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3169 m_host.RotLookAt(rot, (float)strength, (float)damping);
3170 }
3171
3172 public LSL_Integer llStringLength(string str) 3417 public LSL_Integer llStringLength(string str)
3173 { 3418 {
3174 m_host.AddScriptLPS(1); 3419 m_host.AddScriptLPS(1);
@@ -3192,14 +3437,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 3437
3193 TaskInventoryItem item; 3438 TaskInventoryItem item;
3194 3439
3195 lock (m_host.TaskInventory) 3440 m_host.TaskInventory.LockItemsForRead(true);
3441 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3196 { 3442 {
3197 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3443 m_host.TaskInventory.LockItemsForRead(false);
3198 return; 3444 return;
3199 else
3200 item = m_host.TaskInventory[InventorySelf()];
3201 } 3445 }
3202 3446 else
3447 {
3448 item = m_host.TaskInventory[InventorySelf()];
3449 }
3450 m_host.TaskInventory.LockItemsForRead(false);
3203 if (item.PermsGranter == UUID.Zero) 3451 if (item.PermsGranter == UUID.Zero)
3204 return; 3452 return;
3205 3453
@@ -3229,13 +3477,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3229 3477
3230 TaskInventoryItem item; 3478 TaskInventoryItem item;
3231 3479
3232 lock (m_host.TaskInventory) 3480 m_host.TaskInventory.LockItemsForRead(true);
3481 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3233 { 3482 {
3234 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3483 m_host.TaskInventory.LockItemsForRead(false);
3235 return; 3484 return;
3236 else
3237 item = m_host.TaskInventory[InventorySelf()];
3238 } 3485 }
3486 else
3487 {
3488 item = m_host.TaskInventory[InventorySelf()];
3489 }
3490 m_host.TaskInventory.LockItemsForRead(false);
3491
3239 3492
3240 if (item.PermsGranter == UUID.Zero) 3493 if (item.PermsGranter == UUID.Zero)
3241 return; 3494 return;
@@ -3306,10 +3559,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3306 3559
3307 TaskInventoryItem item; 3560 TaskInventoryItem item;
3308 3561
3309 lock (m_host.TaskInventory) 3562
3563 m_host.TaskInventory.LockItemsForRead(true);
3564 if (!m_host.TaskInventory.ContainsKey(invItemID))
3565 {
3566 m_host.TaskInventory.LockItemsForRead(false);
3567 return;
3568 }
3569 else
3310 { 3570 {
3311 item = m_host.TaskInventory[invItemID]; 3571 item = m_host.TaskInventory[invItemID];
3312 } 3572 }
3573 m_host.TaskInventory.LockItemsForRead(false);
3313 3574
3314 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3575 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3315 { 3576 {
@@ -3341,11 +3602,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3341 3602
3342 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3603 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3343 { 3604 {
3344 lock (m_host.TaskInventory) 3605 m_host.TaskInventory.LockItemsForWrite(true);
3345 { 3606 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3346 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3607 m_host.TaskInventory[invItemID].PermsMask = perm;
3347 m_host.TaskInventory[invItemID].PermsMask = perm; 3608 m_host.TaskInventory.LockItemsForWrite(false);
3348 }
3349 3609
3350 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3610 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3351 "run_time_permissions", new Object[] { 3611 "run_time_permissions", new Object[] {
@@ -3365,11 +3625,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3365 3625
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3626 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3627 {
3368 lock (m_host.TaskInventory) 3628 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3629 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3630 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3631 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3632
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3633 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3634 "run_time_permissions", new Object[] {
@@ -3390,11 +3649,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3390 3649
3391 if (!m_waitingForScriptAnswer) 3650 if (!m_waitingForScriptAnswer)
3392 { 3651 {
3393 lock (m_host.TaskInventory) 3652 m_host.TaskInventory.LockItemsForWrite(true);
3394 { 3653 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3395 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3654 m_host.TaskInventory[invItemID].PermsMask = 0;
3396 m_host.TaskInventory[invItemID].PermsMask = 0; 3655 m_host.TaskInventory.LockItemsForWrite(false);
3397 }
3398 3656
3399 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3657 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3400 m_waitingForScriptAnswer=true; 3658 m_waitingForScriptAnswer=true;
@@ -3429,10 +3687,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3687 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3430 llReleaseControls(); 3688 llReleaseControls();
3431 3689
3432 lock (m_host.TaskInventory) 3690
3433 { 3691 m_host.TaskInventory.LockItemsForWrite(true);
3434 m_host.TaskInventory[invItemID].PermsMask = answer; 3692 m_host.TaskInventory[invItemID].PermsMask = answer;
3435 } 3693 m_host.TaskInventory.LockItemsForWrite(false);
3694
3436 3695
3437 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3696 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3697 "run_time_permissions", new Object[] {
@@ -3444,16 +3703,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3444 { 3703 {
3445 m_host.AddScriptLPS(1); 3704 m_host.AddScriptLPS(1);
3446 3705
3447 lock (m_host.TaskInventory) 3706 m_host.TaskInventory.LockItemsForRead(true);
3707
3708 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3448 { 3709 {
3449 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3710 if (item.Type == 10 && item.ItemID == m_itemID)
3450 { 3711 {
3451 if (item.Type == 10 && item.ItemID == m_itemID) 3712 m_host.TaskInventory.LockItemsForRead(false);
3452 { 3713 return item.PermsGranter.ToString();
3453 return item.PermsGranter.ToString();
3454 }
3455 } 3714 }
3456 } 3715 }
3716 m_host.TaskInventory.LockItemsForRead(false);
3457 3717
3458 return UUID.Zero.ToString(); 3718 return UUID.Zero.ToString();
3459 } 3719 }
@@ -3462,19 +3722,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 { 3722 {
3463 m_host.AddScriptLPS(1); 3723 m_host.AddScriptLPS(1);
3464 3724
3465 lock (m_host.TaskInventory) 3725 m_host.TaskInventory.LockItemsForRead(true);
3726
3727 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3466 { 3728 {
3467 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3729 if (item.Type == 10 && item.ItemID == m_itemID)
3468 { 3730 {
3469 if (item.Type == 10 && item.ItemID == m_itemID) 3731 int perms = item.PermsMask;
3470 { 3732 if (m_automaticLinkPermission)
3471 int perms = item.PermsMask; 3733 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3472 if (m_automaticLinkPermission) 3734 m_host.TaskInventory.LockItemsForRead(false);
3473 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3735 return perms;
3474 return perms;
3475 }
3476 } 3736 }
3477 } 3737 }
3738 m_host.TaskInventory.LockItemsForRead(false);
3478 3739
3479 return 0; 3740 return 0;
3480 } 3741 }
@@ -3496,9 +3757,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3496 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3757 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3497 { 3758 {
3498 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3759 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3499 3760 if (parts.Count > 0)
3500 foreach (SceneObjectPart part in parts) 3761 {
3501 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3762 try
3763 {
3764 parts[0].ParentGroup.areUpdatesSuspended = true;
3765 foreach (SceneObjectPart part in parts)
3766 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3767 }
3768 finally
3769 {
3770 parts[0].ParentGroup.areUpdatesSuspended = false;
3771 }
3772 }
3502 } 3773 }
3503 3774
3504 public void llCreateLink(string target, int parent) 3775 public void llCreateLink(string target, int parent)
@@ -3507,11 +3778,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3507 UUID invItemID = InventorySelf(); 3778 UUID invItemID = InventorySelf();
3508 3779
3509 TaskInventoryItem item; 3780 TaskInventoryItem item;
3510 lock (m_host.TaskInventory) 3781 m_host.TaskInventory.LockItemsForRead(true);
3511 { 3782 item = m_host.TaskInventory[invItemID];
3512 item = m_host.TaskInventory[invItemID]; 3783 m_host.TaskInventory.LockItemsForRead(false);
3513 } 3784
3514
3515 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3785 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3516 && !m_automaticLinkPermission) 3786 && !m_automaticLinkPermission)
3517 { 3787 {
@@ -3564,16 +3834,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3564 m_host.AddScriptLPS(1); 3834 m_host.AddScriptLPS(1);
3565 UUID invItemID = InventorySelf(); 3835 UUID invItemID = InventorySelf();
3566 3836
3567 lock (m_host.TaskInventory) 3837 m_host.TaskInventory.LockItemsForRead(true);
3568 {
3569 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3838 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3570 && !m_automaticLinkPermission) 3839 && !m_automaticLinkPermission)
3571 { 3840 {
3572 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3841 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3842 m_host.TaskInventory.LockItemsForRead(false);
3573 return; 3843 return;
3574 } 3844 }
3575 } 3845 m_host.TaskInventory.LockItemsForRead(false);
3576 3846
3577 if (linknum < ScriptBaseClass.LINK_THIS) 3847 if (linknum < ScriptBaseClass.LINK_THIS)
3578 return; 3848 return;
3579 3849
@@ -3612,10 +3882,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3612 // Restructuring Multiple Prims. 3882 // Restructuring Multiple Prims.
3613 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3883 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3614 parts.Remove(parentPrim.RootPart); 3884 parts.Remove(parentPrim.RootPart);
3615 foreach (SceneObjectPart part in parts) 3885 if (parts.Count > 0)
3616 { 3886 {
3617 parentPrim.DelinkFromGroup(part.LocalId, true); 3887 try
3888 {
3889 parts[0].ParentGroup.areUpdatesSuspended = true;
3890 foreach (SceneObjectPart part in parts)
3891 {
3892 parentPrim.DelinkFromGroup(part.LocalId, true);
3893 }
3894 }
3895 finally
3896 {
3897 parts[0].ParentGroup.areUpdatesSuspended = false;
3898 }
3618 } 3899 }
3900
3619 parentPrim.HasGroupChanged = true; 3901 parentPrim.HasGroupChanged = true;
3620 parentPrim.ScheduleGroupForFullUpdate(); 3902 parentPrim.ScheduleGroupForFullUpdate();
3621 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3903 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3624,11 +3906,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3624 { 3906 {
3625 SceneObjectPart newRoot = parts[0]; 3907 SceneObjectPart newRoot = parts[0];
3626 parts.Remove(newRoot); 3908 parts.Remove(newRoot);
3627 foreach (SceneObjectPart part in parts) 3909
3910 try
3628 { 3911 {
3629 part.UpdateFlag = 0; 3912 parts[0].ParentGroup.areUpdatesSuspended = true;
3630 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3913 foreach (SceneObjectPart part in parts)
3914 {
3915 part.UpdateFlag = 0;
3916 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3917 }
3631 } 3918 }
3919 finally
3920 {
3921 parts[0].ParentGroup.areUpdatesSuspended = false;
3922 }
3923
3924
3632 newRoot.ParentGroup.HasGroupChanged = true; 3925 newRoot.ParentGroup.HasGroupChanged = true;
3633 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3926 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3634 } 3927 }
@@ -3654,11 +3947,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3654 3947
3655 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3948 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3656 parts.Remove(parentPrim.RootPart); 3949 parts.Remove(parentPrim.RootPart);
3657 3950 if (parts.Count > 0)
3658 foreach (SceneObjectPart part in parts)
3659 { 3951 {
3660 parentPrim.DelinkFromGroup(part.LocalId, true); 3952 try
3661 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3953 {
3954 parts[0].ParentGroup.areUpdatesSuspended = true;
3955 foreach (SceneObjectPart part in parts)
3956 {
3957 parentPrim.DelinkFromGroup(part.LocalId, true);
3958 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3959 }
3960 }
3961 finally
3962 {
3963 parts[0].ParentGroup.areUpdatesSuspended = false;
3964 }
3662 } 3965 }
3663 parentPrim.HasGroupChanged = true; 3966 parentPrim.HasGroupChanged = true;
3664 parentPrim.ScheduleGroupForFullUpdate(); 3967 parentPrim.ScheduleGroupForFullUpdate();
@@ -3750,17 +4053,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 m_host.AddScriptLPS(1); 4053 m_host.AddScriptLPS(1);
3751 int count = 0; 4054 int count = 0;
3752 4055
3753 lock (m_host.TaskInventory) 4056 m_host.TaskInventory.LockItemsForRead(true);
4057 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3754 { 4058 {
3755 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4059 if (inv.Value.Type == type || type == -1)
3756 { 4060 {
3757 if (inv.Value.Type == type || type == -1) 4061 count = count + 1;
3758 {
3759 count = count + 1;
3760 }
3761 } 4062 }
3762 } 4063 }
3763 4064
4065 m_host.TaskInventory.LockItemsForRead(false);
3764 return count; 4066 return count;
3765 } 4067 }
3766 4068
@@ -3769,16 +4071,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3769 m_host.AddScriptLPS(1); 4071 m_host.AddScriptLPS(1);
3770 ArrayList keys = new ArrayList(); 4072 ArrayList keys = new ArrayList();
3771 4073
3772 lock (m_host.TaskInventory) 4074 m_host.TaskInventory.LockItemsForRead(true);
4075 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3773 { 4076 {
3774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4077 if (inv.Value.Type == type || type == -1)
3775 { 4078 {
3776 if (inv.Value.Type == type || type == -1) 4079 keys.Add(inv.Value.Name);
3777 {
3778 keys.Add(inv.Value.Name);
3779 }
3780 } 4080 }
3781 } 4081 }
4082 m_host.TaskInventory.LockItemsForRead(false);
3782 4083
3783 if (keys.Count == 0) 4084 if (keys.Count == 0)
3784 { 4085 {
@@ -3815,20 +4116,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3815 } 4116 }
3816 4117
3817 // move the first object found with this inventory name 4118 // move the first object found with this inventory name
3818 lock (m_host.TaskInventory) 4119 m_host.TaskInventory.LockItemsForRead(true);
4120 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3819 { 4121 {
3820 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4122 if (inv.Value.Name == inventory)
3821 { 4123 {
3822 if (inv.Value.Name == inventory) 4124 found = true;
3823 { 4125 objId = inv.Key;
3824 found = true; 4126 assetType = inv.Value.Type;
3825 objId = inv.Key; 4127 objName = inv.Value.Name;
3826 assetType = inv.Value.Type; 4128 break;
3827 objName = inv.Value.Name;
3828 break;
3829 }
3830 } 4129 }
3831 } 4130 }
4131 m_host.TaskInventory.LockItemsForRead(false);
3832 4132
3833 if (!found) 4133 if (!found)
3834 { 4134 {
@@ -3836,9 +4136,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3836 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4136 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3837 } 4137 }
3838 4138
3839 // check if destination is an avatar 4139 // check if destination is an object
3840 if (World.GetScenePresence(destId) != null) 4140 if (World.GetSceneObjectPart(destId) != null)
4141 {
4142 // destination is an object
4143 World.MoveTaskInventoryItem(destId, m_host, objId);
4144 }
4145 else
3841 { 4146 {
4147 ScenePresence presence = World.GetScenePresence(destId);
4148
4149 if (presence == null)
4150 {
4151 UserAccount account =
4152 World.UserAccountService.GetUserAccount(
4153 World.RegionInfo.ScopeID,
4154 destId);
4155
4156 if (account == null)
4157 {
4158 llSay(0, "Can't find destination "+destId.ToString());
4159 return;
4160 }
4161 }
4162
3842 // destination is an avatar 4163 // destination is an avatar
3843 InventoryItemBase agentItem = 4164 InventoryItemBase agentItem =
3844 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4165 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3848,7 +4169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3848 4169
3849 byte[] bucket = new byte[17]; 4170 byte[] bucket = new byte[17];
3850 bucket[0] = (byte)assetType; 4171 bucket[0] = (byte)assetType;
3851 byte[] objBytes = objId.GetBytes(); 4172 byte[] objBytes = agentItem.ID.GetBytes();
3852 Array.Copy(objBytes, 0, bucket, 1, 16); 4173 Array.Copy(objBytes, 0, bucket, 1, 16);
3853 4174
3854 Console.WriteLine("Giving inventory"); 4175 Console.WriteLine("Giving inventory");
@@ -3864,33 +4185,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3864 4185
3865 if (m_TransferModule != null) 4186 if (m_TransferModule != null)
3866 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4187 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4188
4189 //This delay should only occur when giving inventory to avatars.
4190 ScriptSleep(3000);
3867 } 4191 }
3868 else
3869 {
3870 // destination is an object
3871 World.MoveTaskInventoryItem(destId, m_host, objId);
3872 }
3873 ScriptSleep(3000);
3874 } 4192 }
3875 4193
4194 [DebuggerNonUserCode]
3876 public void llRemoveInventory(string name) 4195 public void llRemoveInventory(string name)
3877 { 4196 {
3878 m_host.AddScriptLPS(1); 4197 m_host.AddScriptLPS(1);
3879 4198
3880 lock (m_host.TaskInventory) 4199 m_host.TaskInventory.LockItemsForRead(true);
4200 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3881 { 4201 {
3882 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4202 if (item.Name == name)
3883 { 4203 {
3884 if (item.Name == name) 4204 if (item.ItemID == m_itemID)
3885 { 4205 throw new ScriptDeleteException();
3886 if (item.ItemID == m_itemID) 4206 else
3887 throw new ScriptDeleteException(); 4207 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3888 else 4208
3889 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4209 m_host.TaskInventory.LockItemsForRead(false);
3890 return; 4210 return;
3891 }
3892 } 4211 }
3893 } 4212 }
4213 m_host.TaskInventory.LockItemsForRead(false);
3894 } 4214 }
3895 4215
3896 public void llSetText(string text, LSL_Vector color, double alpha) 4216 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3946,6 +4266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3946 ce.time = Util.EnvironmentTickCount(); 4266 ce.time = Util.EnvironmentTickCount();
3947 ce.account = account; 4267 ce.account = account;
3948 ce.pinfo = pinfo; 4268 ce.pinfo = pinfo;
4269 m_userInfoCache[uuid] = ce;
3949 } 4270 }
3950 else 4271 else
3951 { 4272 {
@@ -4013,6 +4334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4013 { 4334 {
4014 m_host.AddScriptLPS(1); 4335 m_host.AddScriptLPS(1);
4015 4336
4337 //Clone is thread safe
4016 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4338 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4017 4339
4018 foreach (TaskInventoryItem item in itemDictionary.Values) 4340 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4066,6 +4388,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4066 ScenePresence presence = World.GetScenePresence(agentId); 4388 ScenePresence presence = World.GetScenePresence(agentId);
4067 if (presence != null) 4389 if (presence != null)
4068 { 4390 {
4391 // agent must not be a god
4392 if (presence.GodLevel >= 200) return;
4393
4069 // agent must be over the owners land 4394 // agent must be over the owners land
4070 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4395 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4071 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4396 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4126,17 +4451,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4126 UUID soundId = UUID.Zero; 4451 UUID soundId = UUID.Zero;
4127 if (!UUID.TryParse(impact_sound, out soundId)) 4452 if (!UUID.TryParse(impact_sound, out soundId))
4128 { 4453 {
4129 lock (m_host.TaskInventory) 4454 m_host.TaskInventory.LockItemsForRead(true);
4455 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4130 { 4456 {
4131 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4457 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4132 { 4458 {
4133 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4459 soundId = item.AssetID;
4134 { 4460 break;
4135 soundId = item.AssetID;
4136 break;
4137 }
4138 } 4461 }
4139 } 4462 }
4463 m_host.TaskInventory.LockItemsForRead(false);
4140 } 4464 }
4141 m_host.CollisionSound = soundId; 4465 m_host.CollisionSound = soundId;
4142 m_host.CollisionSoundVolume = (float)impact_volume; 4466 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4182,6 +4506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4182 UUID partItemID; 4506 UUID partItemID;
4183 foreach (SceneObjectPart part in parts) 4507 foreach (SceneObjectPart part in parts)
4184 { 4508 {
4509 //Clone is thread safe
4185 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4510 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4186 4511
4187 foreach (TaskInventoryItem item in itemsDictionary.Values) 4512 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4396,17 +4721,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4396 4721
4397 m_host.AddScriptLPS(1); 4722 m_host.AddScriptLPS(1);
4398 4723
4399 lock (m_host.TaskInventory) 4724 m_host.TaskInventory.LockItemsForRead(true);
4725 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4400 { 4726 {
4401 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4727 if (item.Type == 10 && item.ItemID == m_itemID)
4402 { 4728 {
4403 if (item.Type == 10 && item.ItemID == m_itemID) 4729 result = item.Name!=null?item.Name:String.Empty;
4404 { 4730 break;
4405 result = item.Name != null ? item.Name : String.Empty;
4406 break;
4407 }
4408 } 4731 }
4409 } 4732 }
4733 m_host.TaskInventory.LockItemsForRead(false);
4410 4734
4411 return result; 4735 return result;
4412 } 4736 }
@@ -4559,23 +4883,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4559 { 4883 {
4560 m_host.AddScriptLPS(1); 4884 m_host.AddScriptLPS(1);
4561 4885
4562 lock (m_host.TaskInventory) 4886 m_host.TaskInventory.LockItemsForRead(true);
4887 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4563 { 4888 {
4564 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4889 if (inv.Value.Name == name)
4565 { 4890 {
4566 if (inv.Value.Name == name) 4891 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4567 { 4892 {
4568 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4893 m_host.TaskInventory.LockItemsForRead(false);
4569 { 4894 return inv.Value.AssetID.ToString();
4570 return inv.Value.AssetID.ToString(); 4895 }
4571 } 4896 else
4572 else 4897 {
4573 { 4898 m_host.TaskInventory.LockItemsForRead(false);
4574 return UUID.Zero.ToString(); 4899 return UUID.Zero.ToString();
4575 }
4576 } 4900 }
4577 } 4901 }
4578 } 4902 }
4903 m_host.TaskInventory.LockItemsForRead(false);
4579 4904
4580 return UUID.Zero.ToString(); 4905 return UUID.Zero.ToString();
4581 } 4906 }
@@ -4728,14 +5053,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5053 {
4729 m_host.AddScriptLPS(1); 5054 m_host.AddScriptLPS(1);
4730 5055
4731 if (src == null) 5056 return src.Length;
4732 {
4733 return 0;
4734 }
4735 else
4736 {
4737 return src.Length;
4738 }
4739 } 5057 }
4740 5058
4741 public LSL_Integer llList2Integer(LSL_List src, int index) 5059 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5511,10 +5829,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5511 m_host.AddScriptLPS(1); 5829 m_host.AddScriptLPS(1);
5512 5830
5513 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5831 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5514 5832 if (parts.Count > 0)
5515 foreach (var part in parts)
5516 { 5833 {
5517 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5834 try
5835 {
5836 parts[0].ParentGroup.areUpdatesSuspended = true;
5837 foreach (var part in parts)
5838 {
5839 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5840 }
5841 }
5842 finally
5843 {
5844 parts[0].ParentGroup.areUpdatesSuspended = false;
5845 }
5518 } 5846 }
5519 } 5847 }
5520 5848
@@ -5570,74 +5898,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5570 5898
5571 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5899 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5572 { 5900 {
5573 m_host.AddScriptLPS(1); 5901 return ParseString2List(str, separators, in_spacers, false);
5574 LSL_List ret = new LSL_List();
5575 LSL_List spacers = new LSL_List();
5576 if (in_spacers.Length > 0 && separators.Length > 0)
5577 {
5578 for (int i = 0; i < in_spacers.Length; i++)
5579 {
5580 object s = in_spacers.Data[i];
5581 for (int j = 0; j < separators.Length; j++)
5582 {
5583 if (separators.Data[j].ToString() == s.ToString())
5584 {
5585 s = null;
5586 break;
5587 }
5588 }
5589 if (s != null)
5590 {
5591 spacers.Add(s);
5592 }
5593 }
5594 }
5595 object[] delimiters = new object[separators.Length + spacers.Length];
5596 separators.Data.CopyTo(delimiters, 0);
5597 spacers.Data.CopyTo(delimiters, separators.Length);
5598 bool dfound = false;
5599 do
5600 {
5601 dfound = false;
5602 int cindex = -1;
5603 string cdeli = "";
5604 for (int i = 0; i < delimiters.Length; i++)
5605 {
5606 int index = str.IndexOf(delimiters[i].ToString());
5607 bool found = index != -1;
5608 if (found && String.Empty != delimiters[i].ToString())
5609 {
5610 if ((cindex > index) || (cindex == -1))
5611 {
5612 cindex = index;
5613 cdeli = delimiters[i].ToString();
5614 }
5615 dfound = dfound || found;
5616 }
5617 }
5618 if (cindex != -1)
5619 {
5620 if (cindex > 0)
5621 {
5622 ret.Add(new LSL_String(str.Substring(0, cindex)));
5623 }
5624 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5625 for (int j = 0; j < spacers.Length; j++)
5626 {
5627 if (spacers.Data[j].ToString() == cdeli)
5628 {
5629 ret.Add(new LSL_String(cdeli));
5630 break;
5631 }
5632 }
5633 str = str.Substring(cindex + cdeli.Length);
5634 }
5635 } while (dfound);
5636 if (str != "")
5637 {
5638 ret.Add(new LSL_String(str));
5639 }
5640 return ret;
5641 } 5902 }
5642 5903
5643 public LSL_Integer llOverMyLand(string id) 5904 public LSL_Integer llOverMyLand(string id)
@@ -5840,7 +6101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5840 return m_host.ParentGroup.RootPart.AttachmentPoint; 6101 return m_host.ParentGroup.RootPart.AttachmentPoint;
5841 } 6102 }
5842 6103
5843 public LSL_Integer llGetFreeMemory() 6104 public virtual LSL_Integer llGetFreeMemory()
5844 { 6105 {
5845 m_host.AddScriptLPS(1); 6106 m_host.AddScriptLPS(1);
5846 // Make scripts designed for LSO happy 6107 // Make scripts designed for LSO happy
@@ -6151,14 +6412,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6151 6412
6152 protected UUID GetTaskInventoryItem(string name) 6413 protected UUID GetTaskInventoryItem(string name)
6153 { 6414 {
6154 lock (m_host.TaskInventory) 6415 m_host.TaskInventory.LockItemsForRead(true);
6416 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6155 { 6417 {
6156 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6418 if (inv.Value.Name == name)
6157 { 6419 {
6158 if (inv.Value.Name == name) 6420 m_host.TaskInventory.LockItemsForRead(false);
6159 return inv.Key; 6421 return inv.Key;
6160 } 6422 }
6161 } 6423 }
6424 m_host.TaskInventory.LockItemsForRead(false);
6162 6425
6163 return UUID.Zero; 6426 return UUID.Zero;
6164 } 6427 }
@@ -6486,22 +6749,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6486 } 6749 }
6487 6750
6488 // copy the first script found with this inventory name 6751 // copy the first script found with this inventory name
6489 lock (m_host.TaskInventory) 6752 m_host.TaskInventory.LockItemsForRead(true);
6753 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6490 { 6754 {
6491 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6755 if (inv.Value.Name == name)
6492 { 6756 {
6493 if (inv.Value.Name == name) 6757 // make sure the object is a script
6758 if (10 == inv.Value.Type)
6494 { 6759 {
6495 // make sure the object is a script 6760 found = true;
6496 if (10 == inv.Value.Type) 6761 srcId = inv.Key;
6497 { 6762 break;
6498 found = true;
6499 srcId = inv.Key;
6500 break;
6501 }
6502 } 6763 }
6503 } 6764 }
6504 } 6765 }
6766 m_host.TaskInventory.LockItemsForRead(false);
6505 6767
6506 if (!found) 6768 if (!found)
6507 { 6769 {
@@ -6585,6 +6847,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6585 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6847 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6586 { 6848 {
6587 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6850 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6851 return shapeBlock;
6588 6852
6589 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6853 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6590 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6854 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6660,6 +6924,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6660 6924
6661 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6925 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6662 { 6926 {
6927 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6928 return;
6929
6663 ObjectShapePacket.ObjectDataBlock shapeBlock; 6930 ObjectShapePacket.ObjectDataBlock shapeBlock;
6664 6931
6665 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6932 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6709,6 +6976,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6709 6976
6710 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6977 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6711 { 6978 {
6979 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6980 return;
6981
6712 ObjectShapePacket.ObjectDataBlock shapeBlock; 6982 ObjectShapePacket.ObjectDataBlock shapeBlock;
6713 6983
6714 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6984 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6751,6 +7021,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6751 7021
6752 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) 7022 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)
6753 { 7023 {
7024 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7025 return;
7026
6754 ObjectShapePacket.ObjectDataBlock shapeBlock; 7027 ObjectShapePacket.ObjectDataBlock shapeBlock;
6755 7028
6756 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7029 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6877,6 +7150,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 7150
6878 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7151 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6879 { 7152 {
7153 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7154 return;
7155
6880 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7156 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6881 UUID sculptId; 7157 UUID sculptId;
6882 7158
@@ -6892,13 +7168,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6892 shapeBlock.PathScaleX = 100; 7168 shapeBlock.PathScaleX = 100;
6893 shapeBlock.PathScaleY = 150; 7169 shapeBlock.PathScaleY = 150;
6894 7170
6895 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7171 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6896 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7172 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6897 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7173 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6898 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7174 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6899 { 7175 {
6900 // default 7176 // default
6901 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7177 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6902 } 7178 }
6903 7179
6904 // retain pathcurve 7180 // retain pathcurve
@@ -6915,23 +7191,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6915 SetPrimParams(m_host, rules); 7191 SetPrimParams(m_host, rules);
6916 } 7192 }
6917 7193
6918 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7194 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6919 { 7195 {
6920 m_host.AddScriptLPS(1); 7196 m_host.AddScriptLPS(1);
6921 7197
6922 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7198 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7199 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7200 if (parts.Count>0)
7201 {
7202 try
7203 {
7204 parts[0].ParentGroup.areUpdatesSuspended = true;
7205 foreach (SceneObjectPart part in parts)
7206 SetPrimParams(part, rules);
7207 }
7208 finally
7209 {
7210 parts[0].ParentGroup.areUpdatesSuspended = false;
7211 }
7212 }
7213 if (avatars.Count > 0)
7214 {
7215 foreach (ScenePresence avatar in avatars)
7216 SetPrimParams(avatar, rules);
7217 }
7218 }
6923 7219
6924 foreach (SceneObjectPart part in parts) 7220 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6925 SetPrimParams(part, rules); 7221 {
7222 llSetLinkPrimitiveParamsFast(linknumber, rules);
7223 ScriptSleep(200);
6926 } 7224 }
6927 7225
6928 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7226 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6929 { 7227 {
6930 llSetLinkPrimitiveParams(linknumber, rules); 7228 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7229 //We only support PRIM_POSITION and PRIM_ROTATION
7230
7231 int idx = 0;
7232
7233 while (idx < rules.Length)
7234 {
7235 int code = rules.GetLSLIntegerItem(idx++);
7236
7237 int remain = rules.Length - idx;
7238
7239
7240
7241 switch (code)
7242 {
7243 case (int)ScriptBaseClass.PRIM_POSITION:
7244 if (remain < 1)
7245 return;
7246 LSL_Vector v;
7247 v = rules.GetVector3Item(idx++);
7248 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7249 av.SendFullUpdateToAllClients();
7250
7251 break;
7252
7253 case (int)ScriptBaseClass.PRIM_ROTATION:
7254 if (remain < 1)
7255 return;
7256 LSL_Rotation r;
7257 r = rules.GetQuaternionItem(idx++);
7258 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7259 av.SendFullUpdateToAllClients();
7260 break;
7261 }
7262 }
7263
6931 } 7264 }
6932 7265
6933 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7266 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6934 { 7267 {
7268 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7269 return;
7270
6935 int idx = 0; 7271 int idx = 0;
6936 7272
6937 while (idx < rules.Length) 7273 while (idx < rules.Length)
@@ -7763,24 +8099,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7763 break; 8099 break;
7764 8100
7765 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8101 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7766 // TODO--------------
7767 if (remain < 1) 8102 if (remain < 1)
7768 return res; 8103 return res;
8104 face = (int)rules.GetLSLIntegerItem(idx++);
7769 8105
7770 face=(int)rules.GetLSLIntegerItem(idx++); 8106 tex = part.Shape.Textures;
7771 8107 int shiny;
7772 res.Add(new LSL_Integer(0)); 8108 if (face == ScriptBaseClass.ALL_SIDES)
7773 res.Add(new LSL_Integer(0)); 8109 {
8110 for (face = 0; face < GetNumberOfSides(part); face++)
8111 {
8112 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8113 if (shinyness == Shininess.High)
8114 {
8115 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8116 }
8117 else if (shinyness == Shininess.Medium)
8118 {
8119 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8120 }
8121 else if (shinyness == Shininess.Low)
8122 {
8123 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8124 }
8125 else
8126 {
8127 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8128 }
8129 res.Add(new LSL_Integer(shiny));
8130 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8131 }
8132 }
8133 else
8134 {
8135 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8136 if (shinyness == Shininess.High)
8137 {
8138 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8139 }
8140 else if (shinyness == Shininess.Medium)
8141 {
8142 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8143 }
8144 else if (shinyness == Shininess.Low)
8145 {
8146 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8147 }
8148 else
8149 {
8150 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8151 }
8152 res.Add(new LSL_Integer(shiny));
8153 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8154 }
7774 break; 8155 break;
7775 8156
7776 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8157 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7777 // TODO--------------
7778 if (remain < 1) 8158 if (remain < 1)
7779 return res; 8159 return res;
8160 face = (int)rules.GetLSLIntegerItem(idx++);
7780 8161
7781 face=(int)rules.GetLSLIntegerItem(idx++); 8162 tex = part.Shape.Textures;
7782 8163 int fullbright;
7783 res.Add(new LSL_Integer(0)); 8164 if (face == ScriptBaseClass.ALL_SIDES)
8165 {
8166 for (face = 0; face < GetNumberOfSides(part); face++)
8167 {
8168 if (tex.GetFace((uint)face).Fullbright == true)
8169 {
8170 fullbright = ScriptBaseClass.TRUE;
8171 }
8172 else
8173 {
8174 fullbright = ScriptBaseClass.FALSE;
8175 }
8176 res.Add(new LSL_Integer(fullbright));
8177 }
8178 }
8179 else
8180 {
8181 if (tex.GetFace((uint)face).Fullbright == true)
8182 {
8183 fullbright = ScriptBaseClass.TRUE;
8184 }
8185 else
8186 {
8187 fullbright = ScriptBaseClass.FALSE;
8188 }
8189 res.Add(new LSL_Integer(fullbright));
8190 }
7784 break; 8191 break;
7785 8192
7786 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8193 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7801,14 +8208,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7801 break; 8208 break;
7802 8209
7803 case (int)ScriptBaseClass.PRIM_TEXGEN: 8210 case (int)ScriptBaseClass.PRIM_TEXGEN:
7804 // TODO--------------
7805 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8211 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7806 if (remain < 1) 8212 if (remain < 1)
7807 return res; 8213 return res;
8214 face = (int)rules.GetLSLIntegerItem(idx++);
7808 8215
7809 face=(int)rules.GetLSLIntegerItem(idx++); 8216 tex = part.Shape.Textures;
7810 8217 if (face == ScriptBaseClass.ALL_SIDES)
7811 res.Add(new LSL_Integer(0)); 8218 {
8219 for (face = 0; face < GetNumberOfSides(part); face++)
8220 {
8221 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8222 {
8223 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8224 }
8225 else
8226 {
8227 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8228 }
8229 }
8230 }
8231 else
8232 {
8233 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8234 {
8235 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8236 }
8237 else
8238 {
8239 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8240 }
8241 }
7812 break; 8242 break;
7813 8243
7814 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8244 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7827,13 +8257,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7827 break; 8257 break;
7828 8258
7829 case (int)ScriptBaseClass.PRIM_GLOW: 8259 case (int)ScriptBaseClass.PRIM_GLOW:
7830 // TODO--------------
7831 if (remain < 1) 8260 if (remain < 1)
7832 return res; 8261 return res;
8262 face = (int)rules.GetLSLIntegerItem(idx++);
7833 8263
7834 face=(int)rules.GetLSLIntegerItem(idx++); 8264 tex = part.Shape.Textures;
7835 8265 float primglow;
7836 res.Add(new LSL_Float(0)); 8266 if (face == ScriptBaseClass.ALL_SIDES)
8267 {
8268 for (face = 0; face < GetNumberOfSides(part); face++)
8269 {
8270 primglow = tex.GetFace((uint)face).Glow;
8271 res.Add(new LSL_Float(primglow));
8272 }
8273 }
8274 else
8275 {
8276 primglow = tex.GetFace((uint)face).Glow;
8277 res.Add(new LSL_Float(primglow));
8278 }
7837 break; 8279 break;
7838 case (int)ScriptBaseClass.PRIM_TEXT: 8280 case (int)ScriptBaseClass.PRIM_TEXT:
7839 Color4 textColor = part.GetTextColor(); 8281 Color4 textColor = part.GetTextColor();
@@ -8374,8 +8816,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8374 // The function returns an ordered list 8816 // The function returns an ordered list
8375 // representing the tokens found in the supplied 8817 // representing the tokens found in the supplied
8376 // sources string. If two successive tokenizers 8818 // sources string. If two successive tokenizers
8377 // are encountered, then a NULL entry is added 8819 // are encountered, then a null-string entry is
8378 // to the list. 8820 // added to the list.
8379 // 8821 //
8380 // It is a precondition that the source and 8822 // It is a precondition that the source and
8381 // toekizer lisst are non-null. If they are null, 8823 // toekizer lisst are non-null. If they are null,
@@ -8383,7 +8825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8383 // while their lengths are being determined. 8825 // while their lengths are being determined.
8384 // 8826 //
8385 // A small amount of working memoryis required 8827 // A small amount of working memoryis required
8386 // of approximately 8*#tokenizers. 8828 // of approximately 8*#tokenizers + 8*srcstrlen.
8387 // 8829 //
8388 // There are many ways in which this function 8830 // There are many ways in which this function
8389 // can be implemented, this implementation is 8831 // can be implemented, this implementation is
@@ -8399,136 +8841,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8399 // and eliminates redundant tokenizers as soon 8841 // and eliminates redundant tokenizers as soon
8400 // as is possible. 8842 // as is possible.
8401 // 8843 //
8402 // The implementation tries to avoid any copying 8844 // The implementation tries to minimize temporary
8403 // of arrays or other objects. 8845 // garbage generation.
8404 // </remarks> 8846 // </remarks>
8405 8847
8406 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8848 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8407 { 8849 {
8408 int beginning = 0; 8850 return ParseString2List(src, separators, spacers, true);
8409 int srclen = src.Length; 8851 }
8410 int seplen = separators.Length;
8411 object[] separray = separators.Data;
8412 int spclen = spacers.Length;
8413 object[] spcarray = spacers.Data;
8414 int mlen = seplen+spclen;
8415
8416 int[] offset = new int[mlen+1];
8417 bool[] active = new bool[mlen];
8418 8852
8419 int best; 8853 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8420 int j; 8854 {
8855 int srclen = src.Length;
8856 int seplen = separators.Length;
8857 object[] separray = separators.Data;
8858 int spclen = spacers.Length;
8859 object[] spcarray = spacers.Data;
8860 int dellen = 0;
8861 string[] delarray = new string[seplen+spclen];
8421 8862
8422 // Initial capacity reduces resize cost 8863 int outlen = 0;
8864 string[] outarray = new string[srclen*2+1];
8423 8865
8424 LSL_List tokens = new LSL_List(); 8866 int i, j;
8867 string d;
8425 8868
8426 m_host.AddScriptLPS(1); 8869 m_host.AddScriptLPS(1);
8427 8870
8428 // All entries are initially valid 8871 /*
8429 8872 * Convert separator and spacer lists to C# strings.
8430 for (int i = 0; i < mlen; i++) 8873 * Also filter out null strings so we don't hang.
8431 active[i] = true; 8874 */
8432 8875 for (i = 0; i < seplen; i ++) {
8433 offset[mlen] = srclen; 8876 d = separray[i].ToString();
8434 8877 if (d.Length > 0) {
8435 while (beginning < srclen) 8878 delarray[dellen++] = d;
8436 { 8879 }
8437 8880 }
8438 best = mlen; // as bad as it gets 8881 seplen = dellen;
8439
8440 // Scan for separators
8441 8882
8442 for (j = 0; j < seplen; j++) 8883 for (i = 0; i < spclen; i ++) {
8443 { 8884 d = spcarray[i].ToString();
8444 if (active[j]) 8885 if (d.Length > 0) {
8445 { 8886 delarray[dellen++] = d;
8446 // scan all of the markers
8447 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8448 {
8449 // not present at all
8450 active[j] = false;
8451 }
8452 else
8453 {
8454 // present and correct
8455 if (offset[j] < offset[best])
8456 {
8457 // closest so far
8458 best = j;
8459 if (offset[best] == beginning)
8460 break;
8461 }
8462 }
8463 }
8464 } 8887 }
8888 }
8465 8889
8466 // Scan for spacers 8890 /*
8891 * Scan through source string from beginning to end.
8892 */
8893 for (i = 0;;) {
8467 8894
8468 if (offset[best] != beginning) 8895 /*
8469 { 8896 * Find earliest delimeter in src starting at i (if any).
8470 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8897 */
8471 { 8898 int earliestDel = -1;
8472 if (active[j]) 8899 int earliestSrc = srclen;
8473 { 8900 string earliestStr = null;
8474 // scan all of the markers 8901 for (j = 0; j < dellen; j ++) {
8475 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8902 d = delarray[j];
8476 { 8903 if (d != null) {
8477 // not present at all 8904 int index = src.IndexOf(d, i);
8478 active[j] = false; 8905 if (index < 0) {
8479 } 8906 delarray[j] = null; // delim nowhere in src, don't check it anymore
8480 else 8907 } else if (index < earliestSrc) {
8481 { 8908 earliestSrc = index; // where delimeter starts in source string
8482 // present and correct 8909 earliestDel = j; // where delimeter is in delarray[]
8483 if (offset[j] < offset[best]) 8910 earliestStr = d; // the delimeter string from delarray[]
8484 { 8911 if (index == i) break; // can't do any better than found at beg of string
8485 // closest so far
8486 best = j;
8487 }
8488 }
8489 } 8912 }
8490 } 8913 }
8491 } 8914 }
8492 8915
8493 // This is the normal exit from the scanning loop 8916 /*
8494 8917 * Output source string starting at i through start of earliest delimeter.
8495 if (best == mlen) 8918 */
8496 { 8919 if (keepNulls || (earliestSrc > i)) {
8497 // no markers were found on this pass 8920 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8498 // so we're pretty much done
8499 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8500 break;
8501 } 8921 }
8502 8922
8503 // Otherwise we just add the newly delimited token 8923 /*
8504 // and recalculate where the search should continue. 8924 * If no delimeter found at or after i, we're done scanning.
8925 */
8926 if (earliestDel < 0) break;
8505 8927
8506 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8928 /*
8507 8929 * If delimeter was a spacer, output the spacer.
8508 if (best < seplen) 8930 */
8509 { 8931 if (earliestDel >= seplen) {
8510 beginning = offset[best] + (separray[best].ToString()).Length; 8932 outarray[outlen++] = earliestStr;
8511 } 8933 }
8512 else
8513 {
8514 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8515 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8516 }
8517 }
8518 8934
8519 // This an awkward an not very intuitive boundary case. If the 8935 /*
8520 // last substring is a tokenizer, then there is an implied trailing 8936 * Look at rest of src string following delimeter.
8521 // null list entry. Hopefully the single comparison will not be too 8937 */
8522 // arduous. Alternatively the 'break' could be replced with a return 8938 i = earliestSrc + earliestStr.Length;
8523 // but that's shabby programming.
8524
8525 if (beginning == srclen)
8526 {
8527 if (srclen != 0)
8528 tokens.Add(new LSL_String(""));
8529 } 8939 }
8530 8940
8531 return tokens; 8941 /*
8942 * Make up an exact-sized output array suitable for an LSL_List object.
8943 */
8944 object[] outlist = new object[outlen];
8945 for (i = 0; i < outlen; i ++) {
8946 outlist[i] = new LSL_String(outarray[i]);
8947 }
8948 return new LSL_List(outlist);
8532 } 8949 }
8533 8950
8534 public LSL_Integer llGetObjectPermMask(int mask) 8951 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8605,28 +9022,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8605 { 9022 {
8606 m_host.AddScriptLPS(1); 9023 m_host.AddScriptLPS(1);
8607 9024
8608 lock (m_host.TaskInventory) 9025 m_host.TaskInventory.LockItemsForRead(true);
9026 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8609 { 9027 {
8610 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9028 if (inv.Value.Name == item)
8611 { 9029 {
8612 if (inv.Value.Name == item) 9030 m_host.TaskInventory.LockItemsForRead(false);
9031 switch (mask)
8613 { 9032 {
8614 switch (mask) 9033 case 0:
8615 { 9034 return (int)inv.Value.BasePermissions;
8616 case 0: 9035 case 1:
8617 return (int)inv.Value.BasePermissions; 9036 return (int)inv.Value.CurrentPermissions;
8618 case 1: 9037 case 2:
8619 return (int)inv.Value.CurrentPermissions; 9038 return (int)inv.Value.GroupPermissions;
8620 case 2: 9039 case 3:
8621 return (int)inv.Value.GroupPermissions; 9040 return (int)inv.Value.EveryonePermissions;
8622 case 3: 9041 case 4:
8623 return (int)inv.Value.EveryonePermissions; 9042 return (int)inv.Value.NextPermissions;
8624 case 4:
8625 return (int)inv.Value.NextPermissions;
8626 }
8627 } 9043 }
8628 } 9044 }
8629 } 9045 }
9046 m_host.TaskInventory.LockItemsForRead(false);
8630 9047
8631 return -1; 9048 return -1;
8632 } 9049 }
@@ -8673,16 +9090,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8673 { 9090 {
8674 m_host.AddScriptLPS(1); 9091 m_host.AddScriptLPS(1);
8675 9092
8676 lock (m_host.TaskInventory) 9093 m_host.TaskInventory.LockItemsForRead(true);
9094 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8677 { 9095 {
8678 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9096 if (inv.Value.Name == item)
8679 { 9097 {
8680 if (inv.Value.Name == item) 9098 m_host.TaskInventory.LockItemsForRead(false);
8681 { 9099 return inv.Value.CreatorID.ToString();
8682 return inv.Value.CreatorID.ToString();
8683 }
8684 } 9100 }
8685 } 9101 }
9102 m_host.TaskInventory.LockItemsForRead(false);
8686 9103
8687 llSay(0, "No item name '" + item + "'"); 9104 llSay(0, "No item name '" + item + "'");
8688 9105
@@ -8728,8 +9145,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8728 return UUID.Zero.ToString(); 9145 return UUID.Zero.ToString();
8729 } 9146 }
8730 reply = new LSL_Vector( 9147 reply = new LSL_Vector(
8731 info.RegionLocX * Constants.RegionSize, 9148 info.RegionLocX / Constants.RegionSize,
8732 info.RegionLocY * Constants.RegionSize, 9149 info.RegionLocY / Constants.RegionSize,
8733 0).ToString(); 9150 0).ToString();
8734 break; 9151 break;
8735 case 6: // DATA_SIM_STATUS 9152 case 6: // DATA_SIM_STATUS
@@ -8942,17 +9359,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8942 int width = 0; 9359 int width = 0;
8943 int height = 0; 9360 int height = 0;
8944 9361
8945 ParcelMediaCommandEnum? commandToSend = null; 9362 uint commandToSend = 0;
8946 float time = 0.0f; // default is from start 9363 float time = 0.0f; // default is from start
8947 9364
8948 ScenePresence presence = null; 9365 ScenePresence presence = null;
8949 9366
8950 for (int i = 0; i < commandList.Data.Length; i++) 9367 for (int i = 0; i < commandList.Data.Length; i++)
8951 { 9368 {
8952 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9369 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8953 switch (command) 9370 switch (command)
8954 { 9371 {
8955 case ParcelMediaCommandEnum.Agent: 9372 case (uint)ParcelMediaCommandEnum.Agent:
8956 // we send only to one agent 9373 // we send only to one agent
8957 if ((i + 1) < commandList.Length) 9374 if ((i + 1) < commandList.Length)
8958 { 9375 {
@@ -8969,25 +9386,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8969 } 9386 }
8970 break; 9387 break;
8971 9388
8972 case ParcelMediaCommandEnum.Loop: 9389 case (uint)ParcelMediaCommandEnum.Loop:
8973 loop = 1; 9390 loop = 1;
8974 commandToSend = command; 9391 commandToSend = command;
8975 update = true; //need to send the media update packet to set looping 9392 update = true; //need to send the media update packet to set looping
8976 break; 9393 break;
8977 9394
8978 case ParcelMediaCommandEnum.Play: 9395 case (uint)ParcelMediaCommandEnum.Play:
8979 loop = 0; 9396 loop = 0;
8980 commandToSend = command; 9397 commandToSend = command;
8981 update = true; //need to send the media update packet to make sure it doesn't loop 9398 update = true; //need to send the media update packet to make sure it doesn't loop
8982 break; 9399 break;
8983 9400
8984 case ParcelMediaCommandEnum.Pause: 9401 case (uint)ParcelMediaCommandEnum.Pause:
8985 case ParcelMediaCommandEnum.Stop: 9402 case (uint)ParcelMediaCommandEnum.Stop:
8986 case ParcelMediaCommandEnum.Unload: 9403 case (uint)ParcelMediaCommandEnum.Unload:
8987 commandToSend = command; 9404 commandToSend = command;
8988 break; 9405 break;
8989 9406
8990 case ParcelMediaCommandEnum.Url: 9407 case (uint)ParcelMediaCommandEnum.Url:
8991 if ((i + 1) < commandList.Length) 9408 if ((i + 1) < commandList.Length)
8992 { 9409 {
8993 if (commandList.Data[i + 1] is LSL_String) 9410 if (commandList.Data[i + 1] is LSL_String)
@@ -9000,7 +9417,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9000 } 9417 }
9001 break; 9418 break;
9002 9419
9003 case ParcelMediaCommandEnum.Texture: 9420 case (uint)ParcelMediaCommandEnum.Texture:
9004 if ((i + 1) < commandList.Length) 9421 if ((i + 1) < commandList.Length)
9005 { 9422 {
9006 if (commandList.Data[i + 1] is LSL_String) 9423 if (commandList.Data[i + 1] is LSL_String)
@@ -9013,7 +9430,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9013 } 9430 }
9014 break; 9431 break;
9015 9432
9016 case ParcelMediaCommandEnum.Time: 9433 case (uint)ParcelMediaCommandEnum.Time:
9017 if ((i + 1) < commandList.Length) 9434 if ((i + 1) < commandList.Length)
9018 { 9435 {
9019 if (commandList.Data[i + 1] is LSL_Float) 9436 if (commandList.Data[i + 1] is LSL_Float)
@@ -9025,7 +9442,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9025 } 9442 }
9026 break; 9443 break;
9027 9444
9028 case ParcelMediaCommandEnum.AutoAlign: 9445 case (uint)ParcelMediaCommandEnum.AutoAlign:
9029 if ((i + 1) < commandList.Length) 9446 if ((i + 1) < commandList.Length)
9030 { 9447 {
9031 if (commandList.Data[i + 1] is LSL_Integer) 9448 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9039,7 +9456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9039 } 9456 }
9040 break; 9457 break;
9041 9458
9042 case ParcelMediaCommandEnum.Type: 9459 case (uint)ParcelMediaCommandEnum.Type:
9043 if ((i + 1) < commandList.Length) 9460 if ((i + 1) < commandList.Length)
9044 { 9461 {
9045 if (commandList.Data[i + 1] is LSL_String) 9462 if (commandList.Data[i + 1] is LSL_String)
@@ -9052,7 +9469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 } 9469 }
9053 break; 9470 break;
9054 9471
9055 case ParcelMediaCommandEnum.Desc: 9472 case (uint)ParcelMediaCommandEnum.Desc:
9056 if ((i + 1) < commandList.Length) 9473 if ((i + 1) < commandList.Length)
9057 { 9474 {
9058 if (commandList.Data[i + 1] is LSL_String) 9475 if (commandList.Data[i + 1] is LSL_String)
@@ -9065,7 +9482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9065 } 9482 }
9066 break; 9483 break;
9067 9484
9068 case ParcelMediaCommandEnum.Size: 9485 case (uint)ParcelMediaCommandEnum.Size:
9069 if ((i + 2) < commandList.Length) 9486 if ((i + 2) < commandList.Length)
9070 { 9487 {
9071 if (commandList.Data[i + 1] is LSL_Integer) 9488 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9135,7 +9552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9135 } 9552 }
9136 } 9553 }
9137 9554
9138 if (commandToSend != null) 9555 if (commandToSend != 0)
9139 { 9556 {
9140 // the commandList contained a start/stop/... command, too 9557 // the commandList contained a start/stop/... command, too
9141 if (presence == null) 9558 if (presence == null)
@@ -9172,7 +9589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9172 9589
9173 if (aList.Data[i] != null) 9590 if (aList.Data[i] != null)
9174 { 9591 {
9175 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9592 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9176 { 9593 {
9177 case ParcelMediaCommandEnum.Url: 9594 case ParcelMediaCommandEnum.Url:
9178 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9595 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9215,16 +9632,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9215 { 9632 {
9216 m_host.AddScriptLPS(1); 9633 m_host.AddScriptLPS(1);
9217 9634
9218 lock (m_host.TaskInventory) 9635 m_host.TaskInventory.LockItemsForRead(true);
9636 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9219 { 9637 {
9220 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9638 if (inv.Value.Name == name)
9221 { 9639 {
9222 if (inv.Value.Name == name) 9640 m_host.TaskInventory.LockItemsForRead(false);
9223 { 9641 return inv.Value.Type;
9224 return inv.Value.Type;
9225 }
9226 } 9642 }
9227 } 9643 }
9644 m_host.TaskInventory.LockItemsForRead(false);
9228 9645
9229 return -1; 9646 return -1;
9230 } 9647 }
@@ -9235,15 +9652,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9235 9652
9236 if (quick_pay_buttons.Data.Length < 4) 9653 if (quick_pay_buttons.Data.Length < 4)
9237 { 9654 {
9238 LSLError("List must have at least 4 elements"); 9655 int x;
9239 return; 9656 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9657 {
9658 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9659 }
9240 } 9660 }
9241 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9661 int[] nPrice = new int[5];
9242 9662 nPrice[0]=price;
9243 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9663 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9244 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9664 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9245 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9665 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9246 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9666 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9667 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9247 m_host.ParentGroup.HasGroupChanged = true; 9668 m_host.ParentGroup.HasGroupChanged = true;
9248 } 9669 }
9249 9670
@@ -9255,17 +9676,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9255 if (invItemID == UUID.Zero) 9676 if (invItemID == UUID.Zero)
9256 return new LSL_Vector(); 9677 return new LSL_Vector();
9257 9678
9258 lock (m_host.TaskInventory) 9679 m_host.TaskInventory.LockItemsForRead(true);
9680 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9259 { 9681 {
9260 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9682 m_host.TaskInventory.LockItemsForRead(false);
9261 return new LSL_Vector(); 9683 return new LSL_Vector();
9684 }
9262 9685
9263 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9686 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9264 { 9687 {
9265 ShoutError("No permissions to track the camera"); 9688 ShoutError("No permissions to track the camera");
9266 return new LSL_Vector(); 9689 m_host.TaskInventory.LockItemsForRead(false);
9267 } 9690 return new LSL_Vector();
9268 } 9691 }
9692 m_host.TaskInventory.LockItemsForRead(false);
9269 9693
9270 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9694 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9271 if (presence != null) 9695 if (presence != null)
@@ -9283,17 +9707,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9283 if (invItemID == UUID.Zero) 9707 if (invItemID == UUID.Zero)
9284 return new LSL_Rotation(); 9708 return new LSL_Rotation();
9285 9709
9286 lock (m_host.TaskInventory) 9710 m_host.TaskInventory.LockItemsForRead(true);
9711 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9287 { 9712 {
9288 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9713 m_host.TaskInventory.LockItemsForRead(false);
9289 return new LSL_Rotation(); 9714 return new LSL_Rotation();
9290 9715 }
9291 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9716 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9292 { 9717 {
9293 ShoutError("No permissions to track the camera"); 9718 ShoutError("No permissions to track the camera");
9294 return new LSL_Rotation(); 9719 m_host.TaskInventory.LockItemsForRead(false);
9295 } 9720 return new LSL_Rotation();
9296 } 9721 }
9722 m_host.TaskInventory.LockItemsForRead(false);
9297 9723
9298 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9724 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9299 if (presence != null) 9725 if (presence != null)
@@ -9355,8 +9781,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9355 { 9781 {
9356 m_host.AddScriptLPS(1); 9782 m_host.AddScriptLPS(1);
9357 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9783 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9358 if (detectedParams == null) return; // only works on the first detected avatar 9784 if (detectedParams == null)
9359 9785 {
9786 if (m_host.IsAttachment == true)
9787 {
9788 detectedParams = new DetectParams();
9789 detectedParams.Key = m_host.OwnerID;
9790 }
9791 else
9792 {
9793 return;
9794 }
9795 }
9796
9360 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9797 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9361 if (avatar != null) 9798 if (avatar != null)
9362 { 9799 {
@@ -9364,6 +9801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9364 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9801 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9365 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9802 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9366 } 9803 }
9804
9367 ScriptSleep(1000); 9805 ScriptSleep(1000);
9368 } 9806 }
9369 9807
@@ -9443,14 +9881,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9443 if (objectID == UUID.Zero) return; 9881 if (objectID == UUID.Zero) return;
9444 9882
9445 UUID agentID; 9883 UUID agentID;
9446 lock (m_host.TaskInventory) 9884 m_host.TaskInventory.LockItemsForRead(true);
9447 { 9885 // we need the permission first, to know which avatar we want to set the camera for
9448 // we need the permission first, to know which avatar we want to set the camera for 9886 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9449 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9450 9887
9451 if (agentID == UUID.Zero) return; 9888 if (agentID == UUID.Zero)
9452 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9889 {
9890 m_host.TaskInventory.LockItemsForRead(false);
9891 return;
9892 }
9893 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9894 {
9895 m_host.TaskInventory.LockItemsForRead(false);
9896 return;
9453 } 9897 }
9898 m_host.TaskInventory.LockItemsForRead(false);
9454 9899
9455 ScenePresence presence = World.GetScenePresence(agentID); 9900 ScenePresence presence = World.GetScenePresence(agentID);
9456 9901
@@ -9500,12 +9945,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9500 9945
9501 // we need the permission first, to know which avatar we want to clear the camera for 9946 // we need the permission first, to know which avatar we want to clear the camera for
9502 UUID agentID; 9947 UUID agentID;
9503 lock (m_host.TaskInventory) 9948 m_host.TaskInventory.LockItemsForRead(true);
9949 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9950 if (agentID == UUID.Zero)
9951 {
9952 m_host.TaskInventory.LockItemsForRead(false);
9953 return;
9954 }
9955 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9504 { 9956 {
9505 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9957 m_host.TaskInventory.LockItemsForRead(false);
9506 if (agentID == UUID.Zero) return; 9958 return;
9507 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9508 } 9959 }
9960 m_host.TaskInventory.LockItemsForRead(false);
9509 9961
9510 ScenePresence presence = World.GetScenePresence(agentID); 9962 ScenePresence presence = World.GetScenePresence(agentID);
9511 9963
@@ -9572,19 +10024,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10024 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9573 { 10025 {
9574 m_host.AddScriptLPS(1); 10026 m_host.AddScriptLPS(1);
9575 string ret = String.Empty; 10027
9576 string src1 = llBase64ToString(str1); 10028 if (str1 == String.Empty)
9577 string src2 = llBase64ToString(str2); 10029 return String.Empty;
9578 int c = 0; 10030 if (str2 == String.Empty)
9579 for (int i = 0; i < src1.Length; i++) 10031 return str1;
10032
10033 byte[] data1 = Convert.FromBase64String(str1);
10034 byte[] data2 = Convert.FromBase64String(str2);
10035
10036 byte[] d2 = new Byte[data1.Length];
10037 int pos = 0;
10038
10039 if (data1.Length <= data2.Length)
9580 { 10040 {
9581 ret += (char) (src1[i] ^ src2[c]); 10041 Array.Copy(data2, 0, d2, 0, data1.Length);
10042 }
10043 else
10044 {
10045 while (pos < data1.Length)
10046 {
10047 int len = data1.Length - pos;
10048 if (len > data2.Length)
10049 len = data2.Length;
9582 10050
9583 c++; 10051 Array.Copy(data2, 0, d2, pos, len);
9584 if (c >= src2.Length) 10052 pos += len;
9585 c = 0; 10053 }
9586 } 10054 }
9587 return llStringToBase64(ret); 10055
10056 for (pos = 0 ; pos < data1.Length ; pos++ )
10057 data1[pos] ^= d2[pos];
10058
10059 return Convert.ToBase64String(data1);
9588 } 10060 }
9589 10061
9590 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10062 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9962,15 +10434,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9962 10434
9963 internal UUID ScriptByName(string name) 10435 internal UUID ScriptByName(string name)
9964 { 10436 {
9965 lock (m_host.TaskInventory) 10437 m_host.TaskInventory.LockItemsForRead(true);
10438
10439 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9966 { 10440 {
9967 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10441 if (item.Type == 10 && item.Name == name)
9968 { 10442 {
9969 if (item.Type == 10 && item.Name == name) 10443 m_host.TaskInventory.LockItemsForRead(false);
9970 return item.ItemID; 10444 return item.ItemID;
9971 } 10445 }
9972 } 10446 }
9973 10447
10448 m_host.TaskInventory.LockItemsForRead(false);
10449
9974 return UUID.Zero; 10450 return UUID.Zero;
9975 } 10451 }
9976 10452
@@ -10011,6 +10487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10011 { 10487 {
10012 m_host.AddScriptLPS(1); 10488 m_host.AddScriptLPS(1);
10013 10489
10490 //Clone is thread safe
10014 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10491 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10015 10492
10016 UUID assetID = UUID.Zero; 10493 UUID assetID = UUID.Zero;
@@ -10073,6 +10550,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10073 { 10550 {
10074 m_host.AddScriptLPS(1); 10551 m_host.AddScriptLPS(1);
10075 10552
10553 //Clone is thread safe
10076 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10554 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10077 10555
10078 UUID assetID = UUID.Zero; 10556 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 5ae6439..fffe65c 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..80b021f 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)
@@ -2218,9 +2222,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2218 { 2222 {
2219 if (avatar.IsChildAgent == false) 2223 if (avatar.IsChildAgent == false)
2220 { 2224 {
2221 result.Add(avatar.UUID); 2225 result.Add(new LSL_Key(avatar.UUID.ToString()));
2222 result.Add(avatar.AbsolutePosition); 2226 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2223 result.Add(avatar.Name); 2227 result.Add(new LSL_String(avatar.Name));
2224 } 2228 }
2225 } 2229 }
2226 }); 2230 });
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_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..f14967e 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 6663aa5..b4da246 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 {