aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1878
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-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/ILSL_Api.cs1
-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.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs47
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs341
15 files changed, 1612 insertions, 836 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 1a13dea..8f05359 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -288,40 +346,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 346 protected UUID InventorySelf()
289 { 347 {
290 UUID invItemID = new UUID(); 348 UUID invItemID = new UUID();
291 349 bool unlock = false;
292 lock (m_host.TaskInventory) 350 if (!m_host.TaskInventory.IsReadLockedByMe())
351 {
352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 356 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 357 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 358 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 359 invItemID = inv.Key;
297 { 360 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 361 }
302 } 362 }
303 363 if (unlock)
364 {
365 m_host.TaskInventory.LockItemsForRead(false);
366 }
304 return invItemID; 367 return invItemID;
305 } 368 }
306 369
307 protected UUID InventoryKey(string name, int type) 370 protected UUID InventoryKey(string name, int type)
308 { 371 {
309 m_host.AddScriptLPS(1); 372 m_host.AddScriptLPS(1);
310 373 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 374
375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 376 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 377 if (inv.Value.Name == name)
314 { 378 {
315 if (inv.Value.Name == name) 379 m_host.TaskInventory.LockItemsForRead(false);
380
381 if (inv.Value.Type != type)
316 { 382 {
317 if (inv.Value.Type != type) 383 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 384 }
385
386 return inv.Value.AssetID;
322 } 387 }
323 } 388 }
324 389
390 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 391 return UUID.Zero;
326 } 392 }
327 393
@@ -329,17 +395,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 395 {
330 m_host.AddScriptLPS(1); 396 m_host.AddScriptLPS(1);
331 397
332 lock (m_host.TaskInventory) 398
399 m_host.TaskInventory.LockItemsForRead(true);
400
401 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 402 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 403 if (inv.Value.Name == name)
335 { 404 {
336 if (inv.Value.Name == name) 405 m_host.TaskInventory.LockItemsForRead(false);
337 { 406 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 407 }
341 } 408 }
342 409
410 m_host.TaskInventory.LockItemsForRead(false);
411
412
343 return UUID.Zero; 413 return UUID.Zero;
344 } 414 }
345 415
@@ -481,26 +551,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 551
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 552 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 553
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 554 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
486 555
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 556 // normalize an angle between -PI and PI (-180 to +180 degrees)
557 protected double NormalizeAngle(double angle)
558 {
559 if (angle > -Math.PI && angle < Math.PI)
560 return angle;
561
562 int numPis = (int)(Math.PI / angle);
563 double remainder = angle - Math.PI * numPis;
564 if (numPis % 2 == 1)
565 return Math.PI - angle;
566 return remainder;
567 }
568
569 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 570 {
489 m_host.AddScriptLPS(1); 571 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 572 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 573
492 double m = (t.x + t.y + t.z + t.s); 574 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 575 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 576 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 577 double sqz = q1.y*q1.y;
496 if (p > 0) 578 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 579 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 580 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 581 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 582 eul.y = Math.PI/2;
501 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)); 583 eul.x = 0;
502 else 584 return eul;
503 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)); 585 }
586 if (test < -0.4999*unit) { // singularity at south pole
587 eul.z = -2 * Math.Atan2(q1.x,q1.s);
588 eul.y = -Math.PI/2;
589 eul.x = 0;
590 return eul;
591 }
592 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
593 eul.y = Math.Asin(2*test/unit);
594 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
595 return eul;
504 } 596 }
505 597
506 /* From wiki: 598 /* From wiki:
@@ -702,77 +794,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 794 {
703 //A and B should both be normalized 795 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 796 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 797 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 798 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 799
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 800 double dotProduct = LSL_Vector.Dot(a, b);
709 { 801 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 802 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
711 } 803 double angle = Math.Acos(dotProduct / magProduct);
712 else 804 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
713 { 805 double s = Math.Sin(angle / 2);
714 a = LSL_Vector.Norm(a); 806
715 b = LSL_Vector.Norm(b); 807 double x = axis.x * s;
716 double dotProduct = LSL_Vector.Dot(a, b); 808 double y = axis.y * s;
717 // There are two degenerate cases possible. These are for vectors 180 or 809 double z = axis.z * s;
718 // 0 degrees apart. These have to be detected and handled individually. 810 double w = Math.Cos(angle / 2);
719 // 811
720 // Check for vectors 180 degrees apart. 812 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 813 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
722 if (dotProduct < -0.9999999f) 814
723 { 815 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
724 // First assume X axis is orthogonal to the vectors. 816 */
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 817
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 818 // This method mimics the 180 errors found in SL
727 // Check for near zero vector. A very small non-zero number here will create 819 // See www.euclideanspace.com... angleBetween
728 // a rotation in an undesired direction. 820 LSL_Vector vec_a = a;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 821 LSL_Vector vec_b = b;
730 { 822
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 823 // Eliminate zero length
732 } 824 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
733 // If the magnitude of the vector was near zero, then assume the X axis is not 825 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
734 // orthogonal and use the Z axis instead. 826 if (vec_a_mag < 0.00001 ||
735 else 827 vec_b_mag < 0.00001)
736 { 828 {
737 // Set 180 z rotation. 829 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 830 }
739 } 831
740 } 832 // Normalize
741 // Check for parallel vectors. 833 vec_a = llVecNorm(vec_a);
742 // A dot product of 1 would mean the angle between vectors is 0 degrees. 834 vec_b = llVecNorm(vec_b);
743 else if (dotProduct > 0.9999999f) 835
744 { 836 // Calculate axis and rotation angle
745 // Set zero rotation. 837 LSL_Vector axis = vec_a % vec_b;
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 838 LSL_Float cos_theta = vec_a * vec_b;
747 } 839
748 else 840 // Check if parallel
749 { 841 if (cos_theta > 0.99999)
750 // All special checks have been performed so get the axis of rotation. 842 {
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
752 // Quarternion s value is the length of the unit vector + dot product. 844 }
753 double qs = 1.0 + dotProduct; 845
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 846 // Check if anti-parallel
755 // Normalize the rotation. 847 else if (cos_theta < -0.99999)
756 double mag = LSL_Rotation.Mag(rotBetween); 848 {
757 // We shouldn't have to worry about a divide by zero here. The qs value will be 849 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so 850 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the 851 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
760 // crossProduct vector should also not be zero. 852 }
761 rotBetween.x = rotBetween.x / mag; 853 else // other rotation
762 rotBetween.y = rotBetween.y / mag; 854 {
763 rotBetween.z = rotBetween.z / mag; 855 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
764 rotBetween.s = rotBetween.s / mag; 856 axis = llVecNorm(axis);
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required 857 double x, y, z, s, t;
766 // any longer since zero vectors are checked for at the top. 858 s = Math.Cos(theta);
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 859 t = Math.Sin(theta);
768 { 860 x = axis.x * t;
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 861 y = axis.y * t;
770 } 862 z = axis.z * t;
771 } 863 return new LSL_Rotation(x,y,z,s);
772 } 864 }
773 return rotBetween; 865 }
774 } 866
775
776 public void llWhisper(int channelID, string text) 867 public void llWhisper(int channelID, string text)
777 { 868 {
778 m_host.AddScriptLPS(1); 869 m_host.AddScriptLPS(1);
@@ -1096,10 +1187,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1187 return detectedParams.TouchUV;
1097 } 1188 }
1098 1189
1190 [DebuggerNonUserCode]
1099 public virtual void llDie() 1191 public virtual void llDie()
1100 { 1192 {
1101 m_host.AddScriptLPS(1); 1193 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1194 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1195 }
1104 1196
1105 public LSL_Float llGround(LSL_Vector offset) 1197 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1264
1173 public void llSetStatus(int status, int value) 1265 public void llSetStatus(int status, int value)
1174 { 1266 {
1267 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1268 return;
1175 m_host.AddScriptLPS(1); 1269 m_host.AddScriptLPS(1);
1176 1270
1177 int statusrotationaxis = 0; 1271 int statusrotationaxis = 0;
@@ -1402,6 +1496,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1496 {
1403 m_host.AddScriptLPS(1); 1497 m_host.AddScriptLPS(1);
1404 1498
1499 SetColor(m_host, color, face);
1500 }
1501
1502 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1503 {
1504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1505 return;
1506
1507 Primitive.TextureEntry tex = part.Shape.Textures;
1508 Color4 texcolor;
1509 if (face >= 0 && face < GetNumberOfSides(part))
1510 {
1511 texcolor = tex.CreateFace((uint)face).RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[face].RGBA = texcolor;
1516 part.UpdateTexture(tex);
1517 return;
1518 }
1519 else if (face == ScriptBaseClass.ALL_SIDES)
1520 {
1521 for (uint i = 0; i < GetNumberOfSides(part); i++)
1522 {
1523 if (tex.FaceTextures[i] != null)
1524 {
1525 texcolor = tex.FaceTextures[i].RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[i].RGBA = texcolor;
1530 }
1531 texcolor = tex.DefaultTexture.RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.DefaultTexture.RGBA = texcolor;
1536 }
1537 part.UpdateTexture(tex);
1538 return;
1539 }
1540
1405 if (face == ScriptBaseClass.ALL_SIDES) 1541 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1542 face = SceneObjectPart.ALL_SIDES;
1407 1543
@@ -1410,6 +1546,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1546
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1547 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1548 {
1549 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1550 return;
1551
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1553 MappingType textype;
1415 textype = MappingType.Default; 1554 textype = MappingType.Default;
@@ -1440,6 +1579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1579
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1581 {
1582 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1583 return;
1584
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1585 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1586 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1587 {
@@ -1465,6 +1607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1607
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1608 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1468 1612
1469 Shininess sval = new Shininess(); 1613 Shininess sval = new Shininess();
1470 1614
@@ -1515,6 +1659,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1659
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1660 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1661 {
1662 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return;
1664
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1665 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1666 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1667 {
@@ -1575,13 +1722,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1722 m_host.AddScriptLPS(1);
1576 1723
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1724 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1725 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1726 {
1580 SetAlpha(part, alpha, face); 1727 try
1728 {
1729 parts[0].ParentGroup.areUpdatesSuspended = true;
1730 foreach (SceneObjectPart part in parts)
1731 SetAlpha(part, alpha, face);
1732 }
1733 finally
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = false;
1736 }
1737 }
1581 } 1738 }
1582 1739
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1740 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1741 {
1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1743 return;
1744
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1745 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1746 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1747 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1787 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1788 float wind, float tension, LSL_Vector Force)
1629 { 1789 {
1630 if (part == null) 1790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1791 return;
1632 1792
1633 if (flexi) 1793 if (flexi)
@@ -1662,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1822 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1823 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1824 {
1665 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1826 return;
1667 1827
1668 if (light) 1828 if (light)
@@ -1739,15 +1899,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1899 m_host.AddScriptLPS(1);
1740 1900
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1901 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1902 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1903 {
1744 SetTexture(part, texture, face); 1904 try
1745 1905 {
1906 parts[0].ParentGroup.areUpdatesSuspended = true;
1907 foreach (SceneObjectPart part in parts)
1908 SetTexture(part, texture, face);
1909 }
1910 finally
1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = false;
1913 }
1914 }
1746 ScriptSleep(200); 1915 ScriptSleep(200);
1747 } 1916 }
1748 1917
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1918 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1919 {
1920 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1921 return;
1922
1751 UUID textureID=new UUID(); 1923 UUID textureID=new UUID();
1752 1924
1753 if (!UUID.TryParse(texture, out textureID)) 1925 if (!UUID.TryParse(texture, out textureID))
@@ -1793,6 +1965,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1793 1965
1794 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1966 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1795 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1796 Primitive.TextureEntry tex = part.Shape.Textures; 1971 Primitive.TextureEntry tex = part.Shape.Textures;
1797 if (face >= 0 && face < GetNumberOfSides(part)) 1972 if (face >= 0 && face < GetNumberOfSides(part))
1798 { 1973 {
@@ -1829,6 +2004,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1829 2004
1830 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2005 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1831 { 2006 {
2007 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2008 return;
2009
1832 Primitive.TextureEntry tex = part.Shape.Textures; 2010 Primitive.TextureEntry tex = part.Shape.Textures;
1833 if (face >= 0 && face < GetNumberOfSides(part)) 2011 if (face >= 0 && face < GetNumberOfSides(part))
1834 { 2012 {
@@ -1865,6 +2043,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 2043
1866 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2044 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1867 { 2045 {
2046 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2047 return;
2048
1868 Primitive.TextureEntry tex = part.Shape.Textures; 2049 Primitive.TextureEntry tex = part.Shape.Textures;
1869 if (face >= 0 && face < GetNumberOfSides(part)) 2050 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2051 {
@@ -1935,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1935 2116
1936 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2117 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1937 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1938 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2122 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1939 LSL_Vector currentPos = GetPartLocalPos(part); 2123 LSL_Vector currentPos = GetPartLocalPos(part);
1940 2124
@@ -1951,7 +2135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 } 2135 }
1952 else 2136 else
1953 { 2137 {
1954 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2138 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1955 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2139 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1956 SceneObjectGroup parent = part.ParentGroup; 2140 SceneObjectGroup parent = part.ParentGroup;
1957 parent.HasGroupChanged = true; 2141 parent.HasGroupChanged = true;
@@ -2003,9 +2187,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2003 m_host.AddScriptLPS(1); 2187 m_host.AddScriptLPS(1);
2004 2188
2005 // try to let this work as in SL... 2189 // try to let this work as in SL...
2006 if (m_host.ParentID == 0) 2190 if (m_host.LinkNum < 2)
2007 { 2191 {
2008 // special case: If we are root, rotate complete SOG to new rotation 2192 // Special case: If we are root, rotate complete SOG to new
2193 // rotation.
2194 // We are root if the link number is 0 (single prim) or 1
2195 // (root prim). ParentID may be nonzero in attachments and
2196 // using it would cause attachments and HUDs to rotate
2197 // to the wrong positions.
2009 SetRot(m_host, Rot2Quaternion(rot)); 2198 SetRot(m_host, Rot2Quaternion(rot));
2010 } 2199 }
2011 else 2200 else
@@ -2034,6 +2223,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2034 2223
2035 protected void SetRot(SceneObjectPart part, Quaternion rot) 2224 protected void SetRot(SceneObjectPart part, Quaternion rot)
2036 { 2225 {
2226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2227 return;
2228
2037 part.UpdateRotation(rot); 2229 part.UpdateRotation(rot);
2038 // Update rotation does not move the object in the physics scene if it's a linkset. 2230 // Update rotation does not move the object in the physics scene if it's a linkset.
2039 2231
@@ -2653,12 +2845,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2653 2845
2654 m_host.AddScriptLPS(1); 2846 m_host.AddScriptLPS(1);
2655 2847
2848 m_host.TaskInventory.LockItemsForRead(true);
2656 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2849 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2657 2850 m_host.TaskInventory.LockItemsForRead(false);
2658 lock (m_host.TaskInventory)
2659 {
2660 item = m_host.TaskInventory[invItemID];
2661 }
2662 2851
2663 if (item.PermsGranter == UUID.Zero) 2852 if (item.PermsGranter == UUID.Zero)
2664 return 0; 2853 return 0;
@@ -2733,6 +2922,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2733 if (dist > m_ScriptDistanceFactor * 10.0f) 2922 if (dist > m_ScriptDistanceFactor * 10.0f)
2734 return; 2923 return;
2735 2924
2925 //Clone is thread-safe
2736 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2926 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2737 2927
2738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2795,6 +2985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 2985
2796 public void llLookAt(LSL_Vector target, double strength, double damping) 2986 public void llLookAt(LSL_Vector target, double strength, double damping)
2797 { 2987 {
2988 /*
2798 m_host.AddScriptLPS(1); 2989 m_host.AddScriptLPS(1);
2799 // Determine where we are looking from 2990 // Determine where we are looking from
2800 LSL_Vector from = llGetPos(); 2991 LSL_Vector from = llGetPos();
@@ -2814,10 +3005,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 // the angles of rotation in radians into rotation value 3005 // the angles of rotation in radians into rotation value
2815 3006
2816 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3007 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2817 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3008
2818 m_host.startLookAt(rotation, (float)damping, (float)strength); 3009 // This would only work if your physics system contains an APID controller:
3010 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3011 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3012
2819 // Orient the object to the angle calculated 3013 // Orient the object to the angle calculated
2820 //llSetRot(rot); 3014 llSetRot(rot);
3015 */
3016
3017 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3018 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3019 // http://bugs.meta7.com/view.php?id=28
3020 // - Tom
3021
3022 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3023 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3024
3025 }
3026
3027 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3028 {
3029 m_host.AddScriptLPS(1);
3030// NotImplemented("llRotLookAt");
3031 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3032
2821 } 3033 }
2822 3034
2823 public void llStopLookAt() 3035 public void llStopLookAt()
@@ -2866,13 +3078,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2866 { 3078 {
2867 TaskInventoryItem item; 3079 TaskInventoryItem item;
2868 3080
2869 lock (m_host.TaskInventory) 3081 m_host.TaskInventory.LockItemsForRead(true);
3082 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2870 { 3083 {
2871 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3084 m_host.TaskInventory.LockItemsForRead(false);
2872 return; 3085 return;
2873 else 3086 }
2874 item = m_host.TaskInventory[InventorySelf()]; 3087 else
3088 {
3089 item = m_host.TaskInventory[InventorySelf()];
2875 } 3090 }
3091 m_host.TaskInventory.LockItemsForRead(false);
2876 3092
2877 if (item.PermsGranter != UUID.Zero) 3093 if (item.PermsGranter != UUID.Zero)
2878 { 3094 {
@@ -2894,13 +3110,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 { 3110 {
2895 TaskInventoryItem item; 3111 TaskInventoryItem item;
2896 3112
3113 m_host.TaskInventory.LockItemsForRead(true);
2897 lock (m_host.TaskInventory) 3114 lock (m_host.TaskInventory)
2898 { 3115 {
3116
2899 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3117 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3118 {
3119 m_host.TaskInventory.LockItemsForRead(false);
2900 return; 3120 return;
3121 }
2901 else 3122 else
3123 {
2902 item = m_host.TaskInventory[InventorySelf()]; 3124 item = m_host.TaskInventory[InventorySelf()];
3125 }
2903 } 3126 }
3127 m_host.TaskInventory.LockItemsForRead(false);
2904 3128
2905 m_host.AddScriptLPS(1); 3129 m_host.AddScriptLPS(1);
2906 3130
@@ -2932,19 +3156,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 { 3156 {
2933 m_host.AddScriptLPS(1); 3157 m_host.AddScriptLPS(1);
2934 3158
2935 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2936 return;
2937
2938 TaskInventoryItem item; 3159 TaskInventoryItem item;
2939 3160
2940 lock (m_host.TaskInventory) 3161 m_host.TaskInventory.LockItemsForRead(true);
3162
3163 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2941 { 3164 {
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3165 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3166 return;
2944 else 3167 }
2945 item = m_host.TaskInventory[InventorySelf()]; 3168 else
3169 {
3170 item = m_host.TaskInventory[InventorySelf()];
2946 } 3171 }
2947 3172
3173 m_host.TaskInventory.LockItemsForRead(false);
3174
2948 if (item.PermsGranter != m_host.OwnerID) 3175 if (item.PermsGranter != m_host.OwnerID)
2949 return; 3176 return;
2950 3177
@@ -2954,10 +3181,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3181
2955 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3182 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2956 3183
2957 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3184 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2958 if (attachmentsModule != null)
2959 attachmentsModule.AttachObject(presence.ControllingClient,
2960 grp, (uint)attachment, false);
2961 } 3185 }
2962 } 3186 }
2963 3187
@@ -2970,13 +3194,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2970 3194
2971 TaskInventoryItem item; 3195 TaskInventoryItem item;
2972 3196
2973 lock (m_host.TaskInventory) 3197 m_host.TaskInventory.LockItemsForRead(true);
3198
3199 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2974 { 3200 {
2975 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3201 m_host.TaskInventory.LockItemsForRead(false);
2976 return; 3202 return;
2977 else 3203 }
2978 item = m_host.TaskInventory[InventorySelf()]; 3204 else
3205 {
3206 item = m_host.TaskInventory[InventorySelf()];
2979 } 3207 }
3208 m_host.TaskInventory.LockItemsForRead(false);
3209
2980 3210
2981 if (item.PermsGranter != m_host.OwnerID) 3211 if (item.PermsGranter != m_host.OwnerID)
2982 return; 3212 return;
@@ -3015,6 +3245,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 3245
3016 public void llInstantMessage(string user, string message) 3246 public void llInstantMessage(string user, string message)
3017 { 3247 {
3248 UUID result;
3249 if (!UUID.TryParse(user, out result))
3250 {
3251 ShoutError("An invalid key was passed to llInstantMessage");
3252 ScriptSleep(2000);
3253 return;
3254 }
3255
3256
3018 m_host.AddScriptLPS(1); 3257 m_host.AddScriptLPS(1);
3019 3258
3020 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3259 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3029,14 +3268,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3029 UUID friendTransactionID = UUID.Random(); 3268 UUID friendTransactionID = UUID.Random();
3030 3269
3031 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3270 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3032 3271
3033 GridInstantMessage msg = new GridInstantMessage(); 3272 GridInstantMessage msg = new GridInstantMessage();
3034 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3273 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3035 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3274 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3036 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3275 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3037// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3276// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3038// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3277// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3039 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3278 DateTime dt = DateTime.UtcNow;
3279
3280 // Ticks from UtcNow, but make it look like local. Evil, huh?
3281 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3282
3283 try
3284 {
3285 // Convert that to the PST timezone
3286 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3287 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3288 }
3289 catch
3290 {
3291 // No logging here, as it could be VERY spammy
3292 }
3293
3294 // And make it look local again to fool the unix time util
3295 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3296
3297 msg.timestamp = (uint)Util.ToUnixTime(dt);
3298
3040 //if (client != null) 3299 //if (client != null)
3041 //{ 3300 //{
3042 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3301 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3050,13 +3309,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 msg.message = message.Substring(0, 1024); 3309 msg.message = message.Substring(0, 1024);
3051 else 3310 else
3052 msg.message = message; 3311 msg.message = message;
3053 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3312 msg.dialog = (byte)19; // MessageFromObject
3054 msg.fromGroup = false;// fromGroup; 3313 msg.fromGroup = false;// fromGroup;
3055 msg.offline = (byte)0; //offline; 3314 msg.offline = (byte)0; //offline;
3056 msg.ParentEstateID = 0; //ParentEstateID; 3315 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3057 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3316 msg.Position = new Vector3(m_host.AbsolutePosition);
3058 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3317 msg.RegionID = World.RegionInfo.RegionID.Guid;
3059 msg.binaryBucket = new byte[0];// binaryBucket; 3318 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3060 3319
3061 if (m_TransferModule != null) 3320 if (m_TransferModule != null)
3062 { 3321 {
@@ -3076,7 +3335,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3076 } 3335 }
3077 3336
3078 emailModule.SendEmail(m_host.UUID, address, subject, message); 3337 emailModule.SendEmail(m_host.UUID, address, subject, message);
3079 ScriptSleep(20000); 3338 ScriptSleep(15000);
3080 } 3339 }
3081 3340
3082 public void llGetNextEmail(string address, string subject) 3341 public void llGetNextEmail(string address, string subject)
@@ -3178,13 +3437,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3178 m_host.AddScriptLPS(1); 3437 m_host.AddScriptLPS(1);
3179 } 3438 }
3180 3439
3181 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3182 {
3183 m_host.AddScriptLPS(1);
3184 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3185 m_host.RotLookAt(rot, (float)strength, (float)damping);
3186 }
3187
3188 public LSL_Integer llStringLength(string str) 3440 public LSL_Integer llStringLength(string str)
3189 { 3441 {
3190 m_host.AddScriptLPS(1); 3442 m_host.AddScriptLPS(1);
@@ -3208,14 +3460,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3208 3460
3209 TaskInventoryItem item; 3461 TaskInventoryItem item;
3210 3462
3211 lock (m_host.TaskInventory) 3463 m_host.TaskInventory.LockItemsForRead(true);
3464 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3212 { 3465 {
3213 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3466 m_host.TaskInventory.LockItemsForRead(false);
3214 return; 3467 return;
3215 else
3216 item = m_host.TaskInventory[InventorySelf()];
3217 } 3468 }
3218 3469 else
3470 {
3471 item = m_host.TaskInventory[InventorySelf()];
3472 }
3473 m_host.TaskInventory.LockItemsForRead(false);
3219 if (item.PermsGranter == UUID.Zero) 3474 if (item.PermsGranter == UUID.Zero)
3220 return; 3475 return;
3221 3476
@@ -3245,13 +3500,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3245 3500
3246 TaskInventoryItem item; 3501 TaskInventoryItem item;
3247 3502
3248 lock (m_host.TaskInventory) 3503 m_host.TaskInventory.LockItemsForRead(true);
3504 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3249 { 3505 {
3250 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3506 m_host.TaskInventory.LockItemsForRead(false);
3251 return; 3507 return;
3252 else
3253 item = m_host.TaskInventory[InventorySelf()];
3254 } 3508 }
3509 else
3510 {
3511 item = m_host.TaskInventory[InventorySelf()];
3512 }
3513 m_host.TaskInventory.LockItemsForRead(false);
3514
3255 3515
3256 if (item.PermsGranter == UUID.Zero) 3516 if (item.PermsGranter == UUID.Zero)
3257 return; 3517 return;
@@ -3322,10 +3582,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 3582
3323 TaskInventoryItem item; 3583 TaskInventoryItem item;
3324 3584
3325 lock (m_host.TaskInventory) 3585
3586 m_host.TaskInventory.LockItemsForRead(true);
3587 if (!m_host.TaskInventory.ContainsKey(invItemID))
3588 {
3589 m_host.TaskInventory.LockItemsForRead(false);
3590 return;
3591 }
3592 else
3326 { 3593 {
3327 item = m_host.TaskInventory[invItemID]; 3594 item = m_host.TaskInventory[invItemID];
3328 } 3595 }
3596 m_host.TaskInventory.LockItemsForRead(false);
3329 3597
3330 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3598 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3331 { 3599 {
@@ -3357,11 +3625,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3357 3625
3358 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3626 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3359 { 3627 {
3360 lock (m_host.TaskInventory) 3628 m_host.TaskInventory.LockItemsForWrite(true);
3361 { 3629 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3362 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3630 m_host.TaskInventory[invItemID].PermsMask = perm;
3363 m_host.TaskInventory[invItemID].PermsMask = perm; 3631 m_host.TaskInventory.LockItemsForWrite(false);
3364 }
3365 3632
3366 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3633 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3367 "run_time_permissions", new Object[] { 3634 "run_time_permissions", new Object[] {
@@ -3381,11 +3648,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3381 3648
3382 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3649 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3383 { 3650 {
3384 lock (m_host.TaskInventory) 3651 m_host.TaskInventory.LockItemsForWrite(true);
3385 { 3652 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3386 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3653 m_host.TaskInventory[invItemID].PermsMask = perm;
3387 m_host.TaskInventory[invItemID].PermsMask = perm; 3654 m_host.TaskInventory.LockItemsForWrite(false);
3388 }
3389 3655
3390 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3656 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3391 "run_time_permissions", new Object[] { 3657 "run_time_permissions", new Object[] {
@@ -3406,11 +3672,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 3672
3407 if (!m_waitingForScriptAnswer) 3673 if (!m_waitingForScriptAnswer)
3408 { 3674 {
3409 lock (m_host.TaskInventory) 3675 m_host.TaskInventory.LockItemsForWrite(true);
3410 { 3676 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3411 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3677 m_host.TaskInventory[invItemID].PermsMask = 0;
3412 m_host.TaskInventory[invItemID].PermsMask = 0; 3678 m_host.TaskInventory.LockItemsForWrite(false);
3413 }
3414 3679
3415 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3680 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3416 m_waitingForScriptAnswer=true; 3681 m_waitingForScriptAnswer=true;
@@ -3445,10 +3710,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3445 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3710 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3446 llReleaseControls(); 3711 llReleaseControls();
3447 3712
3448 lock (m_host.TaskInventory) 3713
3449 { 3714 m_host.TaskInventory.LockItemsForWrite(true);
3450 m_host.TaskInventory[invItemID].PermsMask = answer; 3715 m_host.TaskInventory[invItemID].PermsMask = answer;
3451 } 3716 m_host.TaskInventory.LockItemsForWrite(false);
3717
3452 3718
3453 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3719 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3454 "run_time_permissions", new Object[] { 3720 "run_time_permissions", new Object[] {
@@ -3460,16 +3726,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 { 3726 {
3461 m_host.AddScriptLPS(1); 3727 m_host.AddScriptLPS(1);
3462 3728
3463 lock (m_host.TaskInventory) 3729 m_host.TaskInventory.LockItemsForRead(true);
3730
3731 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3464 { 3732 {
3465 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3733 if (item.Type == 10 && item.ItemID == m_itemID)
3466 { 3734 {
3467 if (item.Type == 10 && item.ItemID == m_itemID) 3735 m_host.TaskInventory.LockItemsForRead(false);
3468 { 3736 return item.PermsGranter.ToString();
3469 return item.PermsGranter.ToString();
3470 }
3471 } 3737 }
3472 } 3738 }
3739 m_host.TaskInventory.LockItemsForRead(false);
3473 3740
3474 return UUID.Zero.ToString(); 3741 return UUID.Zero.ToString();
3475 } 3742 }
@@ -3478,19 +3745,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 { 3745 {
3479 m_host.AddScriptLPS(1); 3746 m_host.AddScriptLPS(1);
3480 3747
3481 lock (m_host.TaskInventory) 3748 m_host.TaskInventory.LockItemsForRead(true);
3749
3750 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3482 { 3751 {
3483 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3752 if (item.Type == 10 && item.ItemID == m_itemID)
3484 { 3753 {
3485 if (item.Type == 10 && item.ItemID == m_itemID) 3754 int perms = item.PermsMask;
3486 { 3755 if (m_automaticLinkPermission)
3487 int perms = item.PermsMask; 3756 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3488 if (m_automaticLinkPermission) 3757 m_host.TaskInventory.LockItemsForRead(false);
3489 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3758 return perms;
3490 return perms;
3491 }
3492 } 3759 }
3493 } 3760 }
3761 m_host.TaskInventory.LockItemsForRead(false);
3494 3762
3495 return 0; 3763 return 0;
3496 } 3764 }
@@ -3512,9 +3780,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3780 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3513 { 3781 {
3514 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3782 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3515 3783 if (parts.Count > 0)
3516 foreach (SceneObjectPart part in parts) 3784 {
3517 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3785 try
3786 {
3787 parts[0].ParentGroup.areUpdatesSuspended = true;
3788 foreach (SceneObjectPart part in parts)
3789 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3790 }
3791 finally
3792 {
3793 parts[0].ParentGroup.areUpdatesSuspended = false;
3794 }
3795 }
3518 } 3796 }
3519 3797
3520 public void llCreateLink(string target, int parent) 3798 public void llCreateLink(string target, int parent)
@@ -3527,11 +3805,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 return; 3805 return;
3528 3806
3529 TaskInventoryItem item; 3807 TaskInventoryItem item;
3530 lock (m_host.TaskInventory) 3808 m_host.TaskInventory.LockItemsForRead(true);
3531 { 3809 item = m_host.TaskInventory[invItemID];
3532 item = m_host.TaskInventory[invItemID]; 3810 m_host.TaskInventory.LockItemsForRead(false);
3533 } 3811
3534
3535 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3812 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3536 && !m_automaticLinkPermission) 3813 && !m_automaticLinkPermission)
3537 { 3814 {
@@ -3552,7 +3829,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 3829
3553 if (targetPart != null) 3830 if (targetPart != null)
3554 { 3831 {
3555 if (parent != 0) { 3832 if (parent != 0)
3833 {
3556 parentPrim = m_host.ParentGroup; 3834 parentPrim = m_host.ParentGroup;
3557 childPrim = targetPart.ParentGroup; 3835 childPrim = targetPart.ParentGroup;
3558 } 3836 }
@@ -3584,16 +3862,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3584 m_host.AddScriptLPS(1); 3862 m_host.AddScriptLPS(1);
3585 UUID invItemID = InventorySelf(); 3863 UUID invItemID = InventorySelf();
3586 3864
3587 lock (m_host.TaskInventory) 3865 m_host.TaskInventory.LockItemsForRead(true);
3588 {
3589 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3866 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3590 && !m_automaticLinkPermission) 3867 && !m_automaticLinkPermission)
3591 { 3868 {
3592 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3869 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3870 m_host.TaskInventory.LockItemsForRead(false);
3593 return; 3871 return;
3594 } 3872 }
3595 } 3873 m_host.TaskInventory.LockItemsForRead(false);
3596 3874
3597 if (linknum < ScriptBaseClass.LINK_THIS) 3875 if (linknum < ScriptBaseClass.LINK_THIS)
3598 return; 3876 return;
3599 3877
@@ -3632,10 +3910,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3632 // Restructuring Multiple Prims. 3910 // Restructuring Multiple Prims.
3633 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3911 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3634 parts.Remove(parentPrim.RootPart); 3912 parts.Remove(parentPrim.RootPart);
3635 foreach (SceneObjectPart part in parts) 3913 if (parts.Count > 0)
3636 { 3914 {
3637 parentPrim.DelinkFromGroup(part.LocalId, true); 3915 try
3916 {
3917 parts[0].ParentGroup.areUpdatesSuspended = true;
3918 foreach (SceneObjectPart part in parts)
3919 {
3920 parentPrim.DelinkFromGroup(part.LocalId, true);
3921 }
3922 }
3923 finally
3924 {
3925 parts[0].ParentGroup.areUpdatesSuspended = false;
3926 }
3638 } 3927 }
3928
3639 parentPrim.HasGroupChanged = true; 3929 parentPrim.HasGroupChanged = true;
3640 parentPrim.ScheduleGroupForFullUpdate(); 3930 parentPrim.ScheduleGroupForFullUpdate();
3641 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3931 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3644,11 +3934,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3644 { 3934 {
3645 SceneObjectPart newRoot = parts[0]; 3935 SceneObjectPart newRoot = parts[0];
3646 parts.Remove(newRoot); 3936 parts.Remove(newRoot);
3647 foreach (SceneObjectPart part in parts) 3937
3938 try
3648 { 3939 {
3649 part.UpdateFlag = 0; 3940 parts[0].ParentGroup.areUpdatesSuspended = true;
3650 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3941 foreach (SceneObjectPart part in parts)
3942 {
3943 part.UpdateFlag = 0;
3944 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3945 }
3651 } 3946 }
3947 finally
3948 {
3949 parts[0].ParentGroup.areUpdatesSuspended = false;
3950 }
3951
3952
3652 newRoot.ParentGroup.HasGroupChanged = true; 3953 newRoot.ParentGroup.HasGroupChanged = true;
3653 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3954 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3654 } 3955 }
@@ -3694,6 +3995,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 } 3995 }
3695 else 3996 else
3696 { 3997 {
3998 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
3999 {
4000 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4001
4002 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4003 if (avatars.Count > linknum)
4004 {
4005 return avatars[linknum].UUID.ToString();
4006 }
4007 }
3697 return UUID.Zero.ToString(); 4008 return UUID.Zero.ToString();
3698 } 4009 }
3699 } 4010 }
@@ -3770,17 +4081,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 m_host.AddScriptLPS(1); 4081 m_host.AddScriptLPS(1);
3771 int count = 0; 4082 int count = 0;
3772 4083
3773 lock (m_host.TaskInventory) 4084 m_host.TaskInventory.LockItemsForRead(true);
4085 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3774 { 4086 {
3775 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4087 if (inv.Value.Type == type || type == -1)
3776 { 4088 {
3777 if (inv.Value.Type == type || type == -1) 4089 count = count + 1;
3778 {
3779 count = count + 1;
3780 }
3781 } 4090 }
3782 } 4091 }
3783 4092
4093 m_host.TaskInventory.LockItemsForRead(false);
3784 return count; 4094 return count;
3785 } 4095 }
3786 4096
@@ -3789,16 +4099,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3789 m_host.AddScriptLPS(1); 4099 m_host.AddScriptLPS(1);
3790 ArrayList keys = new ArrayList(); 4100 ArrayList keys = new ArrayList();
3791 4101
3792 lock (m_host.TaskInventory) 4102 m_host.TaskInventory.LockItemsForRead(true);
4103 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3793 { 4104 {
3794 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4105 if (inv.Value.Type == type || type == -1)
3795 { 4106 {
3796 if (inv.Value.Type == type || type == -1) 4107 keys.Add(inv.Value.Name);
3797 {
3798 keys.Add(inv.Value.Name);
3799 }
3800 } 4108 }
3801 } 4109 }
4110 m_host.TaskInventory.LockItemsForRead(false);
3802 4111
3803 if (keys.Count == 0) 4112 if (keys.Count == 0)
3804 { 4113 {
@@ -3835,20 +4144,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3835 } 4144 }
3836 4145
3837 // move the first object found with this inventory name 4146 // move the first object found with this inventory name
3838 lock (m_host.TaskInventory) 4147 m_host.TaskInventory.LockItemsForRead(true);
4148 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3839 { 4149 {
3840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4150 if (inv.Value.Name == inventory)
3841 { 4151 {
3842 if (inv.Value.Name == inventory) 4152 found = true;
3843 { 4153 objId = inv.Key;
3844 found = true; 4154 assetType = inv.Value.Type;
3845 objId = inv.Key; 4155 objName = inv.Value.Name;
3846 assetType = inv.Value.Type; 4156 break;
3847 objName = inv.Value.Name;
3848 break;
3849 }
3850 } 4157 }
3851 } 4158 }
4159 m_host.TaskInventory.LockItemsForRead(false);
3852 4160
3853 if (!found) 4161 if (!found)
3854 { 4162 {
@@ -3856,9 +4164,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4164 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3857 } 4165 }
3858 4166
3859 // check if destination is an avatar 4167 // check if destination is an object
3860 if (World.GetScenePresence(destId) != null) 4168 if (World.GetSceneObjectPart(destId) != null)
4169 {
4170 // destination is an object
4171 World.MoveTaskInventoryItem(destId, m_host, objId);
4172 }
4173 else
3861 { 4174 {
4175 ScenePresence presence = World.GetScenePresence(destId);
4176
4177 if (presence == null)
4178 {
4179 UserAccount account =
4180 World.UserAccountService.GetUserAccount(
4181 World.RegionInfo.ScopeID,
4182 destId);
4183
4184 if (account == null)
4185 {
4186 llSay(0, "Can't find destination "+destId.ToString());
4187 return;
4188 }
4189 }
4190
3862 // destination is an avatar 4191 // destination is an avatar
3863 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4192 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3864 4193
@@ -3882,31 +4211,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3882 4211
3883 if (m_TransferModule != null) 4212 if (m_TransferModule != null)
3884 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4213 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4214
4215 //This delay should only occur when giving inventory to avatars.
4216 ScriptSleep(3000);
3885 } 4217 }
3886 else
3887 {
3888 // destination is an object
3889 World.MoveTaskInventoryItem(destId, m_host, objId);
3890 }
3891 ScriptSleep(3000);
3892 } 4218 }
3893 4219
4220 [DebuggerNonUserCode]
3894 public void llRemoveInventory(string name) 4221 public void llRemoveInventory(string name)
3895 { 4222 {
3896 m_host.AddScriptLPS(1); 4223 m_host.AddScriptLPS(1);
3897 4224
3898 lock (m_host.TaskInventory) 4225 List<TaskInventoryItem> inv;
4226 try
3899 { 4227 {
3900 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4228 m_host.TaskInventory.LockItemsForRead(true);
4229 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4230 }
4231 finally
4232 {
4233 m_host.TaskInventory.LockItemsForRead(false);
4234 }
4235 foreach (TaskInventoryItem item in inv)
4236 {
4237 if (item.Name == name)
3901 { 4238 {
3902 if (item.Name == name) 4239 if (item.ItemID == m_itemID)
3903 { 4240 throw new ScriptDeleteException();
3904 if (item.ItemID == m_itemID) 4241 else
3905 throw new ScriptDeleteException(); 4242 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3906 else 4243 return;
3907 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3908 return;
3909 }
3910 } 4244 }
3911 } 4245 }
3912 } 4246 }
@@ -3972,6 +4306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 ce.time = Util.EnvironmentTickCount(); 4306 ce.time = Util.EnvironmentTickCount();
3973 ce.account = account; 4307 ce.account = account;
3974 ce.pinfo = pinfo; 4308 ce.pinfo = pinfo;
4309 m_userInfoCache[uuid] = ce;
3975 } 4310 }
3976 else 4311 else
3977 { 4312 {
@@ -4047,6 +4382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4047 { 4382 {
4048 m_host.AddScriptLPS(1); 4383 m_host.AddScriptLPS(1);
4049 4384
4385 //Clone is thread safe
4050 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4386 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4051 4387
4052 foreach (TaskInventoryItem item in itemDictionary.Values) 4388 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4100,6 +4436,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4100 ScenePresence presence = World.GetScenePresence(agentId); 4436 ScenePresence presence = World.GetScenePresence(agentId);
4101 if (presence != null) 4437 if (presence != null)
4102 { 4438 {
4439 // agent must not be a god
4440 if (presence.GodLevel >= 200) return;
4441
4103 // agent must be over the owners land 4442 // agent must be over the owners land
4104 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4443 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4105 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4444 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4159,17 +4498,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4159 UUID soundId = UUID.Zero; 4498 UUID soundId = UUID.Zero;
4160 if (!UUID.TryParse(impact_sound, out soundId)) 4499 if (!UUID.TryParse(impact_sound, out soundId))
4161 { 4500 {
4162 lock (m_host.TaskInventory) 4501 m_host.TaskInventory.LockItemsForRead(true);
4502 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4163 { 4503 {
4164 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4504 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4165 { 4505 {
4166 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4506 soundId = item.AssetID;
4167 { 4507 break;
4168 soundId = item.AssetID;
4169 break;
4170 }
4171 } 4508 }
4172 } 4509 }
4510 m_host.TaskInventory.LockItemsForRead(false);
4173 } 4511 }
4174 m_host.CollisionSound = soundId; 4512 m_host.CollisionSound = soundId;
4175 m_host.CollisionSoundVolume = (float)impact_volume; 4513 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4215,6 +4553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4215 UUID partItemID; 4553 UUID partItemID;
4216 foreach (SceneObjectPart part in parts) 4554 foreach (SceneObjectPart part in parts)
4217 { 4555 {
4556 //Clone is thread safe
4218 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4557 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4219 4558
4220 foreach (TaskInventoryItem item in itemsDictionary.Values) 4559 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4429,17 +4768,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4429 4768
4430 m_host.AddScriptLPS(1); 4769 m_host.AddScriptLPS(1);
4431 4770
4432 lock (m_host.TaskInventory) 4771 m_host.TaskInventory.LockItemsForRead(true);
4772 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4433 { 4773 {
4434 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4774 if (item.Type == 10 && item.ItemID == m_itemID)
4435 { 4775 {
4436 if (item.Type == 10 && item.ItemID == m_itemID) 4776 result = item.Name!=null?item.Name:String.Empty;
4437 { 4777 break;
4438 result = item.Name != null ? item.Name : String.Empty;
4439 break;
4440 }
4441 } 4778 }
4442 } 4779 }
4780 m_host.TaskInventory.LockItemsForRead(false);
4443 4781
4444 return result; 4782 return result;
4445 } 4783 }
@@ -4592,23 +4930,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4592 { 4930 {
4593 m_host.AddScriptLPS(1); 4931 m_host.AddScriptLPS(1);
4594 4932
4595 lock (m_host.TaskInventory) 4933 m_host.TaskInventory.LockItemsForRead(true);
4934 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4596 { 4935 {
4597 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4936 if (inv.Value.Name == name)
4598 { 4937 {
4599 if (inv.Value.Name == name) 4938 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4600 { 4939 {
4601 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4940 m_host.TaskInventory.LockItemsForRead(false);
4602 { 4941 return inv.Value.AssetID.ToString();
4603 return inv.Value.AssetID.ToString(); 4942 }
4604 } 4943 else
4605 else 4944 {
4606 { 4945 m_host.TaskInventory.LockItemsForRead(false);
4607 return UUID.Zero.ToString(); 4946 return UUID.Zero.ToString();
4608 }
4609 } 4947 }
4610 } 4948 }
4611 } 4949 }
4950 m_host.TaskInventory.LockItemsForRead(false);
4612 4951
4613 return UUID.Zero.ToString(); 4952 return UUID.Zero.ToString();
4614 } 4953 }
@@ -4761,14 +5100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5100 {
4762 m_host.AddScriptLPS(1); 5101 m_host.AddScriptLPS(1);
4763 5102
4764 if (src == null) 5103 return src.Length;
4765 {
4766 return 0;
4767 }
4768 else
4769 {
4770 return src.Length;
4771 }
4772 } 5104 }
4773 5105
4774 public LSL_Integer llList2Integer(LSL_List src, int index) 5106 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4814,7 +5146,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4814 else if (src.Data[index] is LSL_Float) 5146 else if (src.Data[index] is LSL_Float)
4815 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5147 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4816 else if (src.Data[index] is LSL_String) 5148 else if (src.Data[index] is LSL_String)
4817 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5149 {
5150 string str = ((LSL_String) src.Data[index]).m_string;
5151 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5152 if (m != Match.Empty)
5153 {
5154 str = m.Value;
5155 double d = 0.0;
5156 if (!Double.TryParse(str, out d))
5157 return 0.0;
5158
5159 return d;
5160 }
5161 return 0.0;
5162 }
4818 return Convert.ToDouble(src.Data[index]); 5163 return Convert.ToDouble(src.Data[index]);
4819 } 5164 }
4820 catch (FormatException) 5165 catch (FormatException)
@@ -5087,7 +5432,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5087 } 5432 }
5088 } 5433 }
5089 } 5434 }
5090 else { 5435 else
5436 {
5091 object[] array = new object[src.Length]; 5437 object[] array = new object[src.Length];
5092 Array.Copy(src.Data, 0, array, 0, src.Length); 5438 Array.Copy(src.Data, 0, array, 0, src.Length);
5093 result = new LSL_List(array); 5439 result = new LSL_List(array);
@@ -5499,7 +5845,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5499 public void llSetSoundQueueing(int queue) 5845 public void llSetSoundQueueing(int queue)
5500 { 5846 {
5501 m_host.AddScriptLPS(1); 5847 m_host.AddScriptLPS(1);
5502 NotImplemented("llSetSoundQueueing");
5503 } 5848 }
5504 5849
5505 public void llSetSoundRadius(double radius) 5850 public void llSetSoundRadius(double radius)
@@ -5544,10 +5889,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5544 m_host.AddScriptLPS(1); 5889 m_host.AddScriptLPS(1);
5545 5890
5546 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5891 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5547 5892 if (parts.Count > 0)
5548 foreach (var part in parts)
5549 { 5893 {
5550 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5894 try
5895 {
5896 parts[0].ParentGroup.areUpdatesSuspended = true;
5897 foreach (var part in parts)
5898 {
5899 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5900 }
5901 }
5902 finally
5903 {
5904 parts[0].ParentGroup.areUpdatesSuspended = false;
5905 }
5551 } 5906 }
5552 } 5907 }
5553 5908
@@ -5601,6 +5956,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5601 ScriptSleep(5000); 5956 ScriptSleep(5000);
5602 } 5957 }
5603 5958
5959 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5960 {
5961 return ParseString2List(str, separators, in_spacers, false);
5962 }
5963
5604 public LSL_Integer llOverMyLand(string id) 5964 public LSL_Integer llOverMyLand(string id)
5605 { 5965 {
5606 m_host.AddScriptLPS(1); 5966 m_host.AddScriptLPS(1);
@@ -5801,7 +6161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5801 return m_host.ParentGroup.RootPart.AttachmentPoint; 6161 return m_host.ParentGroup.RootPart.AttachmentPoint;
5802 } 6162 }
5803 6163
5804 public LSL_Integer llGetFreeMemory() 6164 public virtual LSL_Integer llGetFreeMemory()
5805 { 6165 {
5806 m_host.AddScriptLPS(1); 6166 m_host.AddScriptLPS(1);
5807 // Make scripts designed for LSO happy 6167 // Make scripts designed for LSO happy
@@ -5918,7 +6278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5918 SetParticleSystem(m_host, rules); 6278 SetParticleSystem(m_host, rules);
5919 } 6279 }
5920 6280
5921 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6281 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6282 {
5922 6283
5923 6284
5924 if (rules.Length == 0) 6285 if (rules.Length == 0)
@@ -6112,14 +6473,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6112 6473
6113 protected UUID GetTaskInventoryItem(string name) 6474 protected UUID GetTaskInventoryItem(string name)
6114 { 6475 {
6115 lock (m_host.TaskInventory) 6476 m_host.TaskInventory.LockItemsForRead(true);
6477 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6116 { 6478 {
6117 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6479 if (inv.Value.Name == name)
6118 { 6480 {
6119 if (inv.Value.Name == name) 6481 m_host.TaskInventory.LockItemsForRead(false);
6120 return inv.Key; 6482 return inv.Key;
6121 } 6483 }
6122 } 6484 }
6485 m_host.TaskInventory.LockItemsForRead(false);
6123 6486
6124 return UUID.Zero; 6487 return UUID.Zero;
6125 } 6488 }
@@ -6447,22 +6810,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6447 } 6810 }
6448 6811
6449 // copy the first script found with this inventory name 6812 // copy the first script found with this inventory name
6450 lock (m_host.TaskInventory) 6813 m_host.TaskInventory.LockItemsForRead(true);
6814 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6451 { 6815 {
6452 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6816 if (inv.Value.Name == name)
6453 { 6817 {
6454 if (inv.Value.Name == name) 6818 // make sure the object is a script
6819 if (10 == inv.Value.Type)
6455 { 6820 {
6456 // make sure the object is a script 6821 found = true;
6457 if (10 == inv.Value.Type) 6822 srcId = inv.Key;
6458 { 6823 break;
6459 found = true;
6460 srcId = inv.Key;
6461 break;
6462 }
6463 } 6824 }
6464 } 6825 }
6465 } 6826 }
6827 m_host.TaskInventory.LockItemsForRead(false);
6466 6828
6467 if (!found) 6829 if (!found)
6468 { 6830 {
@@ -6546,6 +6908,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6546 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6908 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6547 { 6909 {
6548 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6910 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6911 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6912 return shapeBlock;
6549 6913
6550 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6914 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6551 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6915 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6621,6 +6985,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6621 6985
6622 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6986 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6623 { 6987 {
6988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6989 return;
6990
6624 ObjectShapePacket.ObjectDataBlock shapeBlock; 6991 ObjectShapePacket.ObjectDataBlock shapeBlock;
6625 6992
6626 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6993 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6670,6 +7037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6670 7037
6671 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7038 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6672 { 7039 {
7040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7041 return;
7042
6673 ObjectShapePacket.ObjectDataBlock shapeBlock; 7043 ObjectShapePacket.ObjectDataBlock shapeBlock;
6674 7044
6675 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7045 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6712,6 +7082,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6712 7082
6713 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) 7083 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)
6714 { 7084 {
7085 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7086 return;
7087
6715 ObjectShapePacket.ObjectDataBlock shapeBlock; 7088 ObjectShapePacket.ObjectDataBlock shapeBlock;
6716 7089
6717 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7090 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6838,6 +7211,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6838 7211
6839 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7212 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6840 { 7213 {
7214 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7215 return;
7216
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7217 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6842 UUID sculptId; 7218 UUID sculptId;
6843 7219
@@ -6853,13 +7229,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6853 shapeBlock.PathScaleX = 100; 7229 shapeBlock.PathScaleX = 100;
6854 shapeBlock.PathScaleY = 150; 7230 shapeBlock.PathScaleY = 150;
6855 7231
6856 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7232 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6857 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7233 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6858 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7234 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6859 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7235 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6860 { 7236 {
6861 // default 7237 // default
6862 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7238 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6863 } 7239 }
6864 7240
6865 // retain pathcurve 7241 // retain pathcurve
@@ -6878,30 +7254,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6878 ScriptSleep(200); 7254 ScriptSleep(200);
6879 } 7255 }
6880 7256
6881 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7257 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6882 { 7258 {
6883 m_host.AddScriptLPS(1); 7259 m_host.AddScriptLPS(1);
6884 7260
6885 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7261 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7262 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7263 if (parts.Count>0)
7264 {
7265 try
7266 {
7267 parts[0].ParentGroup.areUpdatesSuspended = true;
7268 foreach (SceneObjectPart part in parts)
7269 SetPrimParams(part, rules);
7270 }
7271 finally
7272 {
7273 parts[0].ParentGroup.areUpdatesSuspended = false;
7274 }
7275 }
7276 if (avatars.Count > 0)
7277 {
7278 foreach (ScenePresence avatar in avatars)
7279 SetPrimParams(avatar, rules);
7280 }
7281 }
6886 7282
6887 foreach (SceneObjectPart part in parts) 7283 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6888 SetPrimParams(part, rules); 7284 {
6889 7285 llSetLinkPrimitiveParamsFast(linknumber, rules);
6890 ScriptSleep(200); 7286 ScriptSleep(200);
6891 } 7287 }
6892 7288
6893 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7289 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6894 { 7290 {
6895 m_host.AddScriptLPS(1); 7291 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7292 //We only support PRIM_POSITION and PRIM_ROTATION
6896 7293
6897 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7294 int idx = 0;
6898 7295
6899 foreach (SceneObjectPart part in parts) 7296 while (idx < rules.Length)
6900 SetPrimParams(part, rules); 7297 {
7298 int code = rules.GetLSLIntegerItem(idx++);
7299
7300 int remain = rules.Length - idx;
7301
7302
7303
7304 switch (code)
7305 {
7306 case (int)ScriptBaseClass.PRIM_POSITION:
7307 if (remain < 1)
7308 return;
7309 LSL_Vector v;
7310 v = rules.GetVector3Item(idx++);
7311 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7312 av.SendFullUpdateToAllClients();
7313
7314 break;
7315
7316 case (int)ScriptBaseClass.PRIM_ROTATION:
7317 if (remain < 1)
7318 return;
7319 LSL_Rotation r;
7320 r = rules.GetQuaternionItem(idx++);
7321 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7322 av.SendFullUpdateToAllClients();
7323 break;
7324 }
7325 }
6901 } 7326 }
6902 7327
6903 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7328 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6904 { 7329 {
7330 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7331 return;
7332
6905 int idx = 0; 7333 int idx = 0;
6906 7334
6907 while (idx < rules.Length) 7335 while (idx < rules.Length)
@@ -7436,13 +7864,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7436 public LSL_Integer llGetNumberOfPrims() 7864 public LSL_Integer llGetNumberOfPrims()
7437 { 7865 {
7438 m_host.AddScriptLPS(1); 7866 m_host.AddScriptLPS(1);
7439 int avatarCount = 0; 7867 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7440 World.ForEachScenePresence(delegate(ScenePresence presence) 7868
7441 {
7442 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7443 avatarCount++;
7444 });
7445
7446 return m_host.ParentGroup.PrimCount + avatarCount; 7869 return m_host.ParentGroup.PrimCount + avatarCount;
7447 } 7870 }
7448 7871
@@ -7458,55 +7881,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7458 m_host.AddScriptLPS(1); 7881 m_host.AddScriptLPS(1);
7459 UUID objID = UUID.Zero; 7882 UUID objID = UUID.Zero;
7460 LSL_List result = new LSL_List(); 7883 LSL_List result = new LSL_List();
7884
7885 // If the ID is not valid, return null result
7461 if (!UUID.TryParse(obj, out objID)) 7886 if (!UUID.TryParse(obj, out objID))
7462 { 7887 {
7463 result.Add(new LSL_Vector()); 7888 result.Add(new LSL_Vector());
7464 result.Add(new LSL_Vector()); 7889 result.Add(new LSL_Vector());
7465 return result; 7890 return result;
7466 } 7891 }
7892
7893 // Check if this is an attached prim. If so, replace
7894 // the UUID with the avatar UUID and report it's bounding box
7895 SceneObjectPart part = World.GetSceneObjectPart(objID);
7896 if (part != null && part.ParentGroup.IsAttachment)
7897 objID = part.ParentGroup.RootPart.AttachedAvatar;
7898
7899 // Find out if this is an avatar ID. If so, return it's box
7467 ScenePresence presence = World.GetScenePresence(objID); 7900 ScenePresence presence = World.GetScenePresence(objID);
7468 if (presence != null) 7901 if (presence != null)
7469 { 7902 {
7470 if (presence.ParentID == 0) // not sat on an object 7903 // As per LSL Wiki, there is no difference between sitting
7904 // and standing avatar since server 1.36
7905 LSL_Vector lower;
7906 LSL_Vector upper;
7907 if (presence.Animator.Animations.DefaultAnimation.AnimID
7908 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7471 { 7909 {
7472 LSL_Vector lower; 7910 // This is for ground sitting avatars
7473 LSL_Vector upper; 7911 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7474 if (presence.Animator.Animations.DefaultAnimation.AnimID 7912 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7475 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7913 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7476 {
7477 // This is for ground sitting avatars
7478 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7479 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7480 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7481 }
7482 else
7483 {
7484 // This is for standing/flying avatars
7485 float height = presence.Appearance.AvatarHeight / 2.0f;
7486 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7487 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7488 }
7489 result.Add(lower);
7490 result.Add(upper);
7491 return result;
7492 } 7914 }
7493 else 7915 else
7494 { 7916 {
7495 // sitting on an object so we need the bounding box of that 7917 // This is for standing/flying avatars
7496 // which should include the avatar so set the UUID to the 7918 float height = presence.Appearance.AvatarHeight / 2.0f;
7497 // UUID of the object the avatar is sat on and allow it to fall through 7919 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7498 // to processing an object 7920 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7499 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7500 objID = p.UUID;
7501 } 7921 }
7922
7923 // Adjust to the documented error offsets (see LSL Wiki)
7924 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7925 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7926
7927 if (lower.x > upper.x)
7928 lower.x = upper.x;
7929 if (lower.y > upper.y)
7930 lower.y = upper.y;
7931 if (lower.z > upper.z)
7932 lower.z = upper.z;
7933
7934 result.Add(lower);
7935 result.Add(upper);
7936 return result;
7502 } 7937 }
7503 SceneObjectPart part = World.GetSceneObjectPart(objID); 7938
7939 part = World.GetSceneObjectPart(objID);
7504 // Currently only works for single prims without a sitting avatar 7940 // Currently only works for single prims without a sitting avatar
7505 if (part != null) 7941 if (part != null)
7506 { 7942 {
7507 Vector3 halfSize = part.Scale / 2.0f; 7943 float minX;
7508 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7944 float maxX;
7509 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7945 float minY;
7946 float maxY;
7947 float minZ;
7948 float maxZ;
7949
7950 // This BBox is in sim coordinates, with the offset being
7951 // a contained point.
7952 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7953 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7954
7955 minX -= offsets[0].X;
7956 maxX -= offsets[0].X;
7957 minY -= offsets[0].Y;
7958 maxY -= offsets[0].Y;
7959 minZ -= offsets[0].Z;
7960 maxZ -= offsets[0].Z;
7961
7962 LSL_Vector lower;
7963 LSL_Vector upper;
7964
7965 // Adjust to the documented error offsets (see LSL Wiki)
7966 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7967 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7968
7969 if (lower.x > upper.x)
7970 lower.x = upper.x;
7971 if (lower.y > upper.y)
7972 lower.y = upper.y;
7973 if (lower.z > upper.z)
7974 lower.z = upper.z;
7975
7510 result.Add(lower); 7976 result.Add(lower);
7511 result.Add(upper); 7977 result.Add(upper);
7512 return result; 7978 return result;
@@ -7586,13 +8052,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7586 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8052 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7587 part.AbsolutePosition.Y, 8053 part.AbsolutePosition.Y,
7588 part.AbsolutePosition.Z); 8054 part.AbsolutePosition.Z);
7589 // For some reason, the part.AbsolutePosition.* values do not change if the
7590 // linkset is rotated; they always reflect the child prim's world position
7591 // as though the linkset is unrotated. This is incompatible behavior with SL's
7592 // implementation, so will break scripts imported from there (not to mention it
7593 // makes it more difficult to determine a child prim's actual inworld position).
7594 if (part.ParentID != 0)
7595 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7596 res.Add(v); 8055 res.Add(v);
7597 break; 8056 break;
7598 8057
@@ -7751,24 +8210,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7751 break; 8210 break;
7752 8211
7753 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8212 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7754 // TODO--------------
7755 if (remain < 1) 8213 if (remain < 1)
7756 return res; 8214 return res;
8215 face = (int)rules.GetLSLIntegerItem(idx++);
7757 8216
7758 face=(int)rules.GetLSLIntegerItem(idx++); 8217 tex = part.Shape.Textures;
7759 8218 int shiny;
7760 res.Add(new LSL_Integer(0)); 8219 if (face == ScriptBaseClass.ALL_SIDES)
7761 res.Add(new LSL_Integer(0)); 8220 {
8221 for (face = 0; face < GetNumberOfSides(part); face++)
8222 {
8223 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8224 if (shinyness == Shininess.High)
8225 {
8226 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8227 }
8228 else if (shinyness == Shininess.Medium)
8229 {
8230 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8231 }
8232 else if (shinyness == Shininess.Low)
8233 {
8234 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8235 }
8236 else
8237 {
8238 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8239 }
8240 res.Add(new LSL_Integer(shiny));
8241 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8242 }
8243 }
8244 else
8245 {
8246 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8247 if (shinyness == Shininess.High)
8248 {
8249 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8250 }
8251 else if (shinyness == Shininess.Medium)
8252 {
8253 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8254 }
8255 else if (shinyness == Shininess.Low)
8256 {
8257 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8258 }
8259 else
8260 {
8261 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8262 }
8263 res.Add(new LSL_Integer(shiny));
8264 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8265 }
7762 break; 8266 break;
7763 8267
7764 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8268 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7765 // TODO--------------
7766 if (remain < 1) 8269 if (remain < 1)
7767 return res; 8270 return res;
8271 face = (int)rules.GetLSLIntegerItem(idx++);
7768 8272
7769 face=(int)rules.GetLSLIntegerItem(idx++); 8273 tex = part.Shape.Textures;
7770 8274 int fullbright;
7771 res.Add(new LSL_Integer(0)); 8275 if (face == ScriptBaseClass.ALL_SIDES)
8276 {
8277 for (face = 0; face < GetNumberOfSides(part); face++)
8278 {
8279 if (tex.GetFace((uint)face).Fullbright == true)
8280 {
8281 fullbright = ScriptBaseClass.TRUE;
8282 }
8283 else
8284 {
8285 fullbright = ScriptBaseClass.FALSE;
8286 }
8287 res.Add(new LSL_Integer(fullbright));
8288 }
8289 }
8290 else
8291 {
8292 if (tex.GetFace((uint)face).Fullbright == true)
8293 {
8294 fullbright = ScriptBaseClass.TRUE;
8295 }
8296 else
8297 {
8298 fullbright = ScriptBaseClass.FALSE;
8299 }
8300 res.Add(new LSL_Integer(fullbright));
8301 }
7772 break; 8302 break;
7773 8303
7774 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8304 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7789,14 +8319,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7789 break; 8319 break;
7790 8320
7791 case (int)ScriptBaseClass.PRIM_TEXGEN: 8321 case (int)ScriptBaseClass.PRIM_TEXGEN:
7792 // TODO--------------
7793 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8322 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7794 if (remain < 1) 8323 if (remain < 1)
7795 return res; 8324 return res;
8325 face = (int)rules.GetLSLIntegerItem(idx++);
7796 8326
7797 face=(int)rules.GetLSLIntegerItem(idx++); 8327 tex = part.Shape.Textures;
7798 8328 if (face == ScriptBaseClass.ALL_SIDES)
7799 res.Add(new LSL_Integer(0)); 8329 {
8330 for (face = 0; face < GetNumberOfSides(part); face++)
8331 {
8332 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8333 {
8334 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8335 }
8336 else
8337 {
8338 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8339 }
8340 }
8341 }
8342 else
8343 {
8344 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8345 {
8346 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8347 }
8348 else
8349 {
8350 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8351 }
8352 }
7800 break; 8353 break;
7801 8354
7802 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8355 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7815,13 +8368,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7815 break; 8368 break;
7816 8369
7817 case (int)ScriptBaseClass.PRIM_GLOW: 8370 case (int)ScriptBaseClass.PRIM_GLOW:
7818 // TODO--------------
7819 if (remain < 1) 8371 if (remain < 1)
7820 return res; 8372 return res;
8373 face = (int)rules.GetLSLIntegerItem(idx++);
7821 8374
7822 face=(int)rules.GetLSLIntegerItem(idx++); 8375 tex = part.Shape.Textures;
7823 8376 float primglow;
7824 res.Add(new LSL_Float(0)); 8377 if (face == ScriptBaseClass.ALL_SIDES)
8378 {
8379 for (face = 0; face < GetNumberOfSides(part); face++)
8380 {
8381 primglow = tex.GetFace((uint)face).Glow;
8382 res.Add(new LSL_Float(primglow));
8383 }
8384 }
8385 else
8386 {
8387 primglow = tex.GetFace((uint)face).Glow;
8388 res.Add(new LSL_Float(primglow));
8389 }
7825 break; 8390 break;
7826 case (int)ScriptBaseClass.PRIM_TEXT: 8391 case (int)ScriptBaseClass.PRIM_TEXT:
7827 Color4 textColor = part.GetTextColor(); 8392 Color4 textColor = part.GetTextColor();
@@ -8371,8 +8936,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8371 // The function returns an ordered list 8936 // The function returns an ordered list
8372 // representing the tokens found in the supplied 8937 // representing the tokens found in the supplied
8373 // sources string. If two successive tokenizers 8938 // sources string. If two successive tokenizers
8374 // are encountered, then a NULL entry is added 8939 // are encountered, then a null-string entry is
8375 // to the list. 8940 // added to the list.
8376 // 8941 //
8377 // It is a precondition that the source and 8942 // It is a precondition that the source and
8378 // toekizer lisst are non-null. If they are null, 8943 // toekizer lisst are non-null. If they are null,
@@ -8380,7 +8945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8380 // while their lengths are being determined. 8945 // while their lengths are being determined.
8381 // 8946 //
8382 // A small amount of working memoryis required 8947 // A small amount of working memoryis required
8383 // of approximately 8*#tokenizers. 8948 // of approximately 8*#tokenizers + 8*srcstrlen.
8384 // 8949 //
8385 // There are many ways in which this function 8950 // There are many ways in which this function
8386 // can be implemented, this implementation is 8951 // can be implemented, this implementation is
@@ -8396,155 +8961,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8396 // and eliminates redundant tokenizers as soon 8961 // and eliminates redundant tokenizers as soon
8397 // as is possible. 8962 // as is possible.
8398 // 8963 //
8399 // The implementation tries to avoid any copying 8964 // The implementation tries to minimize temporary
8400 // of arrays or other objects. 8965 // garbage generation.
8401 // </remarks> 8966 // </remarks>
8402 8967
8403 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 8968 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8404 { 8969 {
8405 int beginning = 0; 8970 return ParseString2List(src, separators, spacers, true);
8406 int srclen = src.Length; 8971 }
8407 int seplen = separators.Length;
8408 object[] separray = separators.Data;
8409 int spclen = spacers.Length;
8410 object[] spcarray = spacers.Data;
8411 int mlen = seplen+spclen;
8412
8413 int[] offset = new int[mlen+1];
8414 bool[] active = new bool[mlen];
8415
8416 int best;
8417 int j;
8418
8419 // Initial capacity reduces resize cost
8420 8972
8421 LSL_List tokens = new LSL_List(); 8973 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8974 {
8975 int srclen = src.Length;
8976 int seplen = separators.Length;
8977 object[] separray = separators.Data;
8978 int spclen = spacers.Length;
8979 object[] spcarray = spacers.Data;
8980 int dellen = 0;
8981 string[] delarray = new string[seplen+spclen];
8422 8982
8423 // All entries are initially valid 8983 int outlen = 0;
8984 string[] outarray = new string[srclen*2+1];
8424 8985
8425 for (int i = 0; i < mlen; i++) 8986 int i, j;
8426 active[i] = true; 8987 string d;
8427 8988
8428 offset[mlen] = srclen; 8989 m_host.AddScriptLPS(1);
8429 8990
8430 while (beginning < srclen) 8991 /*
8992 * Convert separator and spacer lists to C# strings.
8993 * Also filter out null strings so we don't hang.
8994 */
8995 for (i = 0; i < seplen; i ++)
8431 { 8996 {
8997 d = separray[i].ToString();
8998 if (d.Length > 0)
8999 {
9000 delarray[dellen++] = d;
9001 }
9002 }
9003 seplen = dellen;
8432 9004
8433 best = mlen; // as bad as it gets 9005 for (i = 0; i < spclen; i ++)
9006 {
9007 d = spcarray[i].ToString();
9008 if (d.Length > 0)
9009 {
9010 delarray[dellen++] = d;
9011 }
9012 }
8434 9013
8435 // Scan for separators 9014 /*
9015 * Scan through source string from beginning to end.
9016 */
9017 for (i = 0;;)
9018 {
8436 9019
8437 for (j = 0; j < seplen; j++) 9020 /*
9021 * Find earliest delimeter in src starting at i (if any).
9022 */
9023 int earliestDel = -1;
9024 int earliestSrc = srclen;
9025 string earliestStr = null;
9026 for (j = 0; j < dellen; j ++)
8438 { 9027 {
8439 if (separray[j].ToString() == String.Empty) 9028 d = delarray[j];
8440 active[j] = false; 9029 if (d != null)
8441
8442 if (active[j])
8443 { 9030 {
8444 // scan all of the markers 9031 int index = src.IndexOf(d, i);
8445 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9032 if (index < 0)
8446 { 9033 {
8447 // not present at all 9034 delarray[j] = null; // delim nowhere in src, don't check it anymore
8448 active[j] = false;
8449 } 9035 }
8450 else 9036 else if (index < earliestSrc)
8451 { 9037 {
8452 // present and correct 9038 earliestSrc = index; // where delimeter starts in source string
8453 if (offset[j] < offset[best]) 9039 earliestDel = j; // where delimeter is in delarray[]
8454 { 9040 earliestStr = d; // the delimeter string from delarray[]
8455 // closest so far 9041 if (index == i) break; // can't do any better than found at beg of string
8456 best = j;
8457 if (offset[best] == beginning)
8458 break;
8459 }
8460 } 9042 }
8461 } 9043 }
8462 } 9044 }
8463 9045
8464 // Scan for spacers 9046 /*
8465 9047 * Output source string starting at i through start of earliest delimeter.
8466 if (offset[best] != beginning) 9048 */
9049 if (keepNulls || (earliestSrc > i))
8467 { 9050 {
8468 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9051 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8469 {
8470 if (spcarray[j-seplen].ToString() == String.Empty)
8471 active[j] = false;
8472
8473 if (active[j])
8474 {
8475 // scan all of the markers
8476 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8477 {
8478 // not present at all
8479 active[j] = false;
8480 }
8481 else
8482 {
8483 // present and correct
8484 if (offset[j] < offset[best])
8485 {
8486 // closest so far
8487 best = j;
8488 }
8489 }
8490 }
8491 }
8492 } 9052 }
8493 9053
8494 // This is the normal exit from the scanning loop 9054 /*
9055 * If no delimeter found at or after i, we're done scanning.
9056 */
9057 if (earliestDel < 0) break;
8495 9058
8496 if (best == mlen) 9059 /*
9060 * If delimeter was a spacer, output the spacer.
9061 */
9062 if (earliestDel >= seplen)
8497 { 9063 {
8498 // no markers were found on this pass 9064 outarray[outlen++] = earliestStr;
8499 // so we're pretty much done
8500 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8501 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8502 break;
8503 } 9065 }
8504 9066
8505 // Otherwise we just add the newly delimited token 9067 /*
8506 // and recalculate where the search should continue. 9068 * Look at rest of src string following delimeter.
8507 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9069 */
8508 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9070 i = earliestSrc + earliestStr.Length;
8509
8510 if (best < seplen)
8511 {
8512 beginning = offset[best] + (separray[best].ToString()).Length;
8513 }
8514 else
8515 {
8516 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8517 string str = spcarray[best - seplen].ToString();
8518 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8519 tokens.Add(new LSL_String(str));
8520 }
8521 } 9071 }
8522 9072
8523 // This an awkward an not very intuitive boundary case. If the 9073 /*
8524 // last substring is a tokenizer, then there is an implied trailing 9074 * Make up an exact-sized output array suitable for an LSL_List object.
8525 // null list entry. Hopefully the single comparison will not be too 9075 */
8526 // arduous. Alternatively the 'break' could be replced with a return 9076 object[] outlist = new object[outlen];
8527 // but that's shabby programming. 9077 for (i = 0; i < outlen; i ++)
8528
8529 if ((beginning == srclen) && (keepNulls))
8530 { 9078 {
8531 if (srclen != 0) 9079 outlist[i] = new LSL_String(outarray[i]);
8532 tokens.Add(new LSL_String(""));
8533 } 9080 }
8534 9081 return new LSL_List(outlist);
8535 return tokens;
8536 }
8537
8538 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8539 {
8540 m_host.AddScriptLPS(1);
8541 return this.ParseString(src, separators, spacers, false);
8542 }
8543
8544 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8545 {
8546 m_host.AddScriptLPS(1);
8547 return this.ParseString(src, separators, spacers, true);
8548 } 9082 }
8549 9083
8550 public LSL_Integer llGetObjectPermMask(int mask) 9084 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8621,28 +9155,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8621 { 9155 {
8622 m_host.AddScriptLPS(1); 9156 m_host.AddScriptLPS(1);
8623 9157
8624 lock (m_host.TaskInventory) 9158 m_host.TaskInventory.LockItemsForRead(true);
9159 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8625 { 9160 {
8626 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9161 if (inv.Value.Name == item)
8627 { 9162 {
8628 if (inv.Value.Name == item) 9163 m_host.TaskInventory.LockItemsForRead(false);
9164 switch (mask)
8629 { 9165 {
8630 switch (mask) 9166 case 0:
8631 { 9167 return (int)inv.Value.BasePermissions;
8632 case 0: 9168 case 1:
8633 return (int)inv.Value.BasePermissions; 9169 return (int)inv.Value.CurrentPermissions;
8634 case 1: 9170 case 2:
8635 return (int)inv.Value.CurrentPermissions; 9171 return (int)inv.Value.GroupPermissions;
8636 case 2: 9172 case 3:
8637 return (int)inv.Value.GroupPermissions; 9173 return (int)inv.Value.EveryonePermissions;
8638 case 3: 9174 case 4:
8639 return (int)inv.Value.EveryonePermissions; 9175 return (int)inv.Value.NextPermissions;
8640 case 4:
8641 return (int)inv.Value.NextPermissions;
8642 }
8643 } 9176 }
8644 } 9177 }
8645 } 9178 }
9179 m_host.TaskInventory.LockItemsForRead(false);
8646 9180
8647 return -1; 9181 return -1;
8648 } 9182 }
@@ -8689,16 +9223,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8689 { 9223 {
8690 m_host.AddScriptLPS(1); 9224 m_host.AddScriptLPS(1);
8691 9225
8692 lock (m_host.TaskInventory) 9226 m_host.TaskInventory.LockItemsForRead(true);
9227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8693 { 9228 {
8694 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9229 if (inv.Value.Name == item)
8695 { 9230 {
8696 if (inv.Value.Name == item) 9231 m_host.TaskInventory.LockItemsForRead(false);
8697 { 9232 return inv.Value.CreatorID.ToString();
8698 return inv.Value.CreatorID.ToString();
8699 }
8700 } 9233 }
8701 } 9234 }
9235 m_host.TaskInventory.LockItemsForRead(false);
8702 9236
8703 llSay(0, "No item name '" + item + "'"); 9237 llSay(0, "No item name '" + item + "'");
8704 9238
@@ -8749,8 +9283,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8749 return UUID.Zero.ToString(); 9283 return UUID.Zero.ToString();
8750 } 9284 }
8751 reply = new LSL_Vector( 9285 reply = new LSL_Vector(
8752 info.RegionLocX * Constants.RegionSize, 9286 info.RegionLocX,
8753 info.RegionLocY * Constants.RegionSize, 9287 info.RegionLocY,
8754 0).ToString(); 9288 0).ToString();
8755 break; 9289 break;
8756 case 6: // DATA_SIM_STATUS 9290 case 6: // DATA_SIM_STATUS
@@ -8963,17 +9497,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8963 int width = 0; 9497 int width = 0;
8964 int height = 0; 9498 int height = 0;
8965 9499
8966 ParcelMediaCommandEnum? commandToSend = null; 9500 uint commandToSend = 0;
8967 float time = 0.0f; // default is from start 9501 float time = 0.0f; // default is from start
8968 9502
8969 ScenePresence presence = null; 9503 ScenePresence presence = null;
8970 9504
8971 for (int i = 0; i < commandList.Data.Length; i++) 9505 for (int i = 0; i < commandList.Data.Length; i++)
8972 { 9506 {
8973 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9507 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8974 switch (command) 9508 switch (command)
8975 { 9509 {
8976 case ParcelMediaCommandEnum.Agent: 9510 case (uint)ParcelMediaCommandEnum.Agent:
8977 // we send only to one agent 9511 // we send only to one agent
8978 if ((i + 1) < commandList.Length) 9512 if ((i + 1) < commandList.Length)
8979 { 9513 {
@@ -8990,25 +9524,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8990 } 9524 }
8991 break; 9525 break;
8992 9526
8993 case ParcelMediaCommandEnum.Loop: 9527 case (uint)ParcelMediaCommandEnum.Loop:
8994 loop = 1; 9528 loop = 1;
8995 commandToSend = command; 9529 commandToSend = command;
8996 update = true; //need to send the media update packet to set looping 9530 update = true; //need to send the media update packet to set looping
8997 break; 9531 break;
8998 9532
8999 case ParcelMediaCommandEnum.Play: 9533 case (uint)ParcelMediaCommandEnum.Play:
9000 loop = 0; 9534 loop = 0;
9001 commandToSend = command; 9535 commandToSend = command;
9002 update = true; //need to send the media update packet to make sure it doesn't loop 9536 update = true; //need to send the media update packet to make sure it doesn't loop
9003 break; 9537 break;
9004 9538
9005 case ParcelMediaCommandEnum.Pause: 9539 case (uint)ParcelMediaCommandEnum.Pause:
9006 case ParcelMediaCommandEnum.Stop: 9540 case (uint)ParcelMediaCommandEnum.Stop:
9007 case ParcelMediaCommandEnum.Unload: 9541 case (uint)ParcelMediaCommandEnum.Unload:
9008 commandToSend = command; 9542 commandToSend = command;
9009 break; 9543 break;
9010 9544
9011 case ParcelMediaCommandEnum.Url: 9545 case (uint)ParcelMediaCommandEnum.Url:
9012 if ((i + 1) < commandList.Length) 9546 if ((i + 1) < commandList.Length)
9013 { 9547 {
9014 if (commandList.Data[i + 1] is LSL_String) 9548 if (commandList.Data[i + 1] is LSL_String)
@@ -9021,7 +9555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9021 } 9555 }
9022 break; 9556 break;
9023 9557
9024 case ParcelMediaCommandEnum.Texture: 9558 case (uint)ParcelMediaCommandEnum.Texture:
9025 if ((i + 1) < commandList.Length) 9559 if ((i + 1) < commandList.Length)
9026 { 9560 {
9027 if (commandList.Data[i + 1] is LSL_String) 9561 if (commandList.Data[i + 1] is LSL_String)
@@ -9034,7 +9568,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9034 } 9568 }
9035 break; 9569 break;
9036 9570
9037 case ParcelMediaCommandEnum.Time: 9571 case (uint)ParcelMediaCommandEnum.Time:
9038 if ((i + 1) < commandList.Length) 9572 if ((i + 1) < commandList.Length)
9039 { 9573 {
9040 if (commandList.Data[i + 1] is LSL_Float) 9574 if (commandList.Data[i + 1] is LSL_Float)
@@ -9046,7 +9580,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9046 } 9580 }
9047 break; 9581 break;
9048 9582
9049 case ParcelMediaCommandEnum.AutoAlign: 9583 case (uint)ParcelMediaCommandEnum.AutoAlign:
9050 if ((i + 1) < commandList.Length) 9584 if ((i + 1) < commandList.Length)
9051 { 9585 {
9052 if (commandList.Data[i + 1] is LSL_Integer) 9586 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9060,7 +9594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9060 } 9594 }
9061 break; 9595 break;
9062 9596
9063 case ParcelMediaCommandEnum.Type: 9597 case (uint)ParcelMediaCommandEnum.Type:
9064 if ((i + 1) < commandList.Length) 9598 if ((i + 1) < commandList.Length)
9065 { 9599 {
9066 if (commandList.Data[i + 1] is LSL_String) 9600 if (commandList.Data[i + 1] is LSL_String)
@@ -9073,7 +9607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9073 } 9607 }
9074 break; 9608 break;
9075 9609
9076 case ParcelMediaCommandEnum.Desc: 9610 case (uint)ParcelMediaCommandEnum.Desc:
9077 if ((i + 1) < commandList.Length) 9611 if ((i + 1) < commandList.Length)
9078 { 9612 {
9079 if (commandList.Data[i + 1] is LSL_String) 9613 if (commandList.Data[i + 1] is LSL_String)
@@ -9086,7 +9620,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9086 } 9620 }
9087 break; 9621 break;
9088 9622
9089 case ParcelMediaCommandEnum.Size: 9623 case (uint)ParcelMediaCommandEnum.Size:
9090 if ((i + 2) < commandList.Length) 9624 if ((i + 2) < commandList.Length)
9091 { 9625 {
9092 if (commandList.Data[i + 1] is LSL_Integer) 9626 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9156,7 +9690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9156 } 9690 }
9157 } 9691 }
9158 9692
9159 if (commandToSend != null) 9693 if (commandToSend != 0)
9160 { 9694 {
9161 // the commandList contained a start/stop/... command, too 9695 // the commandList contained a start/stop/... command, too
9162 if (presence == null) 9696 if (presence == null)
@@ -9193,7 +9727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9193 9727
9194 if (aList.Data[i] != null) 9728 if (aList.Data[i] != null)
9195 { 9729 {
9196 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9730 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9197 { 9731 {
9198 case ParcelMediaCommandEnum.Url: 9732 case ParcelMediaCommandEnum.Url:
9199 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9733 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9236,16 +9770,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9236 { 9770 {
9237 m_host.AddScriptLPS(1); 9771 m_host.AddScriptLPS(1);
9238 9772
9239 lock (m_host.TaskInventory) 9773 m_host.TaskInventory.LockItemsForRead(true);
9774 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9240 { 9775 {
9241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9776 if (inv.Value.Name == name)
9242 { 9777 {
9243 if (inv.Value.Name == name) 9778 m_host.TaskInventory.LockItemsForRead(false);
9244 { 9779 return inv.Value.Type;
9245 return inv.Value.Type;
9246 }
9247 } 9780 }
9248 } 9781 }
9782 m_host.TaskInventory.LockItemsForRead(false);
9249 9783
9250 return -1; 9784 return -1;
9251 } 9785 }
@@ -9256,15 +9790,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9256 9790
9257 if (quick_pay_buttons.Data.Length < 4) 9791 if (quick_pay_buttons.Data.Length < 4)
9258 { 9792 {
9259 LSLError("List must have at least 4 elements"); 9793 int x;
9260 return; 9794 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9795 {
9796 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9797 }
9261 } 9798 }
9262 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9799 int[] nPrice = new int[5];
9263 9800 nPrice[0]=price;
9264 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9801 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9265 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9802 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9266 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9803 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9267 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9804 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9805 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9268 m_host.ParentGroup.HasGroupChanged = true; 9806 m_host.ParentGroup.HasGroupChanged = true;
9269 } 9807 }
9270 9808
@@ -9276,17 +9814,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9276 if (invItemID == UUID.Zero) 9814 if (invItemID == UUID.Zero)
9277 return new LSL_Vector(); 9815 return new LSL_Vector();
9278 9816
9279 lock (m_host.TaskInventory) 9817 m_host.TaskInventory.LockItemsForRead(true);
9818 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9280 { 9819 {
9281 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9820 m_host.TaskInventory.LockItemsForRead(false);
9282 return new LSL_Vector(); 9821 return new LSL_Vector();
9822 }
9283 9823
9284 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9824 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9285 { 9825 {
9286 ShoutError("No permissions to track the camera"); 9826 ShoutError("No permissions to track the camera");
9287 return new LSL_Vector(); 9827 m_host.TaskInventory.LockItemsForRead(false);
9288 } 9828 return new LSL_Vector();
9289 } 9829 }
9830 m_host.TaskInventory.LockItemsForRead(false);
9290 9831
9291 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9832 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9292 if (presence != null) 9833 if (presence != null)
@@ -9304,17 +9845,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9304 if (invItemID == UUID.Zero) 9845 if (invItemID == UUID.Zero)
9305 return new LSL_Rotation(); 9846 return new LSL_Rotation();
9306 9847
9307 lock (m_host.TaskInventory) 9848 m_host.TaskInventory.LockItemsForRead(true);
9849 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9308 { 9850 {
9309 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9851 m_host.TaskInventory.LockItemsForRead(false);
9310 return new LSL_Rotation(); 9852 return new LSL_Rotation();
9311
9312 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9313 {
9314 ShoutError("No permissions to track the camera");
9315 return new LSL_Rotation();
9316 }
9317 } 9853 }
9854 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9855 {
9856 ShoutError("No permissions to track the camera");
9857 m_host.TaskInventory.LockItemsForRead(false);
9858 return new LSL_Rotation();
9859 }
9860 m_host.TaskInventory.LockItemsForRead(false);
9318 9861
9319 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9862 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9320 if (presence != null) 9863 if (presence != null)
@@ -9376,8 +9919,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9376 { 9919 {
9377 m_host.AddScriptLPS(1); 9920 m_host.AddScriptLPS(1);
9378 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9921 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9379 if (detectedParams == null) return; // only works on the first detected avatar 9922 if (detectedParams == null)
9380 9923 {
9924 if (m_host.IsAttachment == true)
9925 {
9926 detectedParams = new DetectParams();
9927 detectedParams.Key = m_host.OwnerID;
9928 }
9929 else
9930 {
9931 return;
9932 }
9933 }
9934
9381 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9935 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9382 if (avatar != null) 9936 if (avatar != null)
9383 { 9937 {
@@ -9385,6 +9939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9385 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9939 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9386 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9940 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9387 } 9941 }
9942
9388 ScriptSleep(1000); 9943 ScriptSleep(1000);
9389 } 9944 }
9390 9945
@@ -9464,14 +10019,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 if (objectID == UUID.Zero) return; 10019 if (objectID == UUID.Zero) return;
9465 10020
9466 UUID agentID; 10021 UUID agentID;
9467 lock (m_host.TaskInventory) 10022 m_host.TaskInventory.LockItemsForRead(true);
9468 { 10023 // we need the permission first, to know which avatar we want to set the camera for
9469 // we need the permission first, to know which avatar we want to set the camera for 10024 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9470 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9471 10025
9472 if (agentID == UUID.Zero) return; 10026 if (agentID == UUID.Zero)
9473 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10027 {
10028 m_host.TaskInventory.LockItemsForRead(false);
10029 return;
9474 } 10030 }
10031 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10032 {
10033 m_host.TaskInventory.LockItemsForRead(false);
10034 return;
10035 }
10036 m_host.TaskInventory.LockItemsForRead(false);
9475 10037
9476 ScenePresence presence = World.GetScenePresence(agentID); 10038 ScenePresence presence = World.GetScenePresence(agentID);
9477 10039
@@ -9480,12 +10042,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 10042
9481 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10043 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9482 object[] data = rules.Data; 10044 object[] data = rules.Data;
9483 for (int i = 0; i < data.Length; ++i) { 10045 for (int i = 0; i < data.Length; ++i)
10046 {
9484 int type = Convert.ToInt32(data[i++].ToString()); 10047 int type = Convert.ToInt32(data[i++].ToString());
9485 if (i >= data.Length) break; // odd number of entries => ignore the last 10048 if (i >= data.Length) break; // odd number of entries => ignore the last
9486 10049
9487 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10050 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9488 switch (type) { 10051 switch (type)
10052 {
9489 case ScriptBaseClass.CAMERA_FOCUS: 10053 case ScriptBaseClass.CAMERA_FOCUS:
9490 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10054 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9491 case ScriptBaseClass.CAMERA_POSITION: 10055 case ScriptBaseClass.CAMERA_POSITION:
@@ -9521,12 +10085,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9521 10085
9522 // we need the permission first, to know which avatar we want to clear the camera for 10086 // we need the permission first, to know which avatar we want to clear the camera for
9523 UUID agentID; 10087 UUID agentID;
9524 lock (m_host.TaskInventory) 10088 m_host.TaskInventory.LockItemsForRead(true);
10089 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10090 if (agentID == UUID.Zero)
9525 { 10091 {
9526 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10092 m_host.TaskInventory.LockItemsForRead(false);
9527 if (agentID == UUID.Zero) return; 10093 return;
9528 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10094 }
10095 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10096 {
10097 m_host.TaskInventory.LockItemsForRead(false);
10098 return;
9529 } 10099 }
10100 m_host.TaskInventory.LockItemsForRead(false);
9530 10101
9531 ScenePresence presence = World.GetScenePresence(agentID); 10102 ScenePresence presence = World.GetScenePresence(agentID);
9532 10103
@@ -9593,19 +10164,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9593 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10164 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9594 { 10165 {
9595 m_host.AddScriptLPS(1); 10166 m_host.AddScriptLPS(1);
9596 string ret = String.Empty; 10167
9597 string src1 = llBase64ToString(str1); 10168 if (str1 == String.Empty)
9598 string src2 = llBase64ToString(str2); 10169 return String.Empty;
9599 int c = 0; 10170 if (str2 == String.Empty)
9600 for (int i = 0; i < src1.Length; i++) 10171 return str1;
10172
10173 byte[] data1;
10174 byte[] data2;
10175 try
10176 {
10177 data1 = Convert.FromBase64String(str1);
10178 data2 = Convert.FromBase64String(str2);
10179 }
10180 catch (Exception)
9601 { 10181 {
9602 ret += (char) (src1[i] ^ src2[c]); 10182 return new LSL_String(String.Empty);
10183 }
9603 10184
9604 c++; 10185 byte[] d2 = new Byte[data1.Length];
9605 if (c >= src2.Length) 10186 int pos = 0;
9606 c = 0; 10187
10188 if (data1.Length <= data2.Length)
10189 {
10190 Array.Copy(data2, 0, d2, 0, data1.Length);
9607 } 10191 }
9608 return llStringToBase64(ret); 10192 else
10193 {
10194 while (pos < data1.Length)
10195 {
10196 int len = data1.Length - pos;
10197 if (len > data2.Length)
10198 len = data2.Length;
10199
10200 Array.Copy(data2, 0, d2, pos, len);
10201 pos += len;
10202 }
10203 }
10204
10205 for (pos = 0 ; pos < data1.Length ; pos++ )
10206 data1[pos] ^= d2[pos];
10207
10208 return Convert.ToBase64String(data1);
9609 } 10209 }
9610 10210
9611 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10211 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9664,12 +10264,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9664 Regex r = new Regex(authregex); 10264 Regex r = new Regex(authregex);
9665 int[] gnums = r.GetGroupNumbers(); 10265 int[] gnums = r.GetGroupNumbers();
9666 Match m = r.Match(url); 10266 Match m = r.Match(url);
9667 if (m.Success) { 10267 if (m.Success)
9668 for (int i = 1; i < gnums.Length; i++) { 10268 {
10269 for (int i = 1; i < gnums.Length; i++)
10270 {
9669 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10271 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9670 //CaptureCollection cc = g.Captures; 10272 //CaptureCollection cc = g.Captures;
9671 } 10273 }
9672 if (m.Groups.Count == 5) { 10274 if (m.Groups.Count == 5)
10275 {
9673 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10276 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9674 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10277 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9675 } 10278 }
@@ -9983,15 +10586,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9983 10586
9984 internal UUID ScriptByName(string name) 10587 internal UUID ScriptByName(string name)
9985 { 10588 {
9986 lock (m_host.TaskInventory) 10589 m_host.TaskInventory.LockItemsForRead(true);
10590
10591 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9987 { 10592 {
9988 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10593 if (item.Type == 10 && item.Name == name)
9989 { 10594 {
9990 if (item.Type == 10 && item.Name == name) 10595 m_host.TaskInventory.LockItemsForRead(false);
9991 return item.ItemID; 10596 return item.ItemID;
9992 } 10597 }
9993 } 10598 }
9994 10599
10600 m_host.TaskInventory.LockItemsForRead(false);
10601
9995 return UUID.Zero; 10602 return UUID.Zero;
9996 } 10603 }
9997 10604
@@ -10032,6 +10639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10032 { 10639 {
10033 m_host.AddScriptLPS(1); 10640 m_host.AddScriptLPS(1);
10034 10641
10642 //Clone is thread safe
10035 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10643 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10036 10644
10037 UUID assetID = UUID.Zero; 10645 UUID assetID = UUID.Zero;
@@ -10094,6 +10702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10094 { 10702 {
10095 m_host.AddScriptLPS(1); 10703 m_host.AddScriptLPS(1);
10096 10704
10705 //Clone is thread safe
10097 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10706 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10098 10707
10099 UUID assetID = UUID.Zero; 10708 UUID assetID = UUID.Zero;
@@ -10173,6 +10782,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10173 10782
10174 return GetLinkPrimitiveParams(obj, rules); 10783 return GetLinkPrimitiveParams(obj, rules);
10175 } 10784 }
10785
10786 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10787 {
10788 List<SceneObjectPart> parts = GetLinkParts(link);
10789 if (parts.Count < 1)
10790 return 0;
10791
10792 return GetNumberOfSides(parts[0]);
10793 }
10176 } 10794 }
10177 10795
10178 public class NotecardCache 10796 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8a98be7..5212e1b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2258,9 +2271,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2258 { 2271 {
2259 if (avatar.IsChildAgent == false) 2272 if (avatar.IsChildAgent == false)
2260 { 2273 {
2261 result.Add(avatar.UUID); 2274 result.Add(new LSL_Key(avatar.UUID.ToString()));
2262 result.Add(avatar.AbsolutePosition); 2275 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2263 result.Add(avatar.Name); 2276 result.Add(new LSL_String(avatar.Name));
2264 } 2277 }
2265 } 2278 }
2266 }); 2279 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fefbb35..3b7de53 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/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 561e3b3..bae7d4b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -398,6 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
398 LSL_Vector llWind(LSL_Vector offset); 398 LSL_Vector llWind(LSL_Vector offset);
399 LSL_String llXorBase64Strings(string str1, string str2); 399 LSL_String llXorBase64Strings(string str1, string str2);
400 LSL_String llXorBase64StringsCorrect(string str1, string str2); 400 LSL_String llXorBase64StringsCorrect(string str1, string str2);
401 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
401 402
402 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 403 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
403 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 404 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 630821b..fbf601a 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 b96e977..0342283 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
280 public const int CHANGED_MEDIA = 2048; 280 public const int CHANGED_MEDIA = 2048;
281 public const int CHANGED_ANIMATION = 16384; 281 public const int CHANGED_ANIMATION = 16384;
282 public const int CHANGED_POSITION = 32768;
282 public const int TYPE_INVALID = 0; 283 public const int TYPE_INVALID = 0;
283 public const int TYPE_INTEGER = 1; 284 public const int TYPE_INTEGER = 1;
284 public const int TYPE_FLOAT = 2; 285 public const int TYPE_FLOAT = 2;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..7c26824 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();
@@ -1847,5 +1849,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1847 { 1849 {
1848 return m_LSL_Functions.llClearPrimMedia(face); 1850 return m_LSL_Functions.llClearPrimMedia(face);
1849 } 1851 }
1852
1853 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1854 {
1855 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1856 }
1850 } 1857 }
1851} 1858}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ 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
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6663aa5..623cb7d 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;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -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();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -429,14 +430,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 430 {
430 int permsMask; 431 int permsMask;
431 UUID permsGranter; 432 UUID permsGranter;
432 lock (part.TaskInventory) 433 part.TaskInventory.LockItemsForRead(true);
434 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 435 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 436 part.TaskInventory.LockItemsForRead(false);
435 return; 437 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 438 }
439 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
440 permsMask = part.TaskInventory[m_ItemID].PermsMask;
441 part.TaskInventory.LockItemsForRead(false);
440 442
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 443 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 444 {
@@ -545,6 +547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 547 return true;
546 } 548 }
547 549
550 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 551 public void SetState(string state)
549 { 552 {
550 if (state == State) 553 if (state == State)
@@ -556,7 +559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 559 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 560 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 561 new DetectParams[0]));
559 562
560 throw new EventAbortException(); 563 throw new EventAbortException();
561 } 564 }
562 565
@@ -639,14 +642,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 642 /// <returns></returns>
640 public object EventProcessor() 643 public object EventProcessor()
641 { 644 {
642 if (m_Suspended) 645 EventParams data = null;
643 return 0;
644 646
645 lock (m_Script) 647 lock (m_EventQueue)
646 { 648 {
647 EventParams data = null; 649 if (m_Suspended)
650 return 0;
648 651
649 lock (m_EventQueue) 652 lock (m_Script)
650 { 653 {
651 data = (EventParams) m_EventQueue.Dequeue(); 654 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 655 if (data == null) // Shouldn't happen
@@ -672,6 +675,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 675 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 676 m_CollisionInQueue = false;
674 } 677 }
678 }
679 lock(m_Script)
680 {
675 681
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 682 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 683
@@ -828,6 +834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 834 new Object[0], new DetectParams[0]));
829 } 835 }
830 836
837 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 838 public void ApiResetScript()
832 { 839 {
833 // bool running = Running; 840 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 8629674..35cc65b 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
103 private Dictionary<UUID, IScriptInstance> m_Scripts = 104 private Dictionary<UUID, IScriptInstance> m_Scripts =
104 new Dictionary<UUID, IScriptInstance>(); 105 new Dictionary<UUID, IScriptInstance>();
105 106
107 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
108
106 // Maps the asset ID to the assembly 109 // Maps the asset ID to the assembly
107 110
108 private Dictionary<UUID, string> m_Assemblies = 111 private Dictionary<UUID, string> m_Assemblies =
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
125 IWorkItemResult m_CurrentCompile = null; 128 IWorkItemResult m_CurrentCompile = null;
126 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 129 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
127 130
131 private void lockScriptsForRead(bool locked)
132 {
133 if (locked)
134 {
135 if (m_scriptsLock.RecursiveReadCount > 0)
136 {
137 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
138 m_scriptsLock.ExitReadLock();
139 }
140 if (m_scriptsLock.RecursiveWriteCount > 0)
141 {
142 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
143 m_scriptsLock.ExitWriteLock();
144 }
145
146 while (!m_scriptsLock.TryEnterReadLock(60000))
147 {
148 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
149 if (m_scriptsLock.IsWriteLockHeld)
150 {
151 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152 }
153 }
154 }
155 else
156 {
157 if (m_scriptsLock.RecursiveReadCount > 0)
158 {
159 m_scriptsLock.ExitReadLock();
160 }
161 }
162 }
163 private void lockScriptsForWrite(bool locked)
164 {
165 if (locked)
166 {
167 if (m_scriptsLock.RecursiveReadCount > 0)
168 {
169 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
170 m_scriptsLock.ExitReadLock();
171 }
172 if (m_scriptsLock.RecursiveWriteCount > 0)
173 {
174 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
175 m_scriptsLock.ExitWriteLock();
176 }
177
178 while (!m_scriptsLock.TryEnterWriteLock(60000))
179 {
180 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
181 if (m_scriptsLock.IsWriteLockHeld)
182 {
183 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
184 }
185 }
186 }
187 else
188 {
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_scriptsLock.ExitWriteLock();
192 }
193 }
194 }
195
128 public string ScriptEngineName 196 public string ScriptEngineName
129 { 197 {
130 get { return "XEngine"; } 198 get { return "XEngine"; }
@@ -270,43 +338,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
270 338
271 public void RemoveRegion(Scene scene) 339 public void RemoveRegion(Scene scene)
272 { 340 {
273 lock (m_Scripts) 341 lockScriptsForRead(true);
342 foreach (IScriptInstance instance in m_Scripts.Values)
274 { 343 {
275 foreach (IScriptInstance instance in m_Scripts.Values) 344 // Force a final state save
345 //
346 if (m_Assemblies.ContainsKey(instance.AssetID))
276 { 347 {
277 // Force a final state save 348 string assembly = m_Assemblies[instance.AssetID];
278 // 349 instance.SaveState(assembly);
279 if (m_Assemblies.ContainsKey(instance.AssetID)) 350 }
280 {
281 string assembly = m_Assemblies[instance.AssetID];
282 instance.SaveState(assembly);
283 }
284 351
285 // Clear the event queue and abort the instance thread 352 // Clear the event queue and abort the instance thread
286 // 353 //
287 instance.ClearQueue(); 354 instance.ClearQueue();
288 instance.Stop(0); 355 instance.Stop(0);
289 356
290 // Release events, timer, etc 357 // Release events, timer, etc
291 // 358 //
292 instance.DestroyScriptInstance(); 359 instance.DestroyScriptInstance();
293 360
294 // Unload scripts and app domains 361 // Unload scripts and app domains
295 // Must be done explicitly because they have infinite 362 // Must be done explicitly because they have infinite
296 // lifetime 363 // lifetime
297 // 364 //
298 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 365 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
299 if (m_DomainScripts[instance.AppDomain].Count == 0) 366 if (m_DomainScripts[instance.AppDomain].Count == 0)
300 { 367 {
301 m_DomainScripts.Remove(instance.AppDomain); 368 m_DomainScripts.Remove(instance.AppDomain);
302 UnloadAppDomain(instance.AppDomain); 369 UnloadAppDomain(instance.AppDomain);
303 }
304 } 370 }
305 m_Scripts.Clear();
306 m_PrimObjects.Clear();
307 m_Assemblies.Clear();
308 m_DomainScripts.Clear();
309 } 371 }
372 lockScriptsForRead(false);
373 lockScriptsForWrite(true);
374 m_Scripts.Clear();
375 lockScriptsForWrite(false);
376 m_PrimObjects.Clear();
377 m_Assemblies.Clear();
378 m_DomainScripts.Clear();
379
310 lock (m_ScriptEngines) 380 lock (m_ScriptEngines)
311 { 381 {
312 m_ScriptEngines.Remove(this); 382 m_ScriptEngines.Remove(this);
@@ -365,22 +435,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
365 435
366 List<IScriptInstance> instances = new List<IScriptInstance>(); 436 List<IScriptInstance> instances = new List<IScriptInstance>();
367 437
368 lock (m_Scripts) 438 lockScriptsForRead(true);
369 { 439 foreach (IScriptInstance instance in m_Scripts.Values)
370 foreach (IScriptInstance instance in m_Scripts.Values)
371 instances.Add(instance); 440 instances.Add(instance);
372 } 441 lockScriptsForRead(false);
373 442
374 foreach (IScriptInstance i in instances) 443 foreach (IScriptInstance i in instances)
375 { 444 {
376 string assembly = String.Empty; 445 string assembly = String.Empty;
377 446
378 lock (m_Scripts) 447
379 {
380 if (!m_Assemblies.ContainsKey(i.AssetID)) 448 if (!m_Assemblies.ContainsKey(i.AssetID))
381 continue; 449 continue;
382 assembly = m_Assemblies[i.AssetID]; 450 assembly = m_Assemblies[i.AssetID];
383 } 451
384 452
385 i.SaveState(assembly); 453 i.SaveState(assembly);
386 } 454 }
@@ -709,92 +777,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
709 } 777 }
710 778
711 ScriptInstance instance = null; 779 ScriptInstance instance = null;
712 lock (m_Scripts) 780 // Create the object record
781 lockScriptsForRead(true);
782 if ((!m_Scripts.ContainsKey(itemID)) ||
783 (m_Scripts[itemID].AssetID != assetID))
713 { 784 {
714 // Create the object record 785 lockScriptsForRead(false);
715 786
716 if ((!m_Scripts.ContainsKey(itemID)) || 787 UUID appDomain = assetID;
717 (m_Scripts[itemID].AssetID != assetID))
718 {
719 UUID appDomain = assetID;
720 788
721 if (part.ParentGroup.IsAttachment) 789 if (part.ParentGroup.IsAttachment)
722 appDomain = part.ParentGroup.RootPart.UUID; 790 appDomain = part.ParentGroup.RootPart.UUID;
723 791
724 if (!m_AppDomains.ContainsKey(appDomain)) 792 if (!m_AppDomains.ContainsKey(appDomain))
793 {
794 try
725 { 795 {
726 try 796 AppDomainSetup appSetup = new AppDomainSetup();
727 { 797 appSetup.PrivateBinPath = Path.Combine(
728 AppDomainSetup appSetup = new AppDomainSetup(); 798 m_ScriptEnginesPath,
729 appSetup.PrivateBinPath = Path.Combine( 799 m_Scene.RegionInfo.RegionID.ToString());
730 m_ScriptEnginesPath, 800
731 m_Scene.RegionInfo.RegionID.ToString()); 801 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
732 802 Evidence evidence = new Evidence(baseEvidence);
733 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 803
734 Evidence evidence = new Evidence(baseEvidence); 804 AppDomain sandbox;
735 805 if (m_AppDomainLoading)
736 AppDomain sandbox; 806 sandbox = AppDomain.CreateDomain(
737 if (m_AppDomainLoading) 807 m_Scene.RegionInfo.RegionID.ToString(),
738 sandbox = AppDomain.CreateDomain( 808 evidence, appSetup);
739 m_Scene.RegionInfo.RegionID.ToString(), 809 else
740 evidence, appSetup); 810 sandbox = AppDomain.CurrentDomain;
741 else 811
742 sandbox = AppDomain.CurrentDomain; 812 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
743 813 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
744 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 814 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
745 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 815 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
746 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 816 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
747 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 817 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
748 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 818 //sandbox.SetAppDomainPolicy(sandboxPolicy);
749 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 819
750 //sandbox.SetAppDomainPolicy(sandboxPolicy); 820 m_AppDomains[appDomain] = sandbox;
751 821
752 m_AppDomains[appDomain] = sandbox; 822 m_AppDomains[appDomain].AssemblyResolve +=
753 823 new ResolveEventHandler(
754 m_AppDomains[appDomain].AssemblyResolve += 824 AssemblyResolver.OnAssemblyResolve);
755 new ResolveEventHandler( 825 m_DomainScripts[appDomain] = new List<UUID>();
756 AssemblyResolver.OnAssemblyResolve); 826 }
757 m_DomainScripts[appDomain] = new List<UUID>(); 827 catch (Exception e)
758 } 828 {
759 catch (Exception e) 829 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
830 m_ScriptErrorMessage += "Exception creating app domain:\n";
831 m_ScriptFailCount++;
832 lock (m_AddingAssemblies)
760 { 833 {
761 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 834 m_AddingAssemblies[assembly]--;
762 m_ScriptErrorMessage += "Exception creating app domain:\n";
763 m_ScriptFailCount++;
764 lock (m_AddingAssemblies)
765 {
766 m_AddingAssemblies[assembly]--;
767 }
768 return false;
769 } 835 }
836 return false;
770 } 837 }
771 m_DomainScripts[appDomain].Add(itemID); 838 }
772 839 m_DomainScripts[appDomain].Add(itemID);
773 instance = new ScriptInstance(this, part, 840
774 itemID, assetID, assembly, 841 instance = new ScriptInstance(this, part,
775 m_AppDomains[appDomain], 842 itemID, assetID, assembly,
776 part.ParentGroup.RootPart.Name, 843 m_AppDomains[appDomain],
777 item.Name, startParam, postOnRez, 844 part.ParentGroup.RootPart.Name,
778 stateSource, m_MaxScriptQueue); 845 item.Name, startParam, postOnRez,
779 846 stateSource, m_MaxScriptQueue);
780 m_log.DebugFormat( 847
848 m_log.DebugFormat(
781 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 849 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
782 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 850 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
783 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 851 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
784 852
785 if (presence != null) 853 if (presence != null)
786 { 854 {
787 ShowScriptSaveResponse(item.OwnerID, 855 ShowScriptSaveResponse(item.OwnerID,
788 assetID, "Compile successful", true); 856 assetID, "Compile successful", true);
789 }
790
791 instance.AppDomain = appDomain;
792 instance.LineMap = linemap;
793
794 m_Scripts[itemID] = instance;
795 } 857 }
796 }
797 858
859 instance.AppDomain = appDomain;
860 instance.LineMap = linemap;
861 lockScriptsForWrite(true);
862 m_Scripts[itemID] = instance;
863 lockScriptsForWrite(false);
864 }
865 else
866 {
867 lockScriptsForRead(false);
868 }
798 lock (m_PrimObjects) 869 lock (m_PrimObjects)
799 { 870 {
800 if (!m_PrimObjects.ContainsKey(localID)) 871 if (!m_PrimObjects.ContainsKey(localID))
@@ -813,9 +884,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
813 m_AddingAssemblies[assembly]--; 884 m_AddingAssemblies[assembly]--;
814 } 885 }
815 886
816 if (instance != null) 887 if (instance!=null)
817 instance.Init(); 888 instance.Init();
818 889
819 return true; 890 return true;
820 } 891 }
821 892
@@ -828,20 +899,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
828 m_CompileDict.Remove(itemID); 899 m_CompileDict.Remove(itemID);
829 } 900 }
830 901
831 IScriptInstance instance = null; 902 lockScriptsForRead(true);
832 903 // Do we even have it?
833 lock (m_Scripts) 904 if (!m_Scripts.ContainsKey(itemID))
834 { 905 {
835 // Do we even have it? 906 lockScriptsForRead(false);
836 if (!m_Scripts.ContainsKey(itemID)) 907 return;
837 return;
838
839 instance=m_Scripts[itemID];
840 m_Scripts.Remove(itemID);
841 } 908 }
909
842 910
911 IScriptInstance instance=m_Scripts[itemID];
912 lockScriptsForRead(false);
913 lockScriptsForWrite(true);
914 m_Scripts.Remove(itemID);
915 lockScriptsForWrite(false);
843 instance.ClearQueue(); 916 instance.ClearQueue();
844 instance.Stop(0); 917 instance.Stop(0);
918
845// bool objectRemoved = false; 919// bool objectRemoved = false;
846 920
847 lock (m_PrimObjects) 921 lock (m_PrimObjects)
@@ -877,11 +951,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
877 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 951 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
878 if (handlerObjectRemoved != null) 952 if (handlerObjectRemoved != null)
879 { 953 {
880 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 954 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
881 handlerObjectRemoved(part.UUID); 955 handlerObjectRemoved(part.UUID);
882 } 956 }
883 957
884 958 CleanAssemblies();
959
885 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 960 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
886 if (handlerScriptRemoved != null) 961 if (handlerScriptRemoved != null)
887 handlerScriptRemoved(itemID); 962 handlerScriptRemoved(itemID);
@@ -1023,7 +1098,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1023 return false; 1098 return false;
1024 1099
1025 uuids = m_PrimObjects[localID]; 1100 uuids = m_PrimObjects[localID];
1026 } 1101
1027 1102
1028 foreach (UUID itemID in uuids) 1103 foreach (UUID itemID in uuids)
1029 { 1104 {
@@ -1041,6 +1116,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1041 result = true; 1116 result = true;
1042 } 1117 }
1043 } 1118 }
1119 }
1044 1120
1045 return result; 1121 return result;
1046 } 1122 }
@@ -1140,12 +1216,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1140 private IScriptInstance GetInstance(UUID itemID) 1216 private IScriptInstance GetInstance(UUID itemID)
1141 { 1217 {
1142 IScriptInstance instance; 1218 IScriptInstance instance;
1143 lock (m_Scripts) 1219 lockScriptsForRead(true);
1220 if (!m_Scripts.ContainsKey(itemID))
1144 { 1221 {
1145 if (!m_Scripts.ContainsKey(itemID)) 1222 lockScriptsForRead(false);
1146 return null; 1223 return null;
1147 instance = m_Scripts[itemID];
1148 } 1224 }
1225 instance = m_Scripts[itemID];
1226 lockScriptsForRead(false);
1149 return instance; 1227 return instance;
1150 } 1228 }
1151 1229
@@ -1169,6 +1247,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1169 return false; 1247 return false;
1170 } 1248 }
1171 1249
1250 [DebuggerNonUserCode]
1172 public void ApiResetScript(UUID itemID) 1251 public void ApiResetScript(UUID itemID)
1173 { 1252 {
1174 IScriptInstance instance = GetInstance(itemID); 1253 IScriptInstance instance = GetInstance(itemID);
@@ -1220,6 +1299,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1220 return UUID.Zero; 1299 return UUID.Zero;
1221 } 1300 }
1222 1301
1302 [DebuggerNonUserCode]
1223 public void SetState(UUID itemID, string newState) 1303 public void SetState(UUID itemID, string newState)
1224 { 1304 {
1225 IScriptInstance instance = GetInstance(itemID); 1305 IScriptInstance instance = GetInstance(itemID);
@@ -1240,11 +1320,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1240 { 1320 {
1241 List<IScriptInstance> instances = new List<IScriptInstance>(); 1321 List<IScriptInstance> instances = new List<IScriptInstance>();
1242 1322
1243 lock (m_Scripts) 1323 lockScriptsForRead(true);
1244 { 1324 foreach (IScriptInstance instance in m_Scripts.Values)
1245 foreach (IScriptInstance instance in m_Scripts.Values)
1246 instances.Add(instance); 1325 instances.Add(instance);
1247 } 1326 lockScriptsForRead(false);
1248 1327
1249 foreach (IScriptInstance i in instances) 1328 foreach (IScriptInstance i in instances)
1250 { 1329 {