aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1737
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
14 files changed, 1243 insertions, 690 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 ed63aee..52d3285 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -73,7 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 /// </summary> 74 /// </summary>
74 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 75 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
75 { 76 {
76 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 protected IScriptEngine m_ScriptEngine; 78 protected IScriptEngine m_ScriptEngine;
78 protected SceneObjectPart m_host; 79 protected SceneObjectPart m_host;
79 protected uint m_localID; 80 protected uint m_localID;
@@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 get { return m_ScriptEngine.World; } 152 get { return m_ScriptEngine.World; }
152 } 153 }
153 154
155 [DebuggerNonUserCode]
154 public void state(string newState) 156 public void state(string newState)
155 { 157 {
156 m_ScriptEngine.SetState(m_itemID, newState); 158 m_ScriptEngine.SetState(m_itemID, newState);
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
160 /// Reset the named script. The script must be present 162 /// Reset the named script. The script must be present
161 /// in the same prim. 163 /// in the same prim.
162 /// </summary> 164 /// </summary>
165 [DebuggerNonUserCode]
163 public void llResetScript() 166 public void llResetScript()
164 { 167 {
165 m_host.AddScriptLPS(1); 168 m_host.AddScriptLPS(1);
@@ -216,9 +219,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
216 } 219 }
217 } 220 }
218 221
222 public List<ScenePresence> GetLinkAvatars(int linkType)
223 {
224 List<ScenePresence> ret = new List<ScenePresence>();
225 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
226 return ret;
227
228 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
229
230 switch (linkType)
231 {
232 case ScriptBaseClass.LINK_SET:
233 return avs;
234
235 case ScriptBaseClass.LINK_ROOT:
236 return ret;
237
238 case ScriptBaseClass.LINK_ALL_OTHERS:
239 return avs;
240
241 case ScriptBaseClass.LINK_ALL_CHILDREN:
242 return avs;
243
244 case ScriptBaseClass.LINK_THIS:
245 return ret;
246
247 default:
248 if (linkType < 0)
249 return ret;
250
251 int partCount = m_host.ParentGroup.GetPartCount();
252
253 if (linkType <= partCount)
254 {
255 return ret;
256 }
257 else
258 {
259 linkType = linkType - partCount;
260 if (linkType > avs.Count)
261 {
262 return ret;
263 }
264 else
265 {
266 ret.Add(avs[linkType-1]);
267 return ret;
268 }
269 }
270 }
271 }
272
219 public List<SceneObjectPart> GetLinkParts(int linkType) 273 public List<SceneObjectPart> GetLinkParts(int linkType)
220 { 274 {
221 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 275 List<SceneObjectPart> ret = new List<SceneObjectPart>();
276 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
277 return ret;
222 ret.Add(m_host); 278 ret.Add(m_host);
223 279
224 switch (linkType) 280 switch (linkType)
@@ -272,40 +328,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 328 protected UUID InventorySelf()
273 { 329 {
274 UUID invItemID = new UUID(); 330 UUID invItemID = new UUID();
275 331 bool unlock = false;
276 lock (m_host.TaskInventory) 332 if (!m_host.TaskInventory.IsReadLockedByMe())
333 {
334 m_host.TaskInventory.LockItemsForRead(true);
335 unlock = true;
336 }
337 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
277 { 338 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 339 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 340 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 341 invItemID = inv.Key;
281 { 342 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 343 }
286 } 344 }
287 345 if (unlock)
346 {
347 m_host.TaskInventory.LockItemsForRead(false);
348 }
288 return invItemID; 349 return invItemID;
289 } 350 }
290 351
291 protected UUID InventoryKey(string name, int type) 352 protected UUID InventoryKey(string name, int type)
292 { 353 {
293 m_host.AddScriptLPS(1); 354 m_host.AddScriptLPS(1);
294 355 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 356
357 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 358 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 359 if (inv.Value.Name == name)
298 { 360 {
299 if (inv.Value.Name == name) 361 m_host.TaskInventory.LockItemsForRead(false);
362
363 if (inv.Value.Type != type)
300 { 364 {
301 if (inv.Value.Type != type) 365 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 366 }
367
368 return inv.Value.AssetID;
306 } 369 }
307 } 370 }
308 371
372 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 373 return UUID.Zero;
310 } 374 }
311 375
@@ -313,17 +377,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 377 {
314 m_host.AddScriptLPS(1); 378 m_host.AddScriptLPS(1);
315 379
316 lock (m_host.TaskInventory) 380
381 m_host.TaskInventory.LockItemsForRead(true);
382
383 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 384 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 385 if (inv.Value.Name == name)
319 { 386 {
320 if (inv.Value.Name == name) 387 m_host.TaskInventory.LockItemsForRead(false);
321 { 388 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 389 }
325 } 390 }
326 391
392 m_host.TaskInventory.LockItemsForRead(false);
393
394
327 return UUID.Zero; 395 return UUID.Zero;
328 } 396 }
329 397
@@ -465,26 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 533
466 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
467 535
468 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 536 // Utility function for llRot2Euler
469 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
470 537
471 public LSL_Vector llRot2Euler(LSL_Rotation r) 538 // normalize an angle between -PI and PI (-180 to +180 degrees)
539 protected double NormalizeAngle(double angle)
540 {
541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
543
544 int numPis = (int)(Math.PI / angle);
545 double remainder = angle - Math.PI * numPis;
546 if (numPis % 2 == 1)
547 return Math.PI - angle;
548 return remainder;
549 }
550
551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
472 { 552 {
473 m_host.AddScriptLPS(1); 553 m_host.AddScriptLPS(1);
474 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 554 LSL_Vector eul = new LSL_Vector();
475 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 555
476 double m = (t.x + t.y + t.z + t.s); 556 double sqw = q1.s*q1.s;
477 if (m == 0) return new LSL_Vector(); 557 double sqx = q1.x*q1.x;
478 double n = 2 * (r.y * r.s + r.x * r.z); 558 double sqy = q1.z*q1.z;
479 double p = m * m - n * n; 559 double sqz = q1.y*q1.y;
480 if (p > 0) 560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
481 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 561 double test = q1.x*q1.z + q1.y*q1.s;
482 Math.Atan2(n, Math.Sqrt(p)), 562 if (test > 0.4999*unit) { // singularity at north pole
483 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
484 else if (n > 0) 564 eul.y = Math.PI/2;
485 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 565 eul.x = 0;
486 else 566 return eul;
487 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 567 }
568 if (test < -0.4999*unit) { // singularity at south pole
569 eul.z = -2 * Math.Atan2(q1.x,q1.s);
570 eul.y = -Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
488 } 578 }
489 579
490 /* From wiki: 580 /* From wiki:
@@ -686,77 +776,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
686 { 776 {
687 //A and B should both be normalized 777 //A and B should both be normalized
688 m_host.AddScriptLPS(1); 778 m_host.AddScriptLPS(1);
689 LSL_Rotation rotBetween; 779 /* This method is more accurate than the SL one, and thus causes problems
690 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 780 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
691 // continue calculation. 781
692 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 782 double dotProduct = LSL_Vector.Dot(a, b);
783 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
784 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
785 double angle = Math.Acos(dotProduct / magProduct);
786 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
787 double s = Math.Sin(angle / 2);
788
789 double x = axis.x * s;
790 double y = axis.y * s;
791 double z = axis.z * s;
792 double w = Math.Cos(angle / 2);
793
794 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
795 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
796
797 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
798 */
799
800 // This method mimics the 180 errors found in SL
801 // See www.euclideanspace.com... angleBetween
802 LSL_Vector vec_a = a;
803 LSL_Vector vec_b = b;
804
805 // Eliminate zero length
806 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
807 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
808 if (vec_a_mag < 0.00001 ||
809 vec_b_mag < 0.00001)
693 { 810 {
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
695 } 812 }
696 else 813
814 // Normalize
815 vec_a = llVecNorm(vec_a);
816 vec_b = llVecNorm(vec_b);
817
818 // Calculate axis and rotation angle
819 LSL_Vector axis = vec_a % vec_b;
820 LSL_Float cos_theta = vec_a * vec_b;
821
822 // Check if parallel
823 if (cos_theta > 0.99999)
697 { 824 {
698 a = LSL_Vector.Norm(a); 825 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
699 b = LSL_Vector.Norm(b); 826 }
700 double dotProduct = LSL_Vector.Dot(a, b); 827
701 // There are two degenerate cases possible. These are for vectors 180 or 828 // Check if anti-parallel
702 // 0 degrees apart. These have to be detected and handled individually. 829 else if (cos_theta < -0.99999)
703 // 830 {
704 // Check for vectors 180 degrees apart. 831 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
705 // A dot product of -1 would mean the angle between vectors is 180 degrees. 832 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
706 if (dotProduct < -0.9999999f) 833 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
707 { 834 }
708 // First assume X axis is orthogonal to the vectors. 835 else // other rotation
709 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 836 {
710 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 837 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
711 // Check for near zero vector. A very small non-zero number here will create 838 axis = llVecNorm(axis);
712 // a rotation in an undesired direction. 839 double x, y, z, s, t;
713 if (LSL_Vector.Mag(orthoVector) > 0.0001) 840 s = Math.Cos(theta);
714 { 841 t = Math.Sin(theta);
715 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 842 x = axis.x * t;
716 } 843 y = axis.y * t;
717 // If the magnitude of the vector was near zero, then assume the X axis is not 844 z = axis.z * t;
718 // orthogonal and use the Z axis instead. 845 return new LSL_Rotation(x,y,z,s);
719 else
720 {
721 // Set 180 z rotation.
722 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
723 }
724 }
725 // Check for parallel vectors.
726 // A dot product of 1 would mean the angle between vectors is 0 degrees.
727 else if (dotProduct > 0.9999999f)
728 {
729 // Set zero rotation.
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 else
733 {
734 // All special checks have been performed so get the axis of rotation.
735 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
736 // Quarternion s value is the length of the unit vector + dot product.
737 double qs = 1.0 + dotProduct;
738 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
739 // Normalize the rotation.
740 double mag = LSL_Rotation.Mag(rotBetween);
741 // We shouldn't have to worry about a divide by zero here. The qs value will be
742 // non-zero because we already know if we're here, then the dotProduct is not -1 so
743 // qs will not be zero. Also, we've already handled the input vectors being zero so the
744 // crossProduct vector should also not be zero.
745 rotBetween.x = rotBetween.x / mag;
746 rotBetween.y = rotBetween.y / mag;
747 rotBetween.z = rotBetween.z / mag;
748 rotBetween.s = rotBetween.s / mag;
749 // Check for undefined values and set zero rotation if any found. This code might not actually be required
750 // any longer since zero vectors are checked for at the top.
751 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
752 {
753 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
754 }
755 }
756 } 846 }
757 return rotBetween;
758 } 847 }
759 848
760 public void llWhisper(int channelID, string text) 849 public void llWhisper(int channelID, string text)
761 { 850 {
762 m_host.AddScriptLPS(1); 851 m_host.AddScriptLPS(1);
@@ -1080,10 +1169,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1169 return detectedParams.TouchUV;
1081 } 1170 }
1082 1171
1172 [DebuggerNonUserCode]
1083 public virtual void llDie() 1173 public virtual void llDie()
1084 { 1174 {
1085 m_host.AddScriptLPS(1); 1175 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1176 if (!m_host.IsAttachment) throw new SelfDeleteException();
1087 } 1177 }
1088 1178
1089 public LSL_Float llGround(LSL_Vector offset) 1179 public LSL_Float llGround(LSL_Vector offset)
@@ -1156,6 +1246,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 1246
1157 public void llSetStatus(int status, int value) 1247 public void llSetStatus(int status, int value)
1158 { 1248 {
1249 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1250 return;
1159 m_host.AddScriptLPS(1); 1251 m_host.AddScriptLPS(1);
1160 1252
1161 int statusrotationaxis = 0; 1253 int statusrotationaxis = 0;
@@ -1385,6 +1477,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1477 {
1386 m_host.AddScriptLPS(1); 1478 m_host.AddScriptLPS(1);
1387 1479
1480 SetColor(m_host, color, face);
1481 }
1482
1483 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1484 {
1485 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1486 return;
1487
1488 Primitive.TextureEntry tex = part.Shape.Textures;
1489 Color4 texcolor;
1490 if (face >= 0 && face < GetNumberOfSides(part))
1491 {
1492 texcolor = tex.CreateFace((uint)face).RGBA;
1493 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1494 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1495 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1496 tex.FaceTextures[face].RGBA = texcolor;
1497 part.UpdateTexture(tex);
1498 return;
1499 }
1500 else if (face == ScriptBaseClass.ALL_SIDES)
1501 {
1502 for (uint i = 0; i < GetNumberOfSides(part); i++)
1503 {
1504 if (tex.FaceTextures[i] != null)
1505 {
1506 texcolor = tex.FaceTextures[i].RGBA;
1507 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1508 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1509 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1510 tex.FaceTextures[i].RGBA = texcolor;
1511 }
1512 texcolor = tex.DefaultTexture.RGBA;
1513 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1514 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1515 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1516 tex.DefaultTexture.RGBA = texcolor;
1517 }
1518 part.UpdateTexture(tex);
1519 return;
1520 }
1521
1388 if (face == ScriptBaseClass.ALL_SIDES) 1522 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1523 face = SceneObjectPart.ALL_SIDES;
1390 1524
@@ -1393,6 +1527,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1527
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1528 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1529 {
1530 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1531 return;
1532
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1533 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1534 MappingType textype;
1398 textype = MappingType.Default; 1535 textype = MappingType.Default;
@@ -1423,6 +1560,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1560
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1561 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1562 {
1563 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1564 return;
1565
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1566 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1567 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1568 {
@@ -1448,6 +1588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1588
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1589 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1590 {
1591 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1592 return;
1451 1593
1452 Shininess sval = new Shininess(); 1594 Shininess sval = new Shininess();
1453 1595
@@ -1498,6 +1640,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1640
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1641 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1642 {
1643 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return;
1645
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1646 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1647 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1648 {
@@ -1558,13 +1703,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1703 m_host.AddScriptLPS(1);
1559 1704
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1705 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1706 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1707 {
1563 SetAlpha(part, alpha, face); 1708 try
1709 {
1710 parts[0].ParentGroup.areUpdatesSuspended = true;
1711 foreach (SceneObjectPart part in parts)
1712 SetAlpha(part, alpha, face);
1713 }
1714 finally
1715 {
1716 parts[0].ParentGroup.areUpdatesSuspended = false;
1717 }
1718 }
1564 } 1719 }
1565 1720
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1721 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1722 {
1723 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1724 return;
1725
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1726 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1727 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1728 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1610,7 +1768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1610 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1768 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1611 float wind, float tension, LSL_Vector Force) 1769 float wind, float tension, LSL_Vector Force)
1612 { 1770 {
1613 if (part == null) 1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1614 return; 1772 return;
1615 1773
1616 if (flexi) 1774 if (flexi)
@@ -1645,7 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1803 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1804 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1805 {
1648 if (part == null) 1806 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1807 return;
1650 1808
1651 if (light) 1809 if (light)
@@ -1722,15 +1880,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 m_host.AddScriptLPS(1); 1880 m_host.AddScriptLPS(1);
1723 1881
1724 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1882 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1725 1883 if (parts.Count > 0)
1726 foreach (SceneObjectPart part in parts) 1884 {
1727 SetTexture(part, texture, face); 1885 try
1728 1886 {
1887 parts[0].ParentGroup.areUpdatesSuspended = true;
1888 foreach (SceneObjectPart part in parts)
1889 SetTexture(part, texture, face);
1890 }
1891 finally
1892 {
1893 parts[0].ParentGroup.areUpdatesSuspended = false;
1894 }
1895 }
1729 ScriptSleep(200); 1896 ScriptSleep(200);
1730 } 1897 }
1731 1898
1732 protected void SetTexture(SceneObjectPart part, string texture, int face) 1899 protected void SetTexture(SceneObjectPart part, string texture, int face)
1733 { 1900 {
1901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1902 return;
1903
1734 UUID textureID=new UUID(); 1904 UUID textureID=new UUID();
1735 1905
1736 if (!UUID.TryParse(texture, out textureID)) 1906 if (!UUID.TryParse(texture, out textureID))
@@ -1776,6 +1946,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1776 1946
1777 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1778 { 1948 {
1949 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1950 return;
1951
1779 Primitive.TextureEntry tex = part.Shape.Textures; 1952 Primitive.TextureEntry tex = part.Shape.Textures;
1780 if (face >= 0 && face < GetNumberOfSides(part)) 1953 if (face >= 0 && face < GetNumberOfSides(part))
1781 { 1954 {
@@ -1812,6 +1985,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1812 1985
1813 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1986 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1814 { 1987 {
1988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1989 return;
1990
1815 Primitive.TextureEntry tex = part.Shape.Textures; 1991 Primitive.TextureEntry tex = part.Shape.Textures;
1816 if (face >= 0 && face < GetNumberOfSides(part)) 1992 if (face >= 0 && face < GetNumberOfSides(part))
1817 { 1993 {
@@ -1848,6 +2024,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 2024
1849 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2025 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1850 { 2026 {
2027 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2028 return;
2029
1851 Primitive.TextureEntry tex = part.Shape.Textures; 2030 Primitive.TextureEntry tex = part.Shape.Textures;
1852 if (face >= 0 && face < GetNumberOfSides(part)) 2031 if (face >= 0 && face < GetNumberOfSides(part))
1853 { 2032 {
@@ -1918,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1918 2097
1919 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2098 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1920 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1921 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2103 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1922 LSL_Vector currentPos = llGetLocalPos(); 2104 LSL_Vector currentPos = llGetLocalPos();
1923 2105
@@ -1952,6 +2134,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1952 public LSL_Vector llGetLocalPos() 2134 public LSL_Vector llGetLocalPos()
1953 { 2135 {
1954 m_host.AddScriptLPS(1); 2136 m_host.AddScriptLPS(1);
2137 if (m_host.IsAttachment == true) {
2138 if (m_host.IsRoot == true)
2139 {
2140 return new LSL_Vector(m_host.AbsolutePosition.X,
2141 m_host.AbsolutePosition.Y,
2142 m_host.AbsolutePosition.Z);
2143
2144 }
2145 else
2146 {
2147 return new LSL_Vector(m_host.OffsetPosition.X,
2148 m_host.OffsetPosition.Y,
2149 m_host.OffsetPosition.Z);
2150 }
2151 }
2152
1955 if (m_host.ParentID != 0) 2153 if (m_host.ParentID != 0)
1956 { 2154 {
1957 return new LSL_Vector(m_host.OffsetPosition.X, 2155 return new LSL_Vector(m_host.OffsetPosition.X,
@@ -2002,6 +2200,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 2200
2003 protected void SetRot(SceneObjectPart part, Quaternion rot) 2201 protected void SetRot(SceneObjectPart part, Quaternion rot)
2004 { 2202 {
2203 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2204 return;
2205
2005 part.UpdateRotation(rot); 2206 part.UpdateRotation(rot);
2006 // Update rotation does not move the object in the physics scene if it's a linkset. 2207 // Update rotation does not move the object in the physics scene if it's a linkset.
2007 2208
@@ -2621,12 +2822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2621 2822
2622 m_host.AddScriptLPS(1); 2823 m_host.AddScriptLPS(1);
2623 2824
2825 m_host.TaskInventory.LockItemsForRead(true);
2624 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2826 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2625 2827 m_host.TaskInventory.LockItemsForRead(false);
2626 lock (m_host.TaskInventory)
2627 {
2628 item = m_host.TaskInventory[invItemID];
2629 }
2630 2828
2631 if (item.PermsGranter == UUID.Zero) 2829 if (item.PermsGranter == UUID.Zero)
2632 return 0; 2830 return 0;
@@ -2701,6 +2899,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2701 if (dist > m_ScriptDistanceFactor * 10.0f) 2899 if (dist > m_ScriptDistanceFactor * 10.0f)
2702 return; 2900 return;
2703 2901
2902 //Clone is thread-safe
2704 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2903 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2705 2904
2706 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2905 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2763,6 +2962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2763 2962
2764 public void llLookAt(LSL_Vector target, double strength, double damping) 2963 public void llLookAt(LSL_Vector target, double strength, double damping)
2765 { 2964 {
2965 /*
2766 m_host.AddScriptLPS(1); 2966 m_host.AddScriptLPS(1);
2767 // Determine where we are looking from 2967 // Determine where we are looking from
2768 LSL_Vector from = llGetPos(); 2968 LSL_Vector from = llGetPos();
@@ -2782,10 +2982,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2782 // the angles of rotation in radians into rotation value 2982 // the angles of rotation in radians into rotation value
2783 2983
2784 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2984 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2785 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2985
2786 m_host.startLookAt(rotation, (float)damping, (float)strength); 2986 // This would only work if your physics system contains an APID controller:
2987 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2988 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2989
2787 // Orient the object to the angle calculated 2990 // Orient the object to the angle calculated
2788 //llSetRot(rot); 2991 llSetRot(rot);
2992 */
2993
2994 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2995 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2996 // http://bugs.meta7.com/view.php?id=28
2997 // - Tom
2998
2999 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3000 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3001
3002 }
3003
3004 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3005 {
3006 m_host.AddScriptLPS(1);
3007// NotImplemented("llRotLookAt");
3008 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3009
2789 } 3010 }
2790 3011
2791 public void llStopLookAt() 3012 public void llStopLookAt()
@@ -2834,13 +3055,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2834 { 3055 {
2835 TaskInventoryItem item; 3056 TaskInventoryItem item;
2836 3057
2837 lock (m_host.TaskInventory) 3058 m_host.TaskInventory.LockItemsForRead(true);
3059 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2838 { 3060 {
2839 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3061 m_host.TaskInventory.LockItemsForRead(false);
2840 return; 3062 return;
2841 else
2842 item = m_host.TaskInventory[InventorySelf()];
2843 } 3063 }
3064 else
3065 {
3066 item = m_host.TaskInventory[InventorySelf()];
3067 }
3068 m_host.TaskInventory.LockItemsForRead(false);
2844 3069
2845 if (item.PermsGranter != UUID.Zero) 3070 if (item.PermsGranter != UUID.Zero)
2846 { 3071 {
@@ -2862,13 +3087,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2862 { 3087 {
2863 TaskInventoryItem item; 3088 TaskInventoryItem item;
2864 3089
3090 m_host.TaskInventory.LockItemsForRead(true);
2865 lock (m_host.TaskInventory) 3091 lock (m_host.TaskInventory)
2866 { 3092 {
3093
2867 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3094 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3095 {
3096 m_host.TaskInventory.LockItemsForRead(false);
2868 return; 3097 return;
3098 }
2869 else 3099 else
3100 {
2870 item = m_host.TaskInventory[InventorySelf()]; 3101 item = m_host.TaskInventory[InventorySelf()];
3102 }
2871 } 3103 }
3104 m_host.TaskInventory.LockItemsForRead(false);
2872 3105
2873 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
2874 3107
@@ -2900,19 +3133,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2900 { 3133 {
2901 m_host.AddScriptLPS(1); 3134 m_host.AddScriptLPS(1);
2902 3135
2903 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2904 return;
2905
2906 TaskInventoryItem item; 3136 TaskInventoryItem item;
2907 3137
2908 lock (m_host.TaskInventory) 3138 m_host.TaskInventory.LockItemsForRead(true);
3139
3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2909 { 3141 {
2910 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3142 m_host.TaskInventory.LockItemsForRead(false);
2911 return; 3143 return;
2912 else 3144 }
2913 item = m_host.TaskInventory[InventorySelf()]; 3145 else
3146 {
3147 item = m_host.TaskInventory[InventorySelf()];
2914 } 3148 }
2915 3149
3150 m_host.TaskInventory.LockItemsForRead(false);
3151
2916 if (item.PermsGranter != m_host.OwnerID) 3152 if (item.PermsGranter != m_host.OwnerID)
2917 return; 3153 return;
2918 3154
@@ -2922,10 +3158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 3158
2923 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3159 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2924 3160
2925 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3161 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2926 if (attachmentsModule != null)
2927 attachmentsModule.AttachObject(presence.ControllingClient,
2928 grp, (uint)attachment, false);
2929 } 3162 }
2930 } 3163 }
2931 3164
@@ -2938,13 +3171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 3171
2939 TaskInventoryItem item; 3172 TaskInventoryItem item;
2940 3173
2941 lock (m_host.TaskInventory) 3174 m_host.TaskInventory.LockItemsForRead(true);
3175
3176 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2942 { 3177 {
2943 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3178 m_host.TaskInventory.LockItemsForRead(false);
2944 return; 3179 return;
2945 else 3180 }
2946 item = m_host.TaskInventory[InventorySelf()]; 3181 else
3182 {
3183 item = m_host.TaskInventory[InventorySelf()];
2947 } 3184 }
3185 m_host.TaskInventory.LockItemsForRead(false);
3186
2948 3187
2949 if (item.PermsGranter != m_host.OwnerID) 3188 if (item.PermsGranter != m_host.OwnerID)
2950 return; 3189 return;
@@ -2981,8 +3220,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 return m_host.OwnerID.ToString(); 3220 return m_host.OwnerID.ToString();
2982 } 3221 }
2983 3222
3223 [DebuggerNonUserCode]
2984 public void llInstantMessage(string user, string message) 3224 public void llInstantMessage(string user, string message)
2985 { 3225 {
3226 UUID result;
3227 if (!UUID.TryParse(user, out result))
3228 {
3229 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3230 return;
3231 }
3232
3233
2986 m_host.AddScriptLPS(1); 3234 m_host.AddScriptLPS(1);
2987 3235
2988 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3236 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2997,14 +3245,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 UUID friendTransactionID = UUID.Random(); 3245 UUID friendTransactionID = UUID.Random();
2998 3246
2999 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3247 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3000 3248
3001 GridInstantMessage msg = new GridInstantMessage(); 3249 GridInstantMessage msg = new GridInstantMessage();
3002 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3250 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3003 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3251 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3004 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3252 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3005// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3253// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3006// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3254// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3007 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3255 DateTime dt = DateTime.UtcNow;
3256
3257 // Ticks from UtcNow, but make it look like local. Evil, huh?
3258 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3259
3260 try
3261 {
3262 // Convert that to the PST timezone
3263 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3264 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3265 }
3266 catch
3267 {
3268 // No logging here, as it could be VERY spammy
3269 }
3270
3271 // And make it look local again to fool the unix time util
3272 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3273
3274 msg.timestamp = (uint)Util.ToUnixTime(dt);
3275
3008 //if (client != null) 3276 //if (client != null)
3009 //{ 3277 //{
3010 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3278 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3018,13 +3286,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3018 msg.message = message.Substring(0, 1024); 3286 msg.message = message.Substring(0, 1024);
3019 else 3287 else
3020 msg.message = message; 3288 msg.message = message;
3021 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3289 msg.dialog = (byte)19; // MessageFromObject
3022 msg.fromGroup = false;// fromGroup; 3290 msg.fromGroup = false;// fromGroup;
3023 msg.offline = (byte)0; //offline; 3291 msg.offline = (byte)0; //offline;
3024 msg.ParentEstateID = 0; //ParentEstateID; 3292 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3025 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3293 msg.Position = new Vector3(m_host.AbsolutePosition);
3026 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3294 msg.RegionID = World.RegionInfo.RegionID.Guid;
3027 msg.binaryBucket = new byte[0];// binaryBucket; 3295 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3028 3296
3029 if (m_TransferModule != null) 3297 if (m_TransferModule != null)
3030 { 3298 {
@@ -3044,7 +3312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3044 } 3312 }
3045 3313
3046 emailModule.SendEmail(m_host.UUID, address, subject, message); 3314 emailModule.SendEmail(m_host.UUID, address, subject, message);
3047 ScriptSleep(20000); 3315 ScriptSleep(15000);
3048 } 3316 }
3049 3317
3050 public void llGetNextEmail(string address, string subject) 3318 public void llGetNextEmail(string address, string subject)
@@ -3146,13 +3414,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3146 m_host.AddScriptLPS(1); 3414 m_host.AddScriptLPS(1);
3147 } 3415 }
3148 3416
3149 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3150 {
3151 m_host.AddScriptLPS(1);
3152 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3153 m_host.RotLookAt(rot, (float)strength, (float)damping);
3154 }
3155
3156 public LSL_Integer llStringLength(string str) 3417 public LSL_Integer llStringLength(string str)
3157 { 3418 {
3158 m_host.AddScriptLPS(1); 3419 m_host.AddScriptLPS(1);
@@ -3176,14 +3437,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3176 3437
3177 TaskInventoryItem item; 3438 TaskInventoryItem item;
3178 3439
3179 lock (m_host.TaskInventory) 3440 m_host.TaskInventory.LockItemsForRead(true);
3441 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3180 { 3442 {
3181 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3443 m_host.TaskInventory.LockItemsForRead(false);
3182 return; 3444 return;
3183 else
3184 item = m_host.TaskInventory[InventorySelf()];
3185 } 3445 }
3186 3446 else
3447 {
3448 item = m_host.TaskInventory[InventorySelf()];
3449 }
3450 m_host.TaskInventory.LockItemsForRead(false);
3187 if (item.PermsGranter == UUID.Zero) 3451 if (item.PermsGranter == UUID.Zero)
3188 return; 3452 return;
3189 3453
@@ -3213,13 +3477,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3213 3477
3214 TaskInventoryItem item; 3478 TaskInventoryItem item;
3215 3479
3216 lock (m_host.TaskInventory) 3480 m_host.TaskInventory.LockItemsForRead(true);
3481 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3217 { 3482 {
3218 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3483 m_host.TaskInventory.LockItemsForRead(false);
3219 return; 3484 return;
3220 else 3485 }
3221 item = m_host.TaskInventory[InventorySelf()]; 3486 else
3487 {
3488 item = m_host.TaskInventory[InventorySelf()];
3222 } 3489 }
3490 m_host.TaskInventory.LockItemsForRead(false);
3491
3223 3492
3224 if (item.PermsGranter == UUID.Zero) 3493 if (item.PermsGranter == UUID.Zero)
3225 return; 3494 return;
@@ -3290,10 +3559,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3290 3559
3291 TaskInventoryItem item; 3560 TaskInventoryItem item;
3292 3561
3293 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
3294 { 3570 {
3295 item = m_host.TaskInventory[invItemID]; 3571 item = m_host.TaskInventory[invItemID];
3296 } 3572 }
3573 m_host.TaskInventory.LockItemsForRead(false);
3297 3574
3298 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3575 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3299 { 3576 {
@@ -3325,11 +3602,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3325 3602
3326 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3603 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3327 { 3604 {
3328 lock (m_host.TaskInventory) 3605 m_host.TaskInventory.LockItemsForWrite(true);
3329 { 3606 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3330 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3607 m_host.TaskInventory[invItemID].PermsMask = perm;
3331 m_host.TaskInventory[invItemID].PermsMask = perm; 3608 m_host.TaskInventory.LockItemsForWrite(false);
3332 }
3333 3609
3334 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3610 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3335 "run_time_permissions", new Object[] { 3611 "run_time_permissions", new Object[] {
@@ -3349,11 +3625,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3349 3625
3350 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3626 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3351 { 3627 {
3352 lock (m_host.TaskInventory) 3628 m_host.TaskInventory.LockItemsForWrite(true);
3353 { 3629 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3354 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3630 m_host.TaskInventory[invItemID].PermsMask = perm;
3355 m_host.TaskInventory[invItemID].PermsMask = perm; 3631 m_host.TaskInventory.LockItemsForWrite(false);
3356 }
3357 3632
3358 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3633 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3359 "run_time_permissions", new Object[] { 3634 "run_time_permissions", new Object[] {
@@ -3374,11 +3649,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3374 3649
3375 if (!m_waitingForScriptAnswer) 3650 if (!m_waitingForScriptAnswer)
3376 { 3651 {
3377 lock (m_host.TaskInventory) 3652 m_host.TaskInventory.LockItemsForWrite(true);
3378 { 3653 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3379 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3654 m_host.TaskInventory[invItemID].PermsMask = 0;
3380 m_host.TaskInventory[invItemID].PermsMask = 0; 3655 m_host.TaskInventory.LockItemsForWrite(false);
3381 }
3382 3656
3383 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3657 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3384 m_waitingForScriptAnswer=true; 3658 m_waitingForScriptAnswer=true;
@@ -3413,10 +3687,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3413 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3687 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3414 llReleaseControls(); 3688 llReleaseControls();
3415 3689
3416 lock (m_host.TaskInventory) 3690
3417 { 3691 m_host.TaskInventory.LockItemsForWrite(true);
3418 m_host.TaskInventory[invItemID].PermsMask = answer; 3692 m_host.TaskInventory[invItemID].PermsMask = answer;
3419 } 3693 m_host.TaskInventory.LockItemsForWrite(false);
3694
3420 3695
3421 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3696 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3422 "run_time_permissions", new Object[] { 3697 "run_time_permissions", new Object[] {
@@ -3428,16 +3703,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3428 { 3703 {
3429 m_host.AddScriptLPS(1); 3704 m_host.AddScriptLPS(1);
3430 3705
3431 lock (m_host.TaskInventory) 3706 m_host.TaskInventory.LockItemsForRead(true);
3707
3708 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3432 { 3709 {
3433 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3710 if (item.Type == 10 && item.ItemID == m_itemID)
3434 { 3711 {
3435 if (item.Type == 10 && item.ItemID == m_itemID) 3712 m_host.TaskInventory.LockItemsForRead(false);
3436 { 3713 return item.PermsGranter.ToString();
3437 return item.PermsGranter.ToString();
3438 }
3439 } 3714 }
3440 } 3715 }
3716 m_host.TaskInventory.LockItemsForRead(false);
3441 3717
3442 return UUID.Zero.ToString(); 3718 return UUID.Zero.ToString();
3443 } 3719 }
@@ -3446,19 +3722,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 { 3722 {
3447 m_host.AddScriptLPS(1); 3723 m_host.AddScriptLPS(1);
3448 3724
3449 lock (m_host.TaskInventory) 3725 m_host.TaskInventory.LockItemsForRead(true);
3726
3727 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3450 { 3728 {
3451 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3729 if (item.Type == 10 && item.ItemID == m_itemID)
3452 { 3730 {
3453 if (item.Type == 10 && item.ItemID == m_itemID) 3731 int perms = item.PermsMask;
3454 { 3732 if (m_automaticLinkPermission)
3455 int perms = item.PermsMask; 3733 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3456 if (m_automaticLinkPermission) 3734 m_host.TaskInventory.LockItemsForRead(false);
3457 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3735 return perms;
3458 return perms;
3459 }
3460 } 3736 }
3461 } 3737 }
3738 m_host.TaskInventory.LockItemsForRead(false);
3462 3739
3463 return 0; 3740 return 0;
3464 } 3741 }
@@ -3480,9 +3757,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3480 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3757 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3481 { 3758 {
3482 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3759 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3483 3760 if (parts.Count > 0)
3484 foreach (SceneObjectPart part in parts) 3761 {
3485 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 }
3486 } 3773 }
3487 3774
3488 public void llCreateLink(string target, int parent) 3775 public void llCreateLink(string target, int parent)
@@ -3491,11 +3778,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3491 UUID invItemID = InventorySelf(); 3778 UUID invItemID = InventorySelf();
3492 3779
3493 TaskInventoryItem item; 3780 TaskInventoryItem item;
3494 lock (m_host.TaskInventory) 3781 m_host.TaskInventory.LockItemsForRead(true);
3495 { 3782 item = m_host.TaskInventory[invItemID];
3496 item = m_host.TaskInventory[invItemID]; 3783 m_host.TaskInventory.LockItemsForRead(false);
3497 } 3784
3498
3499 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3785 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3500 && !m_automaticLinkPermission) 3786 && !m_automaticLinkPermission)
3501 { 3787 {
@@ -3548,16 +3834,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3548 m_host.AddScriptLPS(1); 3834 m_host.AddScriptLPS(1);
3549 UUID invItemID = InventorySelf(); 3835 UUID invItemID = InventorySelf();
3550 3836
3551 lock (m_host.TaskInventory) 3837 m_host.TaskInventory.LockItemsForRead(true);
3552 {
3553 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3838 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3554 && !m_automaticLinkPermission) 3839 && !m_automaticLinkPermission)
3555 { 3840 {
3556 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);
3557 return; 3843 return;
3558 } 3844 }
3559 } 3845 m_host.TaskInventory.LockItemsForRead(false);
3560 3846
3561 if (linknum < ScriptBaseClass.LINK_THIS) 3847 if (linknum < ScriptBaseClass.LINK_THIS)
3562 return; 3848 return;
3563 3849
@@ -3596,10 +3882,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3596 // Restructuring Multiple Prims. 3882 // Restructuring Multiple Prims.
3597 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3883 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3598 parts.Remove(parentPrim.RootPart); 3884 parts.Remove(parentPrim.RootPart);
3599 foreach (SceneObjectPart part in parts) 3885 if (parts.Count > 0)
3600 { 3886 {
3601 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 }
3602 } 3899 }
3900
3603 parentPrim.HasGroupChanged = true; 3901 parentPrim.HasGroupChanged = true;
3604 parentPrim.ScheduleGroupForFullUpdate(); 3902 parentPrim.ScheduleGroupForFullUpdate();
3605 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3903 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3608,11 +3906,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3608 { 3906 {
3609 SceneObjectPart newRoot = parts[0]; 3907 SceneObjectPart newRoot = parts[0];
3610 parts.Remove(newRoot); 3908 parts.Remove(newRoot);
3611 foreach (SceneObjectPart part in parts) 3909
3910 try
3612 { 3911 {
3613 part.UpdateFlag = 0; 3912 parts[0].ParentGroup.areUpdatesSuspended = true;
3614 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3913 foreach (SceneObjectPart part in parts)
3914 {
3915 part.UpdateFlag = 0;
3916 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3917 }
3615 } 3918 }
3919 finally
3920 {
3921 parts[0].ParentGroup.areUpdatesSuspended = false;
3922 }
3923
3924
3616 newRoot.ParentGroup.HasGroupChanged = true; 3925 newRoot.ParentGroup.HasGroupChanged = true;
3617 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3926 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3618 } 3927 }
@@ -3638,11 +3947,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3638 3947
3639 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3948 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3640 parts.Remove(parentPrim.RootPart); 3949 parts.Remove(parentPrim.RootPart);
3641 3950 if (parts.Count > 0)
3642 foreach (SceneObjectPart part in parts)
3643 { 3951 {
3644 parentPrim.DelinkFromGroup(part.LocalId, true); 3952 try
3645 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 }
3646 } 3965 }
3647 parentPrim.HasGroupChanged = true; 3966 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 3967 parentPrim.ScheduleGroupForFullUpdate();
@@ -3734,17 +4053,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3734 m_host.AddScriptLPS(1); 4053 m_host.AddScriptLPS(1);
3735 int count = 0; 4054 int count = 0;
3736 4055
3737 lock (m_host.TaskInventory) 4056 m_host.TaskInventory.LockItemsForRead(true);
4057 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3738 { 4058 {
3739 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4059 if (inv.Value.Type == type || type == -1)
3740 { 4060 {
3741 if (inv.Value.Type == type || type == -1) 4061 count = count + 1;
3742 {
3743 count = count + 1;
3744 }
3745 } 4062 }
3746 } 4063 }
3747 4064
4065 m_host.TaskInventory.LockItemsForRead(false);
3748 return count; 4066 return count;
3749 } 4067 }
3750 4068
@@ -3753,16 +4071,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3753 m_host.AddScriptLPS(1); 4071 m_host.AddScriptLPS(1);
3754 ArrayList keys = new ArrayList(); 4072 ArrayList keys = new ArrayList();
3755 4073
3756 lock (m_host.TaskInventory) 4074 m_host.TaskInventory.LockItemsForRead(true);
4075 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3757 { 4076 {
3758 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4077 if (inv.Value.Type == type || type == -1)
3759 { 4078 {
3760 if (inv.Value.Type == type || type == -1) 4079 keys.Add(inv.Value.Name);
3761 {
3762 keys.Add(inv.Value.Name);
3763 }
3764 } 4080 }
3765 } 4081 }
4082 m_host.TaskInventory.LockItemsForRead(false);
3766 4083
3767 if (keys.Count == 0) 4084 if (keys.Count == 0)
3768 { 4085 {
@@ -3799,20 +4116,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3799 } 4116 }
3800 4117
3801 // move the first object found with this inventory name 4118 // move the first object found with this inventory name
3802 lock (m_host.TaskInventory) 4119 m_host.TaskInventory.LockItemsForRead(true);
4120 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3803 { 4121 {
3804 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4122 if (inv.Value.Name == inventory)
3805 { 4123 {
3806 if (inv.Value.Name == inventory) 4124 found = true;
3807 { 4125 objId = inv.Key;
3808 found = true; 4126 assetType = inv.Value.Type;
3809 objId = inv.Key; 4127 objName = inv.Value.Name;
3810 assetType = inv.Value.Type; 4128 break;
3811 objName = inv.Value.Name;
3812 break;
3813 }
3814 } 4129 }
3815 } 4130 }
4131 m_host.TaskInventory.LockItemsForRead(false);
3816 4132
3817 if (!found) 4133 if (!found)
3818 { 4134 {
@@ -3820,9 +4136,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3820 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));
3821 } 4137 }
3822 4138
3823 // check if destination is an avatar 4139 // check if destination is an object
3824 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
3825 { 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
3826 // destination is an avatar 4163 // destination is an avatar
3827 InventoryItemBase agentItem = 4164 InventoryItemBase agentItem =
3828 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4165 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
@@ -3832,7 +4169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3832 4169
3833 byte[] bucket = new byte[17]; 4170 byte[] bucket = new byte[17];
3834 bucket[0] = (byte)assetType; 4171 bucket[0] = (byte)assetType;
3835 byte[] objBytes = objId.GetBytes(); 4172 byte[] objBytes = agentItem.ID.GetBytes();
3836 Array.Copy(objBytes, 0, bucket, 1, 16); 4173 Array.Copy(objBytes, 0, bucket, 1, 16);
3837 4174
3838 Console.WriteLine("Giving inventory"); 4175 Console.WriteLine("Giving inventory");
@@ -3848,33 +4185,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3848 4185
3849 if (m_TransferModule != null) 4186 if (m_TransferModule != null)
3850 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);
3851 } 4191 }
3852 else
3853 {
3854 // destination is an object
3855 World.MoveTaskInventoryItem(destId, m_host, objId);
3856 }
3857 ScriptSleep(3000);
3858 } 4192 }
3859 4193
4194 [DebuggerNonUserCode]
3860 public void llRemoveInventory(string name) 4195 public void llRemoveInventory(string name)
3861 { 4196 {
3862 m_host.AddScriptLPS(1); 4197 m_host.AddScriptLPS(1);
3863 4198
3864 lock (m_host.TaskInventory) 4199 m_host.TaskInventory.LockItemsForRead(true);
4200 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3865 { 4201 {
3866 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4202 if (item.Name == name)
3867 { 4203 {
3868 if (item.Name == name) 4204 if (item.ItemID == m_itemID)
3869 { 4205 throw new ScriptDeleteException();
3870 if (item.ItemID == m_itemID) 4206 else
3871 throw new ScriptDeleteException(); 4207 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3872 else 4208
3873 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4209 m_host.TaskInventory.LockItemsForRead(false);
3874 return; 4210 return;
3875 }
3876 } 4211 }
3877 } 4212 }
4213 m_host.TaskInventory.LockItemsForRead(false);
3878 } 4214 }
3879 4215
3880 public void llSetText(string text, LSL_Vector color, double alpha) 4216 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3964,6 +4300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3964 { 4300 {
3965 m_host.AddScriptLPS(1); 4301 m_host.AddScriptLPS(1);
3966 4302
4303 //Clone is thread safe
3967 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4304 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3968 4305
3969 foreach (TaskInventoryItem item in itemDictionary.Values) 4306 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4017,6 +4354,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4017 ScenePresence presence = World.GetScenePresence(agentId); 4354 ScenePresence presence = World.GetScenePresence(agentId);
4018 if (presence != null) 4355 if (presence != null)
4019 { 4356 {
4357 // agent must not be a god
4358 if (presence.GodLevel >= 200) return;
4359
4020 // agent must be over the owners land 4360 // agent must be over the owners land
4021 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4361 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4022 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4362 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4077,17 +4417,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4077 UUID soundId = UUID.Zero; 4417 UUID soundId = UUID.Zero;
4078 if (!UUID.TryParse(impact_sound, out soundId)) 4418 if (!UUID.TryParse(impact_sound, out soundId))
4079 { 4419 {
4080 lock (m_host.TaskInventory) 4420 m_host.TaskInventory.LockItemsForRead(true);
4421 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4081 { 4422 {
4082 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4423 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4083 { 4424 {
4084 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4425 soundId = item.AssetID;
4085 { 4426 break;
4086 soundId = item.AssetID;
4087 break;
4088 }
4089 } 4427 }
4090 } 4428 }
4429 m_host.TaskInventory.LockItemsForRead(false);
4091 } 4430 }
4092 m_host.CollisionSound = soundId; 4431 m_host.CollisionSound = soundId;
4093 m_host.CollisionSoundVolume = (float)impact_volume; 4432 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4133,6 +4472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4133 UUID partItemID; 4472 UUID partItemID;
4134 foreach (SceneObjectPart part in parts) 4473 foreach (SceneObjectPart part in parts)
4135 { 4474 {
4475 //Clone is thread safe
4136 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4476 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4137 4477
4138 foreach (TaskInventoryItem item in itemsDictionary.Values) 4478 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4347,17 +4687,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4687
4348 m_host.AddScriptLPS(1); 4688 m_host.AddScriptLPS(1);
4349 4689
4350 lock (m_host.TaskInventory) 4690 m_host.TaskInventory.LockItemsForRead(true);
4691 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4351 { 4692 {
4352 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4693 if (item.Type == 10 && item.ItemID == m_itemID)
4353 { 4694 {
4354 if (item.Type == 10 && item.ItemID == m_itemID) 4695 result = item.Name!=null?item.Name:String.Empty;
4355 { 4696 break;
4356 result = item.Name != null ? item.Name : String.Empty;
4357 break;
4358 }
4359 } 4697 }
4360 } 4698 }
4699 m_host.TaskInventory.LockItemsForRead(false);
4361 4700
4362 return result; 4701 return result;
4363 } 4702 }
@@ -4510,23 +4849,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4510 { 4849 {
4511 m_host.AddScriptLPS(1); 4850 m_host.AddScriptLPS(1);
4512 4851
4513 lock (m_host.TaskInventory) 4852 m_host.TaskInventory.LockItemsForRead(true);
4853 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4514 { 4854 {
4515 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4855 if (inv.Value.Name == name)
4516 { 4856 {
4517 if (inv.Value.Name == name) 4857 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4518 { 4858 {
4519 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4859 m_host.TaskInventory.LockItemsForRead(false);
4520 { 4860 return inv.Value.AssetID.ToString();
4521 return inv.Value.AssetID.ToString(); 4861 }
4522 } 4862 else
4523 else 4863 {
4524 { 4864 m_host.TaskInventory.LockItemsForRead(false);
4525 return UUID.Zero.ToString(); 4865 return UUID.Zero.ToString();
4526 }
4527 } 4866 }
4528 } 4867 }
4529 } 4868 }
4869 m_host.TaskInventory.LockItemsForRead(false);
4530 4870
4531 return UUID.Zero.ToString(); 4871 return UUID.Zero.ToString();
4532 } 4872 }
@@ -4679,14 +5019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4679 { 5019 {
4680 m_host.AddScriptLPS(1); 5020 m_host.AddScriptLPS(1);
4681 5021
4682 if (src == null) 5022 return src.Length;
4683 {
4684 return 0;
4685 }
4686 else
4687 {
4688 return src.Length;
4689 }
4690 } 5023 }
4691 5024
4692 public LSL_Integer llList2Integer(LSL_List src, int index) 5025 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5462,10 +5795,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5462 m_host.AddScriptLPS(1); 5795 m_host.AddScriptLPS(1);
5463 5796
5464 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5797 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5465 5798 if (parts.Count > 0)
5466 foreach (var part in parts)
5467 { 5799 {
5468 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5800 try
5801 {
5802 parts[0].ParentGroup.areUpdatesSuspended = true;
5803 foreach (var part in parts)
5804 {
5805 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5806 }
5807 }
5808 finally
5809 {
5810 parts[0].ParentGroup.areUpdatesSuspended = false;
5811 }
5469 } 5812 }
5470 } 5813 }
5471 5814
@@ -5521,74 +5864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5521 5864
5522 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5865 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5523 { 5866 {
5524 m_host.AddScriptLPS(1); 5867 return ParseString2List(str, separators, in_spacers, false);
5525 LSL_List ret = new LSL_List();
5526 LSL_List spacers = new LSL_List();
5527 if (in_spacers.Length > 0 && separators.Length > 0)
5528 {
5529 for (int i = 0; i < in_spacers.Length; i++)
5530 {
5531 object s = in_spacers.Data[i];
5532 for (int j = 0; j < separators.Length; j++)
5533 {
5534 if (separators.Data[j].ToString() == s.ToString())
5535 {
5536 s = null;
5537 break;
5538 }
5539 }
5540 if (s != null)
5541 {
5542 spacers.Add(s);
5543 }
5544 }
5545 }
5546 object[] delimiters = new object[separators.Length + spacers.Length];
5547 separators.Data.CopyTo(delimiters, 0);
5548 spacers.Data.CopyTo(delimiters, separators.Length);
5549 bool dfound = false;
5550 do
5551 {
5552 dfound = false;
5553 int cindex = -1;
5554 string cdeli = "";
5555 for (int i = 0; i < delimiters.Length; i++)
5556 {
5557 int index = str.IndexOf(delimiters[i].ToString());
5558 bool found = index != -1;
5559 if (found && String.Empty != delimiters[i].ToString())
5560 {
5561 if ((cindex > index) || (cindex == -1))
5562 {
5563 cindex = index;
5564 cdeli = delimiters[i].ToString();
5565 }
5566 dfound = dfound || found;
5567 }
5568 }
5569 if (cindex != -1)
5570 {
5571 if (cindex > 0)
5572 {
5573 ret.Add(new LSL_String(str.Substring(0, cindex)));
5574 }
5575 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5576 for (int j = 0; j < spacers.Length; j++)
5577 {
5578 if (spacers.Data[j].ToString() == cdeli)
5579 {
5580 ret.Add(new LSL_String(cdeli));
5581 break;
5582 }
5583 }
5584 str = str.Substring(cindex + cdeli.Length);
5585 }
5586 } while (dfound);
5587 if (str != "")
5588 {
5589 ret.Add(new LSL_String(str));
5590 }
5591 return ret;
5592 } 5868 }
5593 5869
5594 public LSL_Integer llOverMyLand(string id) 5870 public LSL_Integer llOverMyLand(string id)
@@ -5791,7 +6067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5791 return m_host.ParentGroup.RootPart.AttachmentPoint; 6067 return m_host.ParentGroup.RootPart.AttachmentPoint;
5792 } 6068 }
5793 6069
5794 public LSL_Integer llGetFreeMemory() 6070 public virtual LSL_Integer llGetFreeMemory()
5795 { 6071 {
5796 m_host.AddScriptLPS(1); 6072 m_host.AddScriptLPS(1);
5797 // Make scripts designed for LSO happy 6073 // Make scripts designed for LSO happy
@@ -6102,14 +6378,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6102 6378
6103 protected UUID GetTaskInventoryItem(string name) 6379 protected UUID GetTaskInventoryItem(string name)
6104 { 6380 {
6105 lock (m_host.TaskInventory) 6381 m_host.TaskInventory.LockItemsForRead(true);
6382 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6106 { 6383 {
6107 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6384 if (inv.Value.Name == name)
6108 { 6385 {
6109 if (inv.Value.Name == name) 6386 m_host.TaskInventory.LockItemsForRead(false);
6110 return inv.Key; 6387 return inv.Key;
6111 } 6388 }
6112 } 6389 }
6390 m_host.TaskInventory.LockItemsForRead(false);
6113 6391
6114 return UUID.Zero; 6392 return UUID.Zero;
6115 } 6393 }
@@ -6437,22 +6715,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6437 } 6715 }
6438 6716
6439 // copy the first script found with this inventory name 6717 // copy the first script found with this inventory name
6440 lock (m_host.TaskInventory) 6718 m_host.TaskInventory.LockItemsForRead(true);
6719 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6441 { 6720 {
6442 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6721 if (inv.Value.Name == name)
6443 { 6722 {
6444 if (inv.Value.Name == name) 6723 // make sure the object is a script
6724 if (10 == inv.Value.Type)
6445 { 6725 {
6446 // make sure the object is a script 6726 found = true;
6447 if (10 == inv.Value.Type) 6727 srcId = inv.Key;
6448 { 6728 break;
6449 found = true;
6450 srcId = inv.Key;
6451 break;
6452 }
6453 } 6729 }
6454 } 6730 }
6455 } 6731 }
6732 m_host.TaskInventory.LockItemsForRead(false);
6456 6733
6457 if (!found) 6734 if (!found)
6458 { 6735 {
@@ -6536,6 +6813,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6536 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6813 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6537 { 6814 {
6538 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6815 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6816 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6817 return shapeBlock;
6539 6818
6540 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6819 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6541 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6820 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6611,6 +6890,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6611 6890
6612 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6891 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6613 { 6892 {
6893 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6894 return;
6895
6614 ObjectShapePacket.ObjectDataBlock shapeBlock; 6896 ObjectShapePacket.ObjectDataBlock shapeBlock;
6615 6897
6616 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6898 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6660,6 +6942,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6660 6942
6661 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 6943 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6662 { 6944 {
6945 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6946 return;
6947
6663 ObjectShapePacket.ObjectDataBlock shapeBlock; 6948 ObjectShapePacket.ObjectDataBlock shapeBlock;
6664 6949
6665 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6950 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6702,6 +6987,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6702 6987
6703 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) 6988 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)
6704 { 6989 {
6990 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6991 return;
6992
6705 ObjectShapePacket.ObjectDataBlock shapeBlock; 6993 ObjectShapePacket.ObjectDataBlock shapeBlock;
6706 6994
6707 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6995 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6828,6 +7116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6828 7116
6829 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7117 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6830 { 7118 {
7119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7120 return;
7121
6831 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7122 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6832 UUID sculptId; 7123 UUID sculptId;
6833 7124
@@ -6843,13 +7134,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6843 shapeBlock.PathScaleX = 100; 7134 shapeBlock.PathScaleX = 100;
6844 shapeBlock.PathScaleY = 150; 7135 shapeBlock.PathScaleY = 150;
6845 7136
6846 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7137 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6847 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7138 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6848 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7139 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6849 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7140 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6850 { 7141 {
6851 // default 7142 // default
6852 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7143 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6853 } 7144 }
6854 7145
6855 // retain pathcurve 7146 // retain pathcurve
@@ -6866,23 +7157,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6866 SetPrimParams(m_host, rules); 7157 SetPrimParams(m_host, rules);
6867 } 7158 }
6868 7159
6869 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7160 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6870 { 7161 {
6871 m_host.AddScriptLPS(1); 7162 m_host.AddScriptLPS(1);
6872 7163
6873 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7164 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7165 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7166 if (parts.Count>0)
7167 {
7168 try
7169 {
7170 parts[0].ParentGroup.areUpdatesSuspended = true;
7171 foreach (SceneObjectPart part in parts)
7172 SetPrimParams(part, rules);
7173 }
7174 finally
7175 {
7176 parts[0].ParentGroup.areUpdatesSuspended = false;
7177 }
7178 }
7179 if (avatars.Count > 0)
7180 {
7181 foreach (ScenePresence avatar in avatars)
7182 SetPrimParams(avatar, rules);
7183 }
7184 }
6874 7185
6875 foreach (SceneObjectPart part in parts) 7186 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6876 SetPrimParams(part, rules); 7187 {
7188 llSetLinkPrimitiveParamsFast(linknumber, rules);
7189 ScriptSleep(200);
6877 } 7190 }
6878 7191
6879 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7192 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6880 { 7193 {
6881 llSetLinkPrimitiveParams(linknumber, rules); 7194 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7195 //We only support PRIM_POSITION and PRIM_ROTATION
7196
7197 int idx = 0;
7198
7199 while (idx < rules.Length)
7200 {
7201 int code = rules.GetLSLIntegerItem(idx++);
7202
7203 int remain = rules.Length - idx;
7204
7205
7206
7207 switch (code)
7208 {
7209 case (int)ScriptBaseClass.PRIM_POSITION:
7210 if (remain < 1)
7211 return;
7212 LSL_Vector v;
7213 v = rules.GetVector3Item(idx++);
7214 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7215 av.SendFullUpdateToAllClients();
7216
7217 break;
7218
7219 case (int)ScriptBaseClass.PRIM_ROTATION:
7220 if (remain < 1)
7221 return;
7222 LSL_Rotation r;
7223 r = rules.GetQuaternionItem(idx++);
7224 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7225 av.SendFullUpdateToAllClients();
7226 break;
7227 }
7228 }
7229
6882 } 7230 }
6883 7231
6884 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7232 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6885 { 7233 {
7234 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7235 return;
7236
6886 int idx = 0; 7237 int idx = 0;
6887 7238
6888 while (idx < rules.Length) 7239 while (idx < rules.Length)
@@ -7714,24 +8065,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7714 break; 8065 break;
7715 8066
7716 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8067 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7717 // TODO--------------
7718 if (remain < 1) 8068 if (remain < 1)
7719 return res; 8069 return res;
8070 face = (int)rules.GetLSLIntegerItem(idx++);
7720 8071
7721 face=(int)rules.GetLSLIntegerItem(idx++); 8072 tex = part.Shape.Textures;
7722 8073 int shiny;
7723 res.Add(new LSL_Integer(0)); 8074 if (face == ScriptBaseClass.ALL_SIDES)
7724 res.Add(new LSL_Integer(0)); 8075 {
8076 for (face = 0; face < GetNumberOfSides(part); face++)
8077 {
8078 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8079 if (shinyness == Shininess.High)
8080 {
8081 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8082 }
8083 else if (shinyness == Shininess.Medium)
8084 {
8085 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8086 }
8087 else if (shinyness == Shininess.Low)
8088 {
8089 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8090 }
8091 else
8092 {
8093 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8094 }
8095 res.Add(new LSL_Integer(shiny));
8096 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8097 }
8098 }
8099 else
8100 {
8101 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8102 if (shinyness == Shininess.High)
8103 {
8104 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8105 }
8106 else if (shinyness == Shininess.Medium)
8107 {
8108 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8109 }
8110 else if (shinyness == Shininess.Low)
8111 {
8112 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8113 }
8114 else
8115 {
8116 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8117 }
8118 res.Add(new LSL_Integer(shiny));
8119 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8120 }
7725 break; 8121 break;
7726 8122
7727 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8123 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7728 // TODO--------------
7729 if (remain < 1) 8124 if (remain < 1)
7730 return res; 8125 return res;
8126 face = (int)rules.GetLSLIntegerItem(idx++);
7731 8127
7732 face=(int)rules.GetLSLIntegerItem(idx++); 8128 tex = part.Shape.Textures;
7733 8129 int fullbright;
7734 res.Add(new LSL_Integer(0)); 8130 if (face == ScriptBaseClass.ALL_SIDES)
8131 {
8132 for (face = 0; face < GetNumberOfSides(part); face++)
8133 {
8134 if (tex.GetFace((uint)face).Fullbright == true)
8135 {
8136 fullbright = ScriptBaseClass.TRUE;
8137 }
8138 else
8139 {
8140 fullbright = ScriptBaseClass.FALSE;
8141 }
8142 res.Add(new LSL_Integer(fullbright));
8143 }
8144 }
8145 else
8146 {
8147 if (tex.GetFace((uint)face).Fullbright == true)
8148 {
8149 fullbright = ScriptBaseClass.TRUE;
8150 }
8151 else
8152 {
8153 fullbright = ScriptBaseClass.FALSE;
8154 }
8155 res.Add(new LSL_Integer(fullbright));
8156 }
7735 break; 8157 break;
7736 8158
7737 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8159 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7752,14 +8174,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7752 break; 8174 break;
7753 8175
7754 case (int)ScriptBaseClass.PRIM_TEXGEN: 8176 case (int)ScriptBaseClass.PRIM_TEXGEN:
7755 // TODO--------------
7756 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8177 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7757 if (remain < 1) 8178 if (remain < 1)
7758 return res; 8179 return res;
8180 face = (int)rules.GetLSLIntegerItem(idx++);
7759 8181
7760 face=(int)rules.GetLSLIntegerItem(idx++); 8182 tex = part.Shape.Textures;
7761 8183 if (face == ScriptBaseClass.ALL_SIDES)
7762 res.Add(new LSL_Integer(0)); 8184 {
8185 for (face = 0; face < GetNumberOfSides(part); face++)
8186 {
8187 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8188 {
8189 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8190 }
8191 else
8192 {
8193 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8194 }
8195 }
8196 }
8197 else
8198 {
8199 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8200 {
8201 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8202 }
8203 else
8204 {
8205 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8206 }
8207 }
7763 break; 8208 break;
7764 8209
7765 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8210 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7778,13 +8223,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7778 break; 8223 break;
7779 8224
7780 case (int)ScriptBaseClass.PRIM_GLOW: 8225 case (int)ScriptBaseClass.PRIM_GLOW:
7781 // TODO--------------
7782 if (remain < 1) 8226 if (remain < 1)
7783 return res; 8227 return res;
8228 face = (int)rules.GetLSLIntegerItem(idx++);
7784 8229
7785 face=(int)rules.GetLSLIntegerItem(idx++); 8230 tex = part.Shape.Textures;
7786 8231 float primglow;
7787 res.Add(new LSL_Float(0)); 8232 if (face == ScriptBaseClass.ALL_SIDES)
8233 {
8234 for (face = 0; face < GetNumberOfSides(part); face++)
8235 {
8236 primglow = tex.GetFace((uint)face).Glow;
8237 res.Add(new LSL_Float(primglow));
8238 }
8239 }
8240 else
8241 {
8242 primglow = tex.GetFace((uint)face).Glow;
8243 res.Add(new LSL_Float(primglow));
8244 }
7788 break; 8245 break;
7789 case (int)ScriptBaseClass.PRIM_TEXT: 8246 case (int)ScriptBaseClass.PRIM_TEXT:
7790 Color4 textColor = part.GetTextColor(); 8247 Color4 textColor = part.GetTextColor();
@@ -8090,8 +8547,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8090 // The function returns an ordered list 8547 // The function returns an ordered list
8091 // representing the tokens found in the supplied 8548 // representing the tokens found in the supplied
8092 // sources string. If two successive tokenizers 8549 // sources string. If two successive tokenizers
8093 // are encountered, then a NULL entry is added 8550 // are encountered, then a null-string entry is
8094 // to the list. 8551 // added to the list.
8095 // 8552 //
8096 // It is a precondition that the source and 8553 // It is a precondition that the source and
8097 // toekizer lisst are non-null. If they are null, 8554 // toekizer lisst are non-null. If they are null,
@@ -8099,7 +8556,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8099 // while their lengths are being determined. 8556 // while their lengths are being determined.
8100 // 8557 //
8101 // A small amount of working memoryis required 8558 // A small amount of working memoryis required
8102 // of approximately 8*#tokenizers. 8559 // of approximately 8*#tokenizers + 8*srcstrlen.
8103 // 8560 //
8104 // There are many ways in which this function 8561 // There are many ways in which this function
8105 // can be implemented, this implementation is 8562 // can be implemented, this implementation is
@@ -8115,136 +8572,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 // and eliminates redundant tokenizers as soon 8572 // and eliminates redundant tokenizers as soon
8116 // as is possible. 8573 // as is possible.
8117 // 8574 //
8118 // The implementation tries to avoid any copying 8575 // The implementation tries to minimize temporary
8119 // of arrays or other objects. 8576 // garbage generation.
8120 // </remarks> 8577 // </remarks>
8121 8578
8122 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8579 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8123 { 8580 {
8124 int beginning = 0; 8581 return ParseString2List(src, separators, spacers, true);
8125 int srclen = src.Length; 8582 }
8126 int seplen = separators.Length;
8127 object[] separray = separators.Data;
8128 int spclen = spacers.Length;
8129 object[] spcarray = spacers.Data;
8130 int mlen = seplen+spclen;
8131
8132 int[] offset = new int[mlen+1];
8133 bool[] active = new bool[mlen];
8134 8583
8135 int best; 8584 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8136 int j; 8585 {
8586 int srclen = src.Length;
8587 int seplen = separators.Length;
8588 object[] separray = separators.Data;
8589 int spclen = spacers.Length;
8590 object[] spcarray = spacers.Data;
8591 int dellen = 0;
8592 string[] delarray = new string[seplen+spclen];
8137 8593
8138 // Initial capacity reduces resize cost 8594 int outlen = 0;
8595 string[] outarray = new string[srclen*2+1];
8139 8596
8140 LSL_List tokens = new LSL_List(); 8597 int i, j;
8598 string d;
8141 8599
8142 m_host.AddScriptLPS(1); 8600 m_host.AddScriptLPS(1);
8143 8601
8144 // All entries are initially valid 8602 /*
8145 8603 * Convert separator and spacer lists to C# strings.
8146 for (int i = 0; i < mlen; i++) 8604 * Also filter out null strings so we don't hang.
8147 active[i] = true; 8605 */
8148 8606 for (i = 0; i < seplen; i ++) {
8149 offset[mlen] = srclen; 8607 d = separray[i].ToString();
8150 8608 if (d.Length > 0) {
8151 while (beginning < srclen) 8609 delarray[dellen++] = d;
8152 { 8610 }
8153 8611 }
8154 best = mlen; // as bad as it gets 8612 seplen = dellen;
8155
8156 // Scan for separators
8157 8613
8158 for (j = 0; j < seplen; j++) 8614 for (i = 0; i < spclen; i ++) {
8159 { 8615 d = spcarray[i].ToString();
8160 if (active[j]) 8616 if (d.Length > 0) {
8161 { 8617 delarray[dellen++] = d;
8162 // scan all of the markers
8163 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8164 {
8165 // not present at all
8166 active[j] = false;
8167 }
8168 else
8169 {
8170 // present and correct
8171 if (offset[j] < offset[best])
8172 {
8173 // closest so far
8174 best = j;
8175 if (offset[best] == beginning)
8176 break;
8177 }
8178 }
8179 }
8180 } 8618 }
8619 }
8181 8620
8182 // Scan for spacers 8621 /*
8622 * Scan through source string from beginning to end.
8623 */
8624 for (i = 0;;) {
8183 8625
8184 if (offset[best] != beginning) 8626 /*
8185 { 8627 * Find earliest delimeter in src starting at i (if any).
8186 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8628 */
8187 { 8629 int earliestDel = -1;
8188 if (active[j]) 8630 int earliestSrc = srclen;
8189 { 8631 string earliestStr = null;
8190 // scan all of the markers 8632 for (j = 0; j < dellen; j ++) {
8191 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8633 d = delarray[j];
8192 { 8634 if (d != null) {
8193 // not present at all 8635 int index = src.IndexOf(d, i);
8194 active[j] = false; 8636 if (index < 0) {
8195 } 8637 delarray[j] = null; // delim nowhere in src, don't check it anymore
8196 else 8638 } else if (index < earliestSrc) {
8197 { 8639 earliestSrc = index; // where delimeter starts in source string
8198 // present and correct 8640 earliestDel = j; // where delimeter is in delarray[]
8199 if (offset[j] < offset[best]) 8641 earliestStr = d; // the delimeter string from delarray[]
8200 { 8642 if (index == i) break; // can't do any better than found at beg of string
8201 // closest so far
8202 best = j;
8203 }
8204 }
8205 } 8643 }
8206 } 8644 }
8207 } 8645 }
8208 8646
8209 // This is the normal exit from the scanning loop 8647 /*
8210 8648 * Output source string starting at i through start of earliest delimeter.
8211 if (best == mlen) 8649 */
8212 { 8650 if (keepNulls || (earliestSrc > i)) {
8213 // no markers were found on this pass 8651 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8214 // so we're pretty much done
8215 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8216 break;
8217 } 8652 }
8218 8653
8219 // Otherwise we just add the newly delimited token 8654 /*
8220 // and recalculate where the search should continue. 8655 * If no delimeter found at or after i, we're done scanning.
8656 */
8657 if (earliestDel < 0) break;
8221 8658
8222 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8659 /*
8223 8660 * If delimeter was a spacer, output the spacer.
8224 if (best < seplen) 8661 */
8225 { 8662 if (earliestDel >= seplen) {
8226 beginning = offset[best] + (separray[best].ToString()).Length; 8663 outarray[outlen++] = earliestStr;
8227 } 8664 }
8228 else
8229 {
8230 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8231 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8232 }
8233 }
8234 8665
8235 // This an awkward an not very intuitive boundary case. If the 8666 /*
8236 // last substring is a tokenizer, then there is an implied trailing 8667 * Look at rest of src string following delimeter.
8237 // null list entry. Hopefully the single comparison will not be too 8668 */
8238 // arduous. Alternatively the 'break' could be replced with a return 8669 i = earliestSrc + earliestStr.Length;
8239 // but that's shabby programming.
8240
8241 if (beginning == srclen)
8242 {
8243 if (srclen != 0)
8244 tokens.Add(new LSL_String(""));
8245 } 8670 }
8246 8671
8247 return tokens; 8672 /*
8673 * Make up an exact-sized output array suitable for an LSL_List object.
8674 */
8675 object[] outlist = new object[outlen];
8676 for (i = 0; i < outlen; i ++) {
8677 outlist[i] = new LSL_String(outarray[i]);
8678 }
8679 return new LSL_List(outlist);
8248 } 8680 }
8249 8681
8250 public LSL_Integer llGetObjectPermMask(int mask) 8682 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8321,28 +8753,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8321 { 8753 {
8322 m_host.AddScriptLPS(1); 8754 m_host.AddScriptLPS(1);
8323 8755
8324 lock (m_host.TaskInventory) 8756 m_host.TaskInventory.LockItemsForRead(true);
8757 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8325 { 8758 {
8326 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8759 if (inv.Value.Name == item)
8327 { 8760 {
8328 if (inv.Value.Name == item) 8761 m_host.TaskInventory.LockItemsForRead(false);
8762 switch (mask)
8329 { 8763 {
8330 switch (mask) 8764 case 0:
8331 { 8765 return (int)inv.Value.BasePermissions;
8332 case 0: 8766 case 1:
8333 return (int)inv.Value.BasePermissions; 8767 return (int)inv.Value.CurrentPermissions;
8334 case 1: 8768 case 2:
8335 return (int)inv.Value.CurrentPermissions; 8769 return (int)inv.Value.GroupPermissions;
8336 case 2: 8770 case 3:
8337 return (int)inv.Value.GroupPermissions; 8771 return (int)inv.Value.EveryonePermissions;
8338 case 3: 8772 case 4:
8339 return (int)inv.Value.EveryonePermissions; 8773 return (int)inv.Value.NextPermissions;
8340 case 4:
8341 return (int)inv.Value.NextPermissions;
8342 }
8343 } 8774 }
8344 } 8775 }
8345 } 8776 }
8777 m_host.TaskInventory.LockItemsForRead(false);
8346 8778
8347 return -1; 8779 return -1;
8348 } 8780 }
@@ -8389,16 +8821,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8389 { 8821 {
8390 m_host.AddScriptLPS(1); 8822 m_host.AddScriptLPS(1);
8391 8823
8392 lock (m_host.TaskInventory) 8824 m_host.TaskInventory.LockItemsForRead(true);
8825 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8393 { 8826 {
8394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8827 if (inv.Value.Name == item)
8395 { 8828 {
8396 if (inv.Value.Name == item) 8829 m_host.TaskInventory.LockItemsForRead(false);
8397 { 8830 return inv.Value.CreatorID.ToString();
8398 return inv.Value.CreatorID.ToString();
8399 }
8400 } 8831 }
8401 } 8832 }
8833 m_host.TaskInventory.LockItemsForRead(false);
8402 8834
8403 llSay(0, "No item name '" + item + "'"); 8835 llSay(0, "No item name '" + item + "'");
8404 8836
@@ -8658,17 +9090,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8658 int width = 0; 9090 int width = 0;
8659 int height = 0; 9091 int height = 0;
8660 9092
8661 ParcelMediaCommandEnum? commandToSend = null; 9093 uint commandToSend = 0;
8662 float time = 0.0f; // default is from start 9094 float time = 0.0f; // default is from start
8663 9095
8664 ScenePresence presence = null; 9096 ScenePresence presence = null;
8665 9097
8666 for (int i = 0; i < commandList.Data.Length; i++) 9098 for (int i = 0; i < commandList.Data.Length; i++)
8667 { 9099 {
8668 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9100 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8669 switch (command) 9101 switch (command)
8670 { 9102 {
8671 case ParcelMediaCommandEnum.Agent: 9103 case (uint)ParcelMediaCommandEnum.Agent:
8672 // we send only to one agent 9104 // we send only to one agent
8673 if ((i + 1) < commandList.Length) 9105 if ((i + 1) < commandList.Length)
8674 { 9106 {
@@ -8685,25 +9117,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8685 } 9117 }
8686 break; 9118 break;
8687 9119
8688 case ParcelMediaCommandEnum.Loop: 9120 case (uint)ParcelMediaCommandEnum.Loop:
8689 loop = 1; 9121 loop = 1;
8690 commandToSend = command; 9122 commandToSend = command;
8691 update = true; //need to send the media update packet to set looping 9123 update = true; //need to send the media update packet to set looping
8692 break; 9124 break;
8693 9125
8694 case ParcelMediaCommandEnum.Play: 9126 case (uint)ParcelMediaCommandEnum.Play:
8695 loop = 0; 9127 loop = 0;
8696 commandToSend = command; 9128 commandToSend = command;
8697 update = true; //need to send the media update packet to make sure it doesn't loop 9129 update = true; //need to send the media update packet to make sure it doesn't loop
8698 break; 9130 break;
8699 9131
8700 case ParcelMediaCommandEnum.Pause: 9132 case (uint)ParcelMediaCommandEnum.Pause:
8701 case ParcelMediaCommandEnum.Stop: 9133 case (uint)ParcelMediaCommandEnum.Stop:
8702 case ParcelMediaCommandEnum.Unload: 9134 case (uint)ParcelMediaCommandEnum.Unload:
8703 commandToSend = command; 9135 commandToSend = command;
8704 break; 9136 break;
8705 9137
8706 case ParcelMediaCommandEnum.Url: 9138 case (uint)ParcelMediaCommandEnum.Url:
8707 if ((i + 1) < commandList.Length) 9139 if ((i + 1) < commandList.Length)
8708 { 9140 {
8709 if (commandList.Data[i + 1] is LSL_String) 9141 if (commandList.Data[i + 1] is LSL_String)
@@ -8716,7 +9148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8716 } 9148 }
8717 break; 9149 break;
8718 9150
8719 case ParcelMediaCommandEnum.Texture: 9151 case (uint)ParcelMediaCommandEnum.Texture:
8720 if ((i + 1) < commandList.Length) 9152 if ((i + 1) < commandList.Length)
8721 { 9153 {
8722 if (commandList.Data[i + 1] is LSL_String) 9154 if (commandList.Data[i + 1] is LSL_String)
@@ -8729,7 +9161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8729 } 9161 }
8730 break; 9162 break;
8731 9163
8732 case ParcelMediaCommandEnum.Time: 9164 case (uint)ParcelMediaCommandEnum.Time:
8733 if ((i + 1) < commandList.Length) 9165 if ((i + 1) < commandList.Length)
8734 { 9166 {
8735 if (commandList.Data[i + 1] is LSL_Float) 9167 if (commandList.Data[i + 1] is LSL_Float)
@@ -8741,7 +9173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8741 } 9173 }
8742 break; 9174 break;
8743 9175
8744 case ParcelMediaCommandEnum.AutoAlign: 9176 case (uint)ParcelMediaCommandEnum.AutoAlign:
8745 if ((i + 1) < commandList.Length) 9177 if ((i + 1) < commandList.Length)
8746 { 9178 {
8747 if (commandList.Data[i + 1] is LSL_Integer) 9179 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8755,7 +9187,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8755 } 9187 }
8756 break; 9188 break;
8757 9189
8758 case ParcelMediaCommandEnum.Type: 9190 case (uint)ParcelMediaCommandEnum.Type:
8759 if ((i + 1) < commandList.Length) 9191 if ((i + 1) < commandList.Length)
8760 { 9192 {
8761 if (commandList.Data[i + 1] is LSL_String) 9193 if (commandList.Data[i + 1] is LSL_String)
@@ -8768,7 +9200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8768 } 9200 }
8769 break; 9201 break;
8770 9202
8771 case ParcelMediaCommandEnum.Desc: 9203 case (uint)ParcelMediaCommandEnum.Desc:
8772 if ((i + 1) < commandList.Length) 9204 if ((i + 1) < commandList.Length)
8773 { 9205 {
8774 if (commandList.Data[i + 1] is LSL_String) 9206 if (commandList.Data[i + 1] is LSL_String)
@@ -8781,7 +9213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8781 } 9213 }
8782 break; 9214 break;
8783 9215
8784 case ParcelMediaCommandEnum.Size: 9216 case (uint)ParcelMediaCommandEnum.Size:
8785 if ((i + 2) < commandList.Length) 9217 if ((i + 2) < commandList.Length)
8786 { 9218 {
8787 if (commandList.Data[i + 1] is LSL_Integer) 9219 if (commandList.Data[i + 1] is LSL_Integer)
@@ -8851,7 +9283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8851 } 9283 }
8852 } 9284 }
8853 9285
8854 if (commandToSend != null) 9286 if (commandToSend != 0)
8855 { 9287 {
8856 // the commandList contained a start/stop/... command, too 9288 // the commandList contained a start/stop/... command, too
8857 if (presence == null) 9289 if (presence == null)
@@ -8888,7 +9320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8888 9320
8889 if (aList.Data[i] != null) 9321 if (aList.Data[i] != null)
8890 { 9322 {
8891 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9323 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
8892 { 9324 {
8893 case ParcelMediaCommandEnum.Url: 9325 case ParcelMediaCommandEnum.Url:
8894 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9326 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -8931,16 +9363,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8931 { 9363 {
8932 m_host.AddScriptLPS(1); 9364 m_host.AddScriptLPS(1);
8933 9365
8934 lock (m_host.TaskInventory) 9366 m_host.TaskInventory.LockItemsForRead(true);
9367 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8935 { 9368 {
8936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9369 if (inv.Value.Name == name)
8937 { 9370 {
8938 if (inv.Value.Name == name) 9371 m_host.TaskInventory.LockItemsForRead(false);
8939 { 9372 return inv.Value.Type;
8940 return inv.Value.Type;
8941 }
8942 } 9373 }
8943 } 9374 }
9375 m_host.TaskInventory.LockItemsForRead(false);
8944 9376
8945 return -1; 9377 return -1;
8946 } 9378 }
@@ -8951,15 +9383,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8951 9383
8952 if (quick_pay_buttons.Data.Length < 4) 9384 if (quick_pay_buttons.Data.Length < 4)
8953 { 9385 {
8954 LSLError("List must have at least 4 elements"); 9386 int x;
8955 return; 9387 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9388 {
9389 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9390 }
8956 } 9391 }
8957 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9392 int[] nPrice = new int[5];
8958 9393 nPrice[0]=price;
8959 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9394 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
8960 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9395 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
8961 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9396 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
8962 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9397 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9398 m_host.ParentGroup.RootPart.PayPrice = nPrice;
8963 m_host.ParentGroup.HasGroupChanged = true; 9399 m_host.ParentGroup.HasGroupChanged = true;
8964 } 9400 }
8965 9401
@@ -8971,17 +9407,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8971 if (invItemID == UUID.Zero) 9407 if (invItemID == UUID.Zero)
8972 return new LSL_Vector(); 9408 return new LSL_Vector();
8973 9409
8974 lock (m_host.TaskInventory) 9410 m_host.TaskInventory.LockItemsForRead(true);
9411 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8975 { 9412 {
8976 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9413 m_host.TaskInventory.LockItemsForRead(false);
8977 return new LSL_Vector(); 9414 return new LSL_Vector();
9415 }
8978 9416
8979 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9417 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8980 { 9418 {
8981 ShoutError("No permissions to track the camera"); 9419 ShoutError("No permissions to track the camera");
8982 return new LSL_Vector(); 9420 m_host.TaskInventory.LockItemsForRead(false);
8983 } 9421 return new LSL_Vector();
8984 } 9422 }
9423 m_host.TaskInventory.LockItemsForRead(false);
8985 9424
8986 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9425 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8987 if (presence != null) 9426 if (presence != null)
@@ -8999,17 +9438,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8999 if (invItemID == UUID.Zero) 9438 if (invItemID == UUID.Zero)
9000 return new LSL_Rotation(); 9439 return new LSL_Rotation();
9001 9440
9002 lock (m_host.TaskInventory) 9441 m_host.TaskInventory.LockItemsForRead(true);
9442 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9003 { 9443 {
9004 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9444 m_host.TaskInventory.LockItemsForRead(false);
9005 return new LSL_Rotation(); 9445 return new LSL_Rotation();
9006 9446 }
9007 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9447 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9008 { 9448 {
9009 ShoutError("No permissions to track the camera"); 9449 ShoutError("No permissions to track the camera");
9010 return new LSL_Rotation(); 9450 m_host.TaskInventory.LockItemsForRead(false);
9011 } 9451 return new LSL_Rotation();
9012 } 9452 }
9453 m_host.TaskInventory.LockItemsForRead(false);
9013 9454
9014 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9455 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9015 if (presence != null) 9456 if (presence != null)
@@ -9071,8 +9512,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9071 { 9512 {
9072 m_host.AddScriptLPS(1); 9513 m_host.AddScriptLPS(1);
9073 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9514 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9074 if (detectedParams == null) return; // only works on the first detected avatar 9515 if (detectedParams == null)
9075 9516 {
9517 if (m_host.IsAttachment == true)
9518 {
9519 detectedParams = new DetectParams();
9520 detectedParams.Key = m_host.OwnerID;
9521 }
9522 else
9523 {
9524 return;
9525 }
9526 }
9527
9076 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9528 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9077 if (avatar != null) 9529 if (avatar != null)
9078 { 9530 {
@@ -9080,6 +9532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9080 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9532 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9081 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9533 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9082 } 9534 }
9535
9083 ScriptSleep(1000); 9536 ScriptSleep(1000);
9084 } 9537 }
9085 9538
@@ -9159,14 +9612,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9159 if (objectID == UUID.Zero) return; 9612 if (objectID == UUID.Zero) return;
9160 9613
9161 UUID agentID; 9614 UUID agentID;
9162 lock (m_host.TaskInventory) 9615 m_host.TaskInventory.LockItemsForRead(true);
9163 { 9616 // we need the permission first, to know which avatar we want to set the camera for
9164 // we need the permission first, to know which avatar we want to set the camera for 9617 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9165 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9166 9618
9167 if (agentID == UUID.Zero) return; 9619 if (agentID == UUID.Zero)
9168 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9620 {
9621 m_host.TaskInventory.LockItemsForRead(false);
9622 return;
9623 }
9624 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9625 {
9626 m_host.TaskInventory.LockItemsForRead(false);
9627 return;
9169 } 9628 }
9629 m_host.TaskInventory.LockItemsForRead(false);
9170 9630
9171 ScenePresence presence = World.GetScenePresence(agentID); 9631 ScenePresence presence = World.GetScenePresence(agentID);
9172 9632
@@ -9216,12 +9676,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9216 9676
9217 // we need the permission first, to know which avatar we want to clear the camera for 9677 // we need the permission first, to know which avatar we want to clear the camera for
9218 UUID agentID; 9678 UUID agentID;
9219 lock (m_host.TaskInventory) 9679 m_host.TaskInventory.LockItemsForRead(true);
9680 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9681 if (agentID == UUID.Zero)
9682 {
9683 m_host.TaskInventory.LockItemsForRead(false);
9684 return;
9685 }
9686 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9220 { 9687 {
9221 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9688 m_host.TaskInventory.LockItemsForRead(false);
9222 if (agentID == UUID.Zero) return; 9689 return;
9223 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9224 } 9690 }
9691 m_host.TaskInventory.LockItemsForRead(false);
9225 9692
9226 ScenePresence presence = World.GetScenePresence(agentID); 9693 ScenePresence presence = World.GetScenePresence(agentID);
9227 9694
@@ -9288,19 +9755,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9288 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 9755 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9289 { 9756 {
9290 m_host.AddScriptLPS(1); 9757 m_host.AddScriptLPS(1);
9291 string ret = String.Empty; 9758
9292 string src1 = llBase64ToString(str1); 9759 if (str1 == String.Empty)
9293 string src2 = llBase64ToString(str2); 9760 return String.Empty;
9294 int c = 0; 9761 if (str2 == String.Empty)
9295 for (int i = 0; i < src1.Length; i++) 9762 return str1;
9763
9764 byte[] data1 = Convert.FromBase64String(str1);
9765 byte[] data2 = Convert.FromBase64String(str2);
9766
9767 byte[] d2 = new Byte[data1.Length];
9768 int pos = 0;
9769
9770 if (data1.Length <= data2.Length)
9296 { 9771 {
9297 ret += (char) (src1[i] ^ src2[c]); 9772 Array.Copy(data2, 0, d2, 0, data1.Length);
9773 }
9774 else
9775 {
9776 while (pos < data1.Length)
9777 {
9778 int len = data1.Length - pos;
9779 if (len > data2.Length)
9780 len = data2.Length;
9298 9781
9299 c++; 9782 Array.Copy(data2, 0, d2, pos, len);
9300 if (c >= src2.Length) 9783 pos += len;
9301 c = 0; 9784 }
9302 } 9785 }
9303 return llStringToBase64(ret); 9786
9787 for (pos = 0 ; pos < data1.Length ; pos++ )
9788 data1[pos] ^= d2[pos];
9789
9790 return Convert.ToBase64String(data1);
9304 } 9791 }
9305 9792
9306 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 9793 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9678,15 +10165,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 10165
9679 internal UUID ScriptByName(string name) 10166 internal UUID ScriptByName(string name)
9680 { 10167 {
9681 lock (m_host.TaskInventory) 10168 m_host.TaskInventory.LockItemsForRead(true);
10169
10170 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9682 { 10171 {
9683 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10172 if (item.Type == 10 && item.Name == name)
9684 { 10173 {
9685 if (item.Type == 10 && item.Name == name) 10174 m_host.TaskInventory.LockItemsForRead(false);
9686 return item.ItemID; 10175 return item.ItemID;
9687 } 10176 }
9688 } 10177 }
9689 10178
10179 m_host.TaskInventory.LockItemsForRead(false);
10180
9690 return UUID.Zero; 10181 return UUID.Zero;
9691 } 10182 }
9692 10183
@@ -9727,6 +10218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9727 { 10218 {
9728 m_host.AddScriptLPS(1); 10219 m_host.AddScriptLPS(1);
9729 10220
10221 //Clone is thread safe
9730 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10222 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9731 10223
9732 UUID assetID = UUID.Zero; 10224 UUID assetID = UUID.Zero;
@@ -9789,6 +10281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9789 { 10281 {
9790 m_host.AddScriptLPS(1); 10282 m_host.AddScriptLPS(1);
9791 10283
10284 //Clone is thread safe
9792 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10285 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9793 10286
9794 UUID assetID = UUID.Zero; 10287 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index fe71ed5..1fa8c30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -73,6 +73,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 74 m_LSFunctionsEnabled = true;
75 75
76 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
77 m_LSFunctionsEnabled = true;
78
76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); 79 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
77 if (m_comms == null) 80 if (m_comms == null)
78 m_LSFunctionsEnabled = false; 81 m_LSFunctionsEnabled = false;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 01b64eb..db43902 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -769,18 +769,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
769 if (target != null) 769 if (target != null)
770 { 770 {
771 UUID animID=UUID.Zero; 771 UUID animID=UUID.Zero;
772 lock (m_host.TaskInventory) 772 m_host.TaskInventory.LockItemsForRead(true);
773 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
773 { 774 {
774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 775 if (inv.Value.Name == animation)
775 { 776 {
776 if (inv.Value.Name == animation) 777 if (inv.Value.Type == (int)AssetType.Animation)
777 { 778 animID = inv.Value.AssetID;
778 if (inv.Value.Type == (int)AssetType.Animation) 779 continue;
779 animID = inv.Value.AssetID;
780 continue;
781 }
782 } 780 }
783 } 781 }
782 m_host.TaskInventory.LockItemsForRead(false);
784 if (animID == UUID.Zero) 783 if (animID == UUID.Zero)
785 target.Animator.AddAnimation(animation, m_host.UUID); 784 target.Animator.AddAnimation(animation, m_host.UUID);
786 else 785 else
@@ -802,18 +801,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
802 if (target != null) 801 if (target != null)
803 { 802 {
804 UUID animID=UUID.Zero; 803 UUID animID=UUID.Zero;
805 lock (m_host.TaskInventory) 804 m_host.TaskInventory.LockItemsForRead(true);
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
806 { 806 {
807 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 807 if (inv.Value.Name == animation)
808 { 808 {
809 if (inv.Value.Name == animation) 809 if (inv.Value.Type == (int)AssetType.Animation)
810 { 810 animID = inv.Value.AssetID;
811 if (inv.Value.Type == (int)AssetType.Animation) 811 continue;
812 animID = inv.Value.AssetID;
813 continue;
814 }
815 } 812 }
816 } 813 }
814 m_host.TaskInventory.LockItemsForRead(false);
817 815
818 if (animID == UUID.Zero) 816 if (animID == UUID.Zero)
819 target.Animator.RemoveAnimation(animation); 817 target.Animator.RemoveAnimation(animation);
@@ -1664,6 +1662,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1664 1662
1665 if (!UUID.TryParse(name, out assetID)) 1663 if (!UUID.TryParse(name, out assetID))
1666 { 1664 {
1665 m_host.TaskInventory.LockItemsForRead(true);
1667 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1666 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1668 { 1667 {
1669 if (item.Type == 7 && item.Name == name) 1668 if (item.Type == 7 && item.Name == name)
@@ -1671,6 +1670,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1671 assetID = item.AssetID; 1670 assetID = item.AssetID;
1672 } 1671 }
1673 } 1672 }
1673 m_host.TaskInventory.LockItemsForRead(false);
1674 } 1674 }
1675 1675
1676 if (assetID == UUID.Zero) 1676 if (assetID == UUID.Zero)
@@ -1717,6 +1717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1717 1717
1718 if (!UUID.TryParse(name, out assetID)) 1718 if (!UUID.TryParse(name, out assetID))
1719 { 1719 {
1720 m_host.TaskInventory.LockItemsForRead(true);
1720 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1721 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1721 { 1722 {
1722 if (item.Type == 7 && item.Name == name) 1723 if (item.Type == 7 && item.Name == name)
@@ -1724,6 +1725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 assetID = item.AssetID; 1725 assetID = item.AssetID;
1725 } 1726 }
1726 } 1727 }
1728 m_host.TaskInventory.LockItemsForRead(false);
1727 } 1729 }
1728 1730
1729 if (assetID == UUID.Zero) 1731 if (assetID == UUID.Zero)
@@ -1774,6 +1776,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1776
1775 if (!UUID.TryParse(name, out assetID)) 1777 if (!UUID.TryParse(name, out assetID))
1776 { 1778 {
1779 m_host.TaskInventory.LockItemsForRead(true);
1777 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1780 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1778 { 1781 {
1779 if (item.Type == 7 && item.Name == name) 1782 if (item.Type == 7 && item.Name == name)
@@ -1781,6 +1784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1781 assetID = item.AssetID; 1784 assetID = item.AssetID;
1782 } 1785 }
1783 } 1786 }
1787 m_host.TaskInventory.LockItemsForRead(false);
1784 } 1788 }
1785 1789
1786 if (assetID == UUID.Zero) 1790 if (assetID == UUID.Zero)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c2abd5..a5b1124 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 309 // in mouselook.
310 310
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
312 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 313 q = avatar.Rotation;
313 } 314 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 423 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 424 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment)
427 {
428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook.
431
432 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
433 fromRegionPos = avatar.AbsolutePosition;
434 q = avatar.Rotation;
435 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 436 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 437 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 438 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 78ee43c..c8f3623 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
81 // Avatar Info Commands 81 // Avatar Info Commands
82 string osGetAgentIP(string agent); 82 string osGetAgentIP(string agent);
83 LSL_List osGetAgents(); 83 LSL_List osGetAgents();
84 84
85 // Teleport commands 85 // Teleport commands
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dba6502..96f6486 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -274,6 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
274 public const int CHANGED_ALLOWED_DROP = 64; 274 public const int CHANGED_ALLOWED_DROP = 64;
275 public const int CHANGED_OWNER = 128; 275 public const int CHANGED_OWNER = 128;
276 public const int CHANGED_REGION_RESTART = 256; 276 public const int CHANGED_REGION_RESTART = 256;
277 public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART
277 public const int CHANGED_REGION = 512; 278 public const int CHANGED_REGION = 512;
278 public const int CHANGED_TELEPORT = 1024; 279 public const int CHANGED_TELEPORT = 1024;
279 public const int CHANGED_ANIMATION = 16384; 280 public const int CHANGED_ANIMATION = 16384;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3339995..e86d08c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index f8dbe03..8280ca5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,5 +72,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
76 public LSL_List cmGetWindlightScene(LSL_List rules)
77 {
78 return m_LS_Functions.lsGetWindlightScene(rules);
79 }
80
81 public int cmSetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsSetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
87 {
88 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
89 }
75 } 90 }
76} 91}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 3dd381d..b348403 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -429,14 +429,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 429 {
430 int permsMask; 430 int permsMask;
431 UUID permsGranter; 431 UUID permsGranter;
432 lock (part.TaskInventory) 432 part.TaskInventory.LockItemsForRead(true);
433 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 434 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 435 part.TaskInventory.LockItemsForRead(false);
435 return; 436 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 437 }
438 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
439 permsMask = part.TaskInventory[m_ItemID].PermsMask;
440 part.TaskInventory.LockItemsForRead(false);
440 441
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 442 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 443 {
@@ -545,6 +546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 546 return true;
546 } 547 }
547 548
549 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 550 public void SetState(string state)
549 { 551 {
550 if (state == State) 552 if (state == State)
@@ -556,7 +558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 558 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 559 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 560 new DetectParams[0]));
559 561
560 throw new EventAbortException(); 562 throw new EventAbortException();
561 } 563 }
562 564
@@ -639,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 641 /// <returns></returns>
640 public object EventProcessor() 642 public object EventProcessor()
641 { 643 {
642 if (m_Suspended) 644 EventParams data = null;
643 return 0;
644 645
645 lock (m_Script) 646 lock (m_EventQueue)
646 { 647 {
647 EventParams data = null; 648 if (m_Suspended)
649 return 0;
648 650
649 lock (m_EventQueue) 651 lock (m_Script)
650 { 652 {
651 data = (EventParams) m_EventQueue.Dequeue(); 653 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 654 if (data == null) // Shouldn't happen
@@ -672,6 +674,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 674 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 675 m_CollisionInQueue = false;
674 } 676 }
677 }
678 lock(m_Script)
679 {
675 680
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 682
@@ -828,6 +833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 833 new Object[0], new DetectParams[0]));
829 } 834 }
830 835
836 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 837 public void ApiResetScript()
832 { 838 {
833 // bool running = Running; 839 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }