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 cc3cf17..254ed0f 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;
@@ -3023,6 +3253,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3023 3253
3024 public void llInstantMessage(string user, string message) 3254 public void llInstantMessage(string user, string message)
3025 { 3255 {
3256 UUID result;
3257 if (!UUID.TryParse(user, out result))
3258 {
3259 ShoutError("An invalid key was passed to llInstantMessage");
3260 ScriptSleep(2000);
3261 return;
3262 }
3263
3264
3026 m_host.AddScriptLPS(1); 3265 m_host.AddScriptLPS(1);
3027 3266
3028 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3267 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3037,14 +3276,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 UUID friendTransactionID = UUID.Random(); 3276 UUID friendTransactionID = UUID.Random();
3038 3277
3039 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3278 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3040 3279
3041 GridInstantMessage msg = new GridInstantMessage(); 3280 GridInstantMessage msg = new GridInstantMessage();
3042 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3281 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3043 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3282 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3044 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3283 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3045// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3284// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3046// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3285// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3047 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3286 DateTime dt = DateTime.UtcNow;
3287
3288 // Ticks from UtcNow, but make it look like local. Evil, huh?
3289 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3290
3291 try
3292 {
3293 // Convert that to the PST timezone
3294 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3295 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3296 }
3297 catch
3298 {
3299 // No logging here, as it could be VERY spammy
3300 }
3301
3302 // And make it look local again to fool the unix time util
3303 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3304
3305 msg.timestamp = (uint)Util.ToUnixTime(dt);
3306
3048 //if (client != null) 3307 //if (client != null)
3049 //{ 3308 //{
3050 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3309 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3058,13 +3317,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3058 msg.message = message.Substring(0, 1024); 3317 msg.message = message.Substring(0, 1024);
3059 else 3318 else
3060 msg.message = message; 3319 msg.message = message;
3061 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3320 msg.dialog = (byte)19; // MessageFromObject
3062 msg.fromGroup = false;// fromGroup; 3321 msg.fromGroup = false;// fromGroup;
3063 msg.offline = (byte)0; //offline; 3322 msg.offline = (byte)0; //offline;
3064 msg.ParentEstateID = 0; //ParentEstateID; 3323 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3065 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3324 msg.Position = new Vector3(m_host.AbsolutePosition);
3066 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3325 msg.RegionID = World.RegionInfo.RegionID.Guid;
3067 msg.binaryBucket = new byte[0];// binaryBucket; 3326 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3068 3327
3069 if (m_TransferModule != null) 3328 if (m_TransferModule != null)
3070 { 3329 {
@@ -3084,7 +3343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3084 } 3343 }
3085 3344
3086 emailModule.SendEmail(m_host.UUID, address, subject, message); 3345 emailModule.SendEmail(m_host.UUID, address, subject, message);
3087 ScriptSleep(20000); 3346 ScriptSleep(15000);
3088 } 3347 }
3089 3348
3090 public void llGetNextEmail(string address, string subject) 3349 public void llGetNextEmail(string address, string subject)
@@ -3186,13 +3445,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3186 m_host.AddScriptLPS(1); 3445 m_host.AddScriptLPS(1);
3187 } 3446 }
3188 3447
3189 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3190 {
3191 m_host.AddScriptLPS(1);
3192 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3193 m_host.RotLookAt(rot, (float)strength, (float)damping);
3194 }
3195
3196 public LSL_Integer llStringLength(string str) 3448 public LSL_Integer llStringLength(string str)
3197 { 3449 {
3198 m_host.AddScriptLPS(1); 3450 m_host.AddScriptLPS(1);
@@ -3216,14 +3468,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3216 3468
3217 TaskInventoryItem item; 3469 TaskInventoryItem item;
3218 3470
3219 lock (m_host.TaskInventory) 3471 m_host.TaskInventory.LockItemsForRead(true);
3472 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3220 { 3473 {
3221 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3474 m_host.TaskInventory.LockItemsForRead(false);
3222 return; 3475 return;
3223 else
3224 item = m_host.TaskInventory[InventorySelf()];
3225 } 3476 }
3226 3477 else
3478 {
3479 item = m_host.TaskInventory[InventorySelf()];
3480 }
3481 m_host.TaskInventory.LockItemsForRead(false);
3227 if (item.PermsGranter == UUID.Zero) 3482 if (item.PermsGranter == UUID.Zero)
3228 return; 3483 return;
3229 3484
@@ -3253,13 +3508,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3253 3508
3254 TaskInventoryItem item; 3509 TaskInventoryItem item;
3255 3510
3256 lock (m_host.TaskInventory) 3511 m_host.TaskInventory.LockItemsForRead(true);
3512 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3257 { 3513 {
3258 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3514 m_host.TaskInventory.LockItemsForRead(false);
3259 return; 3515 return;
3260 else
3261 item = m_host.TaskInventory[InventorySelf()];
3262 } 3516 }
3517 else
3518 {
3519 item = m_host.TaskInventory[InventorySelf()];
3520 }
3521 m_host.TaskInventory.LockItemsForRead(false);
3522
3263 3523
3264 if (item.PermsGranter == UUID.Zero) 3524 if (item.PermsGranter == UUID.Zero)
3265 return; 3525 return;
@@ -3330,10 +3590,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3330 3590
3331 TaskInventoryItem item; 3591 TaskInventoryItem item;
3332 3592
3333 lock (m_host.TaskInventory) 3593
3594 m_host.TaskInventory.LockItemsForRead(true);
3595 if (!m_host.TaskInventory.ContainsKey(invItemID))
3596 {
3597 m_host.TaskInventory.LockItemsForRead(false);
3598 return;
3599 }
3600 else
3334 { 3601 {
3335 item = m_host.TaskInventory[invItemID]; 3602 item = m_host.TaskInventory[invItemID];
3336 } 3603 }
3604 m_host.TaskInventory.LockItemsForRead(false);
3337 3605
3338 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3606 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3339 { 3607 {
@@ -3365,11 +3633,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3365 3633
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3634 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3635 {
3368 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3637 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3638 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3639 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3640
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3641 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3642 "run_time_permissions", new Object[] {
@@ -3389,11 +3656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3656
3390 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3657 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3391 { 3658 {
3392 lock (m_host.TaskInventory) 3659 m_host.TaskInventory.LockItemsForWrite(true);
3393 { 3660 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3394 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3661 m_host.TaskInventory[invItemID].PermsMask = perm;
3395 m_host.TaskInventory[invItemID].PermsMask = perm; 3662 m_host.TaskInventory.LockItemsForWrite(false);
3396 }
3397 3663
3398 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3664 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3399 "run_time_permissions", new Object[] { 3665 "run_time_permissions", new Object[] {
@@ -3414,11 +3680,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 3680
3415 if (!m_waitingForScriptAnswer) 3681 if (!m_waitingForScriptAnswer)
3416 { 3682 {
3417 lock (m_host.TaskInventory) 3683 m_host.TaskInventory.LockItemsForWrite(true);
3418 { 3684 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3419 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3685 m_host.TaskInventory[invItemID].PermsMask = 0;
3420 m_host.TaskInventory[invItemID].PermsMask = 0; 3686 m_host.TaskInventory.LockItemsForWrite(false);
3421 }
3422 3687
3423 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3688 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3424 m_waitingForScriptAnswer=true; 3689 m_waitingForScriptAnswer=true;
@@ -3453,10 +3718,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3453 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3718 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3454 llReleaseControls(); 3719 llReleaseControls();
3455 3720
3456 lock (m_host.TaskInventory) 3721
3457 { 3722 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsMask = answer; 3723 m_host.TaskInventory[invItemID].PermsMask = answer;
3459 } 3724 m_host.TaskInventory.LockItemsForWrite(false);
3725
3460 3726
3461 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3727 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3728 "run_time_permissions", new Object[] {
@@ -3468,16 +3734,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3468 { 3734 {
3469 m_host.AddScriptLPS(1); 3735 m_host.AddScriptLPS(1);
3470 3736
3471 lock (m_host.TaskInventory) 3737 m_host.TaskInventory.LockItemsForRead(true);
3738
3739 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3472 { 3740 {
3473 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3741 if (item.Type == 10 && item.ItemID == m_itemID)
3474 { 3742 {
3475 if (item.Type == 10 && item.ItemID == m_itemID) 3743 m_host.TaskInventory.LockItemsForRead(false);
3476 { 3744 return item.PermsGranter.ToString();
3477 return item.PermsGranter.ToString();
3478 }
3479 } 3745 }
3480 } 3746 }
3747 m_host.TaskInventory.LockItemsForRead(false);
3481 3748
3482 return UUID.Zero.ToString(); 3749 return UUID.Zero.ToString();
3483 } 3750 }
@@ -3486,19 +3753,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3486 { 3753 {
3487 m_host.AddScriptLPS(1); 3754 m_host.AddScriptLPS(1);
3488 3755
3489 lock (m_host.TaskInventory) 3756 m_host.TaskInventory.LockItemsForRead(true);
3757
3758 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3490 { 3759 {
3491 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3760 if (item.Type == 10 && item.ItemID == m_itemID)
3492 { 3761 {
3493 if (item.Type == 10 && item.ItemID == m_itemID) 3762 int perms = item.PermsMask;
3494 { 3763 if (m_automaticLinkPermission)
3495 int perms = item.PermsMask; 3764 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3496 if (m_automaticLinkPermission) 3765 m_host.TaskInventory.LockItemsForRead(false);
3497 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3766 return perms;
3498 return perms;
3499 }
3500 } 3767 }
3501 } 3768 }
3769 m_host.TaskInventory.LockItemsForRead(false);
3502 3770
3503 return 0; 3771 return 0;
3504 } 3772 }
@@ -3520,9 +3788,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3520 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3788 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3521 { 3789 {
3522 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3790 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3523 3791 if (parts.Count > 0)
3524 foreach (SceneObjectPart part in parts) 3792 {
3525 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3793 try
3794 {
3795 parts[0].ParentGroup.areUpdatesSuspended = true;
3796 foreach (SceneObjectPart part in parts)
3797 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3798 }
3799 finally
3800 {
3801 parts[0].ParentGroup.areUpdatesSuspended = false;
3802 }
3803 }
3526 } 3804 }
3527 3805
3528 public void llCreateLink(string target, int parent) 3806 public void llCreateLink(string target, int parent)
@@ -3535,11 +3813,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3535 return; 3813 return;
3536 3814
3537 TaskInventoryItem item; 3815 TaskInventoryItem item;
3538 lock (m_host.TaskInventory) 3816 m_host.TaskInventory.LockItemsForRead(true);
3539 { 3817 item = m_host.TaskInventory[invItemID];
3540 item = m_host.TaskInventory[invItemID]; 3818 m_host.TaskInventory.LockItemsForRead(false);
3541 } 3819
3542
3543 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3820 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3544 && !m_automaticLinkPermission) 3821 && !m_automaticLinkPermission)
3545 { 3822 {
@@ -3560,7 +3837,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3560 3837
3561 if (targetPart != null) 3838 if (targetPart != null)
3562 { 3839 {
3563 if (parent != 0) { 3840 if (parent != 0)
3841 {
3564 parentPrim = m_host.ParentGroup; 3842 parentPrim = m_host.ParentGroup;
3565 childPrim = targetPart.ParentGroup; 3843 childPrim = targetPart.ParentGroup;
3566 } 3844 }
@@ -3592,16 +3870,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3592 m_host.AddScriptLPS(1); 3870 m_host.AddScriptLPS(1);
3593 UUID invItemID = InventorySelf(); 3871 UUID invItemID = InventorySelf();
3594 3872
3595 lock (m_host.TaskInventory) 3873 m_host.TaskInventory.LockItemsForRead(true);
3596 {
3597 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3874 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3598 && !m_automaticLinkPermission) 3875 && !m_automaticLinkPermission)
3599 { 3876 {
3600 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3877 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3878 m_host.TaskInventory.LockItemsForRead(false);
3601 return; 3879 return;
3602 } 3880 }
3603 } 3881 m_host.TaskInventory.LockItemsForRead(false);
3604 3882
3605 if (linknum < ScriptBaseClass.LINK_THIS) 3883 if (linknum < ScriptBaseClass.LINK_THIS)
3606 return; 3884 return;
3607 3885
@@ -3640,10 +3918,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 // Restructuring Multiple Prims. 3918 // Restructuring Multiple Prims.
3641 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3919 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3642 parts.Remove(parentPrim.RootPart); 3920 parts.Remove(parentPrim.RootPart);
3643 foreach (SceneObjectPart part in parts) 3921 if (parts.Count > 0)
3644 { 3922 {
3645 parentPrim.DelinkFromGroup(part.LocalId, true); 3923 try
3924 {
3925 parts[0].ParentGroup.areUpdatesSuspended = true;
3926 foreach (SceneObjectPart part in parts)
3927 {
3928 parentPrim.DelinkFromGroup(part.LocalId, true);
3929 }
3930 }
3931 finally
3932 {
3933 parts[0].ParentGroup.areUpdatesSuspended = false;
3934 }
3646 } 3935 }
3936
3647 parentPrim.HasGroupChanged = true; 3937 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 3938 parentPrim.ScheduleGroupForFullUpdate();
3649 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3939 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3652,11 +3942,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3652 { 3942 {
3653 SceneObjectPart newRoot = parts[0]; 3943 SceneObjectPart newRoot = parts[0];
3654 parts.Remove(newRoot); 3944 parts.Remove(newRoot);
3655 foreach (SceneObjectPart part in parts) 3945
3946 try
3656 { 3947 {
3657 part.UpdateFlag = 0; 3948 parts[0].ParentGroup.areUpdatesSuspended = true;
3658 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3949 foreach (SceneObjectPart part in parts)
3950 {
3951 part.UpdateFlag = 0;
3952 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3953 }
3659 } 3954 }
3955 finally
3956 {
3957 parts[0].ParentGroup.areUpdatesSuspended = false;
3958 }
3959
3960
3660 newRoot.ParentGroup.HasGroupChanged = true; 3961 newRoot.ParentGroup.HasGroupChanged = true;
3661 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3962 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3662 } 3963 }
@@ -3702,6 +4003,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3702 } 4003 }
3703 else 4004 else
3704 { 4005 {
4006 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4007 {
4008 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4009
4010 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4011 if (avatars.Count > linknum)
4012 {
4013 return avatars[linknum].UUID.ToString();
4014 }
4015 }
3705 return UUID.Zero.ToString(); 4016 return UUID.Zero.ToString();
3706 } 4017 }
3707 } 4018 }
@@ -3778,17 +4089,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3778 m_host.AddScriptLPS(1); 4089 m_host.AddScriptLPS(1);
3779 int count = 0; 4090 int count = 0;
3780 4091
3781 lock (m_host.TaskInventory) 4092 m_host.TaskInventory.LockItemsForRead(true);
4093 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3782 { 4094 {
3783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4095 if (inv.Value.Type == type || type == -1)
3784 { 4096 {
3785 if (inv.Value.Type == type || type == -1) 4097 count = count + 1;
3786 {
3787 count = count + 1;
3788 }
3789 } 4098 }
3790 } 4099 }
3791 4100
4101 m_host.TaskInventory.LockItemsForRead(false);
3792 return count; 4102 return count;
3793 } 4103 }
3794 4104
@@ -3797,16 +4107,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3797 m_host.AddScriptLPS(1); 4107 m_host.AddScriptLPS(1);
3798 ArrayList keys = new ArrayList(); 4108 ArrayList keys = new ArrayList();
3799 4109
3800 lock (m_host.TaskInventory) 4110 m_host.TaskInventory.LockItemsForRead(true);
4111 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3801 { 4112 {
3802 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4113 if (inv.Value.Type == type || type == -1)
3803 { 4114 {
3804 if (inv.Value.Type == type || type == -1) 4115 keys.Add(inv.Value.Name);
3805 {
3806 keys.Add(inv.Value.Name);
3807 }
3808 } 4116 }
3809 } 4117 }
4118 m_host.TaskInventory.LockItemsForRead(false);
3810 4119
3811 if (keys.Count == 0) 4120 if (keys.Count == 0)
3812 { 4121 {
@@ -3843,20 +4152,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 } 4152 }
3844 4153
3845 // move the first object found with this inventory name 4154 // move the first object found with this inventory name
3846 lock (m_host.TaskInventory) 4155 m_host.TaskInventory.LockItemsForRead(true);
4156 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3847 { 4157 {
3848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4158 if (inv.Value.Name == inventory)
3849 { 4159 {
3850 if (inv.Value.Name == inventory) 4160 found = true;
3851 { 4161 objId = inv.Key;
3852 found = true; 4162 assetType = inv.Value.Type;
3853 objId = inv.Key; 4163 objName = inv.Value.Name;
3854 assetType = inv.Value.Type; 4164 break;
3855 objName = inv.Value.Name;
3856 break;
3857 }
3858 } 4165 }
3859 } 4166 }
4167 m_host.TaskInventory.LockItemsForRead(false);
3860 4168
3861 if (!found) 4169 if (!found)
3862 { 4170 {
@@ -3864,9 +4172,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3864 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4172 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3865 } 4173 }
3866 4174
3867 // check if destination is an avatar 4175 // check if destination is an object
3868 if (World.GetScenePresence(destId) != null) 4176 if (World.GetSceneObjectPart(destId) != null)
4177 {
4178 // destination is an object
4179 World.MoveTaskInventoryItem(destId, m_host, objId);
4180 }
4181 else
3869 { 4182 {
4183 ScenePresence presence = World.GetScenePresence(destId);
4184
4185 if (presence == null)
4186 {
4187 UserAccount account =
4188 World.UserAccountService.GetUserAccount(
4189 World.RegionInfo.ScopeID,
4190 destId);
4191
4192 if (account == null)
4193 {
4194 llSay(0, "Can't find destination "+destId.ToString());
4195 return;
4196 }
4197 }
4198
3870 // destination is an avatar 4199 // destination is an avatar
3871 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4200 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3872 4201
@@ -3890,31 +4219,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 4219
3891 if (m_TransferModule != null) 4220 if (m_TransferModule != null)
3892 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4221 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4222
4223 //This delay should only occur when giving inventory to avatars.
4224 ScriptSleep(3000);
3893 } 4225 }
3894 else
3895 {
3896 // destination is an object
3897 World.MoveTaskInventoryItem(destId, m_host, objId);
3898 }
3899 ScriptSleep(3000);
3900 } 4226 }
3901 4227
4228 [DebuggerNonUserCode]
3902 public void llRemoveInventory(string name) 4229 public void llRemoveInventory(string name)
3903 { 4230 {
3904 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3905 4232
3906 lock (m_host.TaskInventory) 4233 List<TaskInventoryItem> inv;
4234 try
3907 { 4235 {
3908 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4236 m_host.TaskInventory.LockItemsForRead(true);
4237 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4238 }
4239 finally
4240 {
4241 m_host.TaskInventory.LockItemsForRead(false);
4242 }
4243 foreach (TaskInventoryItem item in inv)
4244 {
4245 if (item.Name == name)
3909 { 4246 {
3910 if (item.Name == name) 4247 if (item.ItemID == m_itemID)
3911 { 4248 throw new ScriptDeleteException();
3912 if (item.ItemID == m_itemID) 4249 else
3913 throw new ScriptDeleteException(); 4250 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3914 else 4251 return;
3915 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3916 return;
3917 }
3918 } 4252 }
3919 } 4253 }
3920 } 4254 }
@@ -3980,6 +4314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3980 ce.time = Util.EnvironmentTickCount(); 4314 ce.time = Util.EnvironmentTickCount();
3981 ce.account = account; 4315 ce.account = account;
3982 ce.pinfo = pinfo; 4316 ce.pinfo = pinfo;
4317 m_userInfoCache[uuid] = ce;
3983 } 4318 }
3984 else 4319 else
3985 { 4320 {
@@ -4055,6 +4390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4055 { 4390 {
4056 m_host.AddScriptLPS(1); 4391 m_host.AddScriptLPS(1);
4057 4392
4393 //Clone is thread safe
4058 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4394 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4059 4395
4060 foreach (TaskInventoryItem item in itemDictionary.Values) 4396 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4108,6 +4444,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4108 ScenePresence presence = World.GetScenePresence(agentId); 4444 ScenePresence presence = World.GetScenePresence(agentId);
4109 if (presence != null) 4445 if (presence != null)
4110 { 4446 {
4447 // agent must not be a god
4448 if (presence.GodLevel >= 200) return;
4449
4111 // agent must be over the owners land 4450 // agent must be over the owners land
4112 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4451 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4113 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4452 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4167,17 +4506,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4167 UUID soundId = UUID.Zero; 4506 UUID soundId = UUID.Zero;
4168 if (!UUID.TryParse(impact_sound, out soundId)) 4507 if (!UUID.TryParse(impact_sound, out soundId))
4169 { 4508 {
4170 lock (m_host.TaskInventory) 4509 m_host.TaskInventory.LockItemsForRead(true);
4510 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4171 { 4511 {
4172 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4512 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4173 { 4513 {
4174 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4514 soundId = item.AssetID;
4175 { 4515 break;
4176 soundId = item.AssetID;
4177 break;
4178 }
4179 } 4516 }
4180 } 4517 }
4518 m_host.TaskInventory.LockItemsForRead(false);
4181 } 4519 }
4182 m_host.CollisionSound = soundId; 4520 m_host.CollisionSound = soundId;
4183 m_host.CollisionSoundVolume = (float)impact_volume; 4521 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4223,6 +4561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4223 UUID partItemID; 4561 UUID partItemID;
4224 foreach (SceneObjectPart part in parts) 4562 foreach (SceneObjectPart part in parts)
4225 { 4563 {
4564 //Clone is thread safe
4226 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4565 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4227 4566
4228 foreach (TaskInventoryItem item in itemsDictionary.Values) 4567 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4437,17 +4776,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4437 4776
4438 m_host.AddScriptLPS(1); 4777 m_host.AddScriptLPS(1);
4439 4778
4440 lock (m_host.TaskInventory) 4779 m_host.TaskInventory.LockItemsForRead(true);
4780 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4441 { 4781 {
4442 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4782 if (item.Type == 10 && item.ItemID == m_itemID)
4443 { 4783 {
4444 if (item.Type == 10 && item.ItemID == m_itemID) 4784 result = item.Name!=null?item.Name:String.Empty;
4445 { 4785 break;
4446 result = item.Name != null ? item.Name : String.Empty;
4447 break;
4448 }
4449 } 4786 }
4450 } 4787 }
4788 m_host.TaskInventory.LockItemsForRead(false);
4451 4789
4452 return result; 4790 return result;
4453 } 4791 }
@@ -4600,23 +4938,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4600 { 4938 {
4601 m_host.AddScriptLPS(1); 4939 m_host.AddScriptLPS(1);
4602 4940
4603 lock (m_host.TaskInventory) 4941 m_host.TaskInventory.LockItemsForRead(true);
4942 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4604 { 4943 {
4605 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4944 if (inv.Value.Name == name)
4606 { 4945 {
4607 if (inv.Value.Name == name) 4946 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4608 { 4947 {
4609 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4948 m_host.TaskInventory.LockItemsForRead(false);
4610 { 4949 return inv.Value.AssetID.ToString();
4611 return inv.Value.AssetID.ToString(); 4950 }
4612 } 4951 else
4613 else 4952 {
4614 { 4953 m_host.TaskInventory.LockItemsForRead(false);
4615 return UUID.Zero.ToString(); 4954 return UUID.Zero.ToString();
4616 }
4617 } 4955 }
4618 } 4956 }
4619 } 4957 }
4958 m_host.TaskInventory.LockItemsForRead(false);
4620 4959
4621 return UUID.Zero.ToString(); 4960 return UUID.Zero.ToString();
4622 } 4961 }
@@ -4769,14 +5108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4769 { 5108 {
4770 m_host.AddScriptLPS(1); 5109 m_host.AddScriptLPS(1);
4771 5110
4772 if (src == null) 5111 return src.Length;
4773 {
4774 return 0;
4775 }
4776 else
4777 {
4778 return src.Length;
4779 }
4780 } 5112 }
4781 5113
4782 public LSL_Integer llList2Integer(LSL_List src, int index) 5114 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4822,7 +5154,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4822 else if (src.Data[index] is LSL_Float) 5154 else if (src.Data[index] is LSL_Float)
4823 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5155 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4824 else if (src.Data[index] is LSL_String) 5156 else if (src.Data[index] is LSL_String)
4825 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5157 {
5158 string str = ((LSL_String) src.Data[index]).m_string;
5159 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5160 if (m != Match.Empty)
5161 {
5162 str = m.Value;
5163 double d = 0.0;
5164 if (!Double.TryParse(str, out d))
5165 return 0.0;
5166
5167 return d;
5168 }
5169 return 0.0;
5170 }
4826 return Convert.ToDouble(src.Data[index]); 5171 return Convert.ToDouble(src.Data[index]);
4827 } 5172 }
4828 catch (FormatException) 5173 catch (FormatException)
@@ -5095,7 +5440,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5095 } 5440 }
5096 } 5441 }
5097 } 5442 }
5098 else { 5443 else
5444 {
5099 object[] array = new object[src.Length]; 5445 object[] array = new object[src.Length];
5100 Array.Copy(src.Data, 0, array, 0, src.Length); 5446 Array.Copy(src.Data, 0, array, 0, src.Length);
5101 result = new LSL_List(array); 5447 result = new LSL_List(array);
@@ -5507,7 +5853,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5507 public void llSetSoundQueueing(int queue) 5853 public void llSetSoundQueueing(int queue)
5508 { 5854 {
5509 m_host.AddScriptLPS(1); 5855 m_host.AddScriptLPS(1);
5510 NotImplemented("llSetSoundQueueing");
5511 } 5856 }
5512 5857
5513 public void llSetSoundRadius(double radius) 5858 public void llSetSoundRadius(double radius)
@@ -5552,10 +5897,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5552 m_host.AddScriptLPS(1); 5897 m_host.AddScriptLPS(1);
5553 5898
5554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5899 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5555 5900 if (parts.Count > 0)
5556 foreach (var part in parts)
5557 { 5901 {
5558 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5902 try
5903 {
5904 parts[0].ParentGroup.areUpdatesSuspended = true;
5905 foreach (var part in parts)
5906 {
5907 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5908 }
5909 }
5910 finally
5911 {
5912 parts[0].ParentGroup.areUpdatesSuspended = false;
5913 }
5559 } 5914 }
5560 } 5915 }
5561 5916
@@ -5609,6 +5964,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5609 ScriptSleep(5000); 5964 ScriptSleep(5000);
5610 } 5965 }
5611 5966
5967 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5968 {
5969 return ParseString2List(str, separators, in_spacers, false);
5970 }
5971
5612 public LSL_Integer llOverMyLand(string id) 5972 public LSL_Integer llOverMyLand(string id)
5613 { 5973 {
5614 m_host.AddScriptLPS(1); 5974 m_host.AddScriptLPS(1);
@@ -5809,7 +6169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5809 return m_host.ParentGroup.RootPart.AttachmentPoint; 6169 return m_host.ParentGroup.RootPart.AttachmentPoint;
5810 } 6170 }
5811 6171
5812 public LSL_Integer llGetFreeMemory() 6172 public virtual LSL_Integer llGetFreeMemory()
5813 { 6173 {
5814 m_host.AddScriptLPS(1); 6174 m_host.AddScriptLPS(1);
5815 // Make scripts designed for LSO happy 6175 // Make scripts designed for LSO happy
@@ -5926,7 +6286,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5926 SetParticleSystem(m_host, rules); 6286 SetParticleSystem(m_host, rules);
5927 } 6287 }
5928 6288
5929 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6289 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6290 {
5930 6291
5931 6292
5932 if (rules.Length == 0) 6293 if (rules.Length == 0)
@@ -6120,14 +6481,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6120 6481
6121 protected UUID GetTaskInventoryItem(string name) 6482 protected UUID GetTaskInventoryItem(string name)
6122 { 6483 {
6123 lock (m_host.TaskInventory) 6484 m_host.TaskInventory.LockItemsForRead(true);
6485 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6124 { 6486 {
6125 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6487 if (inv.Value.Name == name)
6126 { 6488 {
6127 if (inv.Value.Name == name) 6489 m_host.TaskInventory.LockItemsForRead(false);
6128 return inv.Key; 6490 return inv.Key;
6129 } 6491 }
6130 } 6492 }
6493 m_host.TaskInventory.LockItemsForRead(false);
6131 6494
6132 return UUID.Zero; 6495 return UUID.Zero;
6133 } 6496 }
@@ -6455,22 +6818,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6455 } 6818 }
6456 6819
6457 // copy the first script found with this inventory name 6820 // copy the first script found with this inventory name
6458 lock (m_host.TaskInventory) 6821 m_host.TaskInventory.LockItemsForRead(true);
6822 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6459 { 6823 {
6460 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6824 if (inv.Value.Name == name)
6461 { 6825 {
6462 if (inv.Value.Name == name) 6826 // make sure the object is a script
6827 if (10 == inv.Value.Type)
6463 { 6828 {
6464 // make sure the object is a script 6829 found = true;
6465 if (10 == inv.Value.Type) 6830 srcId = inv.Key;
6466 { 6831 break;
6467 found = true;
6468 srcId = inv.Key;
6469 break;
6470 }
6471 } 6832 }
6472 } 6833 }
6473 } 6834 }
6835 m_host.TaskInventory.LockItemsForRead(false);
6474 6836
6475 if (!found) 6837 if (!found)
6476 { 6838 {
@@ -6554,6 +6916,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6554 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6916 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6555 { 6917 {
6556 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6918 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6919 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6920 return shapeBlock;
6557 6921
6558 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6922 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6559 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6923 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6629,6 +6993,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6629 6993
6630 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6994 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6631 { 6995 {
6996 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6997 return;
6998
6632 ObjectShapePacket.ObjectDataBlock shapeBlock; 6999 ObjectShapePacket.ObjectDataBlock shapeBlock;
6633 7000
6634 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7001 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6678,6 +7045,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6678 7045
6679 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7046 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6680 { 7047 {
7048 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7049 return;
7050
6681 ObjectShapePacket.ObjectDataBlock shapeBlock; 7051 ObjectShapePacket.ObjectDataBlock shapeBlock;
6682 7052
6683 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7053 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6720,6 +7090,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6720 7090
6721 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) 7091 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)
6722 { 7092 {
7093 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7094 return;
7095
6723 ObjectShapePacket.ObjectDataBlock shapeBlock; 7096 ObjectShapePacket.ObjectDataBlock shapeBlock;
6724 7097
6725 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7098 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6846,6 +7219,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6846 7219
6847 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7220 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6848 { 7221 {
7222 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7223 return;
7224
6849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7225 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6850 UUID sculptId; 7226 UUID sculptId;
6851 7227
@@ -6861,13 +7237,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 shapeBlock.PathScaleX = 100; 7237 shapeBlock.PathScaleX = 100;
6862 shapeBlock.PathScaleY = 150; 7238 shapeBlock.PathScaleY = 150;
6863 7239
6864 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7240 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6865 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7241 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6866 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7242 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6867 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7243 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6868 { 7244 {
6869 // default 7245 // default
6870 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7246 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6871 } 7247 }
6872 7248
6873 // retain pathcurve 7249 // retain pathcurve
@@ -6886,30 +7262,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6886 ScriptSleep(200); 7262 ScriptSleep(200);
6887 } 7263 }
6888 7264
6889 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7265 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6890 { 7266 {
6891 m_host.AddScriptLPS(1); 7267 m_host.AddScriptLPS(1);
6892 7268
6893 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7269 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7270 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7271 if (parts.Count>0)
7272 {
7273 try
7274 {
7275 parts[0].ParentGroup.areUpdatesSuspended = true;
7276 foreach (SceneObjectPart part in parts)
7277 SetPrimParams(part, rules);
7278 }
7279 finally
7280 {
7281 parts[0].ParentGroup.areUpdatesSuspended = false;
7282 }
7283 }
7284 if (avatars.Count > 0)
7285 {
7286 foreach (ScenePresence avatar in avatars)
7287 SetPrimParams(avatar, rules);
7288 }
7289 }
6894 7290
6895 foreach (SceneObjectPart part in parts) 7291 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6896 SetPrimParams(part, rules); 7292 {
6897 7293 llSetLinkPrimitiveParamsFast(linknumber, rules);
6898 ScriptSleep(200); 7294 ScriptSleep(200);
6899 } 7295 }
6900 7296
6901 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7297 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6902 { 7298 {
6903 m_host.AddScriptLPS(1); 7299 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7300 //We only support PRIM_POSITION and PRIM_ROTATION
6904 7301
6905 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7302 int idx = 0;
6906 7303
6907 foreach (SceneObjectPart part in parts) 7304 while (idx < rules.Length)
6908 SetPrimParams(part, rules); 7305 {
7306 int code = rules.GetLSLIntegerItem(idx++);
7307
7308 int remain = rules.Length - idx;
7309
7310
7311
7312 switch (code)
7313 {
7314 case (int)ScriptBaseClass.PRIM_POSITION:
7315 if (remain < 1)
7316 return;
7317 LSL_Vector v;
7318 v = rules.GetVector3Item(idx++);
7319 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7320 av.SendFullUpdateToAllClients();
7321
7322 break;
7323
7324 case (int)ScriptBaseClass.PRIM_ROTATION:
7325 if (remain < 1)
7326 return;
7327 LSL_Rotation r;
7328 r = rules.GetQuaternionItem(idx++);
7329 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7330 av.SendFullUpdateToAllClients();
7331 break;
7332 }
7333 }
6909 } 7334 }
6910 7335
6911 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7336 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6912 { 7337 {
7338 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7339 return;
7340
6913 int idx = 0; 7341 int idx = 0;
6914 7342
6915 while (idx < rules.Length) 7343 while (idx < rules.Length)
@@ -7444,13 +7872,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7444 public LSL_Integer llGetNumberOfPrims() 7872 public LSL_Integer llGetNumberOfPrims()
7445 { 7873 {
7446 m_host.AddScriptLPS(1); 7874 m_host.AddScriptLPS(1);
7447 int avatarCount = 0; 7875 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7448 World.ForEachScenePresence(delegate(ScenePresence presence) 7876
7449 {
7450 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7451 avatarCount++;
7452 });
7453
7454 return m_host.ParentGroup.PrimCount + avatarCount; 7877 return m_host.ParentGroup.PrimCount + avatarCount;
7455 } 7878 }
7456 7879
@@ -7466,55 +7889,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7466 m_host.AddScriptLPS(1); 7889 m_host.AddScriptLPS(1);
7467 UUID objID = UUID.Zero; 7890 UUID objID = UUID.Zero;
7468 LSL_List result = new LSL_List(); 7891 LSL_List result = new LSL_List();
7892
7893 // If the ID is not valid, return null result
7469 if (!UUID.TryParse(obj, out objID)) 7894 if (!UUID.TryParse(obj, out objID))
7470 { 7895 {
7471 result.Add(new LSL_Vector()); 7896 result.Add(new LSL_Vector());
7472 result.Add(new LSL_Vector()); 7897 result.Add(new LSL_Vector());
7473 return result; 7898 return result;
7474 } 7899 }
7900
7901 // Check if this is an attached prim. If so, replace
7902 // the UUID with the avatar UUID and report it's bounding box
7903 SceneObjectPart part = World.GetSceneObjectPart(objID);
7904 if (part != null && part.ParentGroup.IsAttachment)
7905 objID = part.ParentGroup.RootPart.AttachedAvatar;
7906
7907 // Find out if this is an avatar ID. If so, return it's box
7475 ScenePresence presence = World.GetScenePresence(objID); 7908 ScenePresence presence = World.GetScenePresence(objID);
7476 if (presence != null) 7909 if (presence != null)
7477 { 7910 {
7478 if (presence.ParentID == 0) // not sat on an object 7911 // As per LSL Wiki, there is no difference between sitting
7912 // and standing avatar since server 1.36
7913 LSL_Vector lower;
7914 LSL_Vector upper;
7915 if (presence.Animator.Animations.DefaultAnimation.AnimID
7916 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7479 { 7917 {
7480 LSL_Vector lower; 7918 // This is for ground sitting avatars
7481 LSL_Vector upper; 7919 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7482 if (presence.Animator.Animations.DefaultAnimation.AnimID 7920 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7483 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7921 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7484 {
7485 // This is for ground sitting avatars
7486 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7487 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7488 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7489 }
7490 else
7491 {
7492 // This is for standing/flying avatars
7493 float height = presence.Appearance.AvatarHeight / 2.0f;
7494 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7495 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7496 }
7497 result.Add(lower);
7498 result.Add(upper);
7499 return result;
7500 } 7922 }
7501 else 7923 else
7502 { 7924 {
7503 // sitting on an object so we need the bounding box of that 7925 // This is for standing/flying avatars
7504 // which should include the avatar so set the UUID to the 7926 float height = presence.Appearance.AvatarHeight / 2.0f;
7505 // UUID of the object the avatar is sat on and allow it to fall through 7927 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7506 // to processing an object 7928 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7507 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7508 objID = p.UUID;
7509 } 7929 }
7930
7931 // Adjust to the documented error offsets (see LSL Wiki)
7932 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7933 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7934
7935 if (lower.x > upper.x)
7936 lower.x = upper.x;
7937 if (lower.y > upper.y)
7938 lower.y = upper.y;
7939 if (lower.z > upper.z)
7940 lower.z = upper.z;
7941
7942 result.Add(lower);
7943 result.Add(upper);
7944 return result;
7510 } 7945 }
7511 SceneObjectPart part = World.GetSceneObjectPart(objID); 7946
7947 part = World.GetSceneObjectPart(objID);
7512 // Currently only works for single prims without a sitting avatar 7948 // Currently only works for single prims without a sitting avatar
7513 if (part != null) 7949 if (part != null)
7514 { 7950 {
7515 Vector3 halfSize = part.Scale / 2.0f; 7951 float minX;
7516 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7952 float maxX;
7517 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7953 float minY;
7954 float maxY;
7955 float minZ;
7956 float maxZ;
7957
7958 // This BBox is in sim coordinates, with the offset being
7959 // a contained point.
7960 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7961 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7962
7963 minX -= offsets[0].X;
7964 maxX -= offsets[0].X;
7965 minY -= offsets[0].Y;
7966 maxY -= offsets[0].Y;
7967 minZ -= offsets[0].Z;
7968 maxZ -= offsets[0].Z;
7969
7970 LSL_Vector lower;
7971 LSL_Vector upper;
7972
7973 // Adjust to the documented error offsets (see LSL Wiki)
7974 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7975 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7976
7977 if (lower.x > upper.x)
7978 lower.x = upper.x;
7979 if (lower.y > upper.y)
7980 lower.y = upper.y;
7981 if (lower.z > upper.z)
7982 lower.z = upper.z;
7983
7518 result.Add(lower); 7984 result.Add(lower);
7519 result.Add(upper); 7985 result.Add(upper);
7520 return result; 7986 return result;
@@ -7594,13 +8060,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7594 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8060 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7595 part.AbsolutePosition.Y, 8061 part.AbsolutePosition.Y,
7596 part.AbsolutePosition.Z); 8062 part.AbsolutePosition.Z);
7597 // For some reason, the part.AbsolutePosition.* values do not change if the
7598 // linkset is rotated; they always reflect the child prim's world position
7599 // as though the linkset is unrotated. This is incompatible behavior with SL's
7600 // implementation, so will break scripts imported from there (not to mention it
7601 // makes it more difficult to determine a child prim's actual inworld position).
7602 if (part.ParentID != 0)
7603 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7604 res.Add(v); 8063 res.Add(v);
7605 break; 8064 break;
7606 8065
@@ -7759,24 +8218,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 break; 8218 break;
7760 8219
7761 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8220 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7762 // TODO--------------
7763 if (remain < 1) 8221 if (remain < 1)
7764 return res; 8222 return res;
8223 face = (int)rules.GetLSLIntegerItem(idx++);
7765 8224
7766 face=(int)rules.GetLSLIntegerItem(idx++); 8225 tex = part.Shape.Textures;
7767 8226 int shiny;
7768 res.Add(new LSL_Integer(0)); 8227 if (face == ScriptBaseClass.ALL_SIDES)
7769 res.Add(new LSL_Integer(0)); 8228 {
8229 for (face = 0; face < GetNumberOfSides(part); face++)
8230 {
8231 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8232 if (shinyness == Shininess.High)
8233 {
8234 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8235 }
8236 else if (shinyness == Shininess.Medium)
8237 {
8238 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8239 }
8240 else if (shinyness == Shininess.Low)
8241 {
8242 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8243 }
8244 else
8245 {
8246 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8247 }
8248 res.Add(new LSL_Integer(shiny));
8249 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8250 }
8251 }
8252 else
8253 {
8254 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8255 if (shinyness == Shininess.High)
8256 {
8257 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8258 }
8259 else if (shinyness == Shininess.Medium)
8260 {
8261 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8262 }
8263 else if (shinyness == Shininess.Low)
8264 {
8265 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8266 }
8267 else
8268 {
8269 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8270 }
8271 res.Add(new LSL_Integer(shiny));
8272 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8273 }
7770 break; 8274 break;
7771 8275
7772 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8276 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7773 // TODO--------------
7774 if (remain < 1) 8277 if (remain < 1)
7775 return res; 8278 return res;
8279 face = (int)rules.GetLSLIntegerItem(idx++);
7776 8280
7777 face=(int)rules.GetLSLIntegerItem(idx++); 8281 tex = part.Shape.Textures;
7778 8282 int fullbright;
7779 res.Add(new LSL_Integer(0)); 8283 if (face == ScriptBaseClass.ALL_SIDES)
8284 {
8285 for (face = 0; face < GetNumberOfSides(part); face++)
8286 {
8287 if (tex.GetFace((uint)face).Fullbright == true)
8288 {
8289 fullbright = ScriptBaseClass.TRUE;
8290 }
8291 else
8292 {
8293 fullbright = ScriptBaseClass.FALSE;
8294 }
8295 res.Add(new LSL_Integer(fullbright));
8296 }
8297 }
8298 else
8299 {
8300 if (tex.GetFace((uint)face).Fullbright == true)
8301 {
8302 fullbright = ScriptBaseClass.TRUE;
8303 }
8304 else
8305 {
8306 fullbright = ScriptBaseClass.FALSE;
8307 }
8308 res.Add(new LSL_Integer(fullbright));
8309 }
7780 break; 8310 break;
7781 8311
7782 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8312 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7797,14 +8327,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7797 break; 8327 break;
7798 8328
7799 case (int)ScriptBaseClass.PRIM_TEXGEN: 8329 case (int)ScriptBaseClass.PRIM_TEXGEN:
7800 // TODO--------------
7801 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8330 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7802 if (remain < 1) 8331 if (remain < 1)
7803 return res; 8332 return res;
8333 face = (int)rules.GetLSLIntegerItem(idx++);
7804 8334
7805 face=(int)rules.GetLSLIntegerItem(idx++); 8335 tex = part.Shape.Textures;
7806 8336 if (face == ScriptBaseClass.ALL_SIDES)
7807 res.Add(new LSL_Integer(0)); 8337 {
8338 for (face = 0; face < GetNumberOfSides(part); face++)
8339 {
8340 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8341 {
8342 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8343 }
8344 else
8345 {
8346 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8347 }
8348 }
8349 }
8350 else
8351 {
8352 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8353 {
8354 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8355 }
8356 else
8357 {
8358 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8359 }
8360 }
7808 break; 8361 break;
7809 8362
7810 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8363 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7823,13 +8376,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7823 break; 8376 break;
7824 8377
7825 case (int)ScriptBaseClass.PRIM_GLOW: 8378 case (int)ScriptBaseClass.PRIM_GLOW:
7826 // TODO--------------
7827 if (remain < 1) 8379 if (remain < 1)
7828 return res; 8380 return res;
8381 face = (int)rules.GetLSLIntegerItem(idx++);
7829 8382
7830 face=(int)rules.GetLSLIntegerItem(idx++); 8383 tex = part.Shape.Textures;
7831 8384 float primglow;
7832 res.Add(new LSL_Float(0)); 8385 if (face == ScriptBaseClass.ALL_SIDES)
8386 {
8387 for (face = 0; face < GetNumberOfSides(part); face++)
8388 {
8389 primglow = tex.GetFace((uint)face).Glow;
8390 res.Add(new LSL_Float(primglow));
8391 }
8392 }
8393 else
8394 {
8395 primglow = tex.GetFace((uint)face).Glow;
8396 res.Add(new LSL_Float(primglow));
8397 }
7833 break; 8398 break;
7834 case (int)ScriptBaseClass.PRIM_TEXT: 8399 case (int)ScriptBaseClass.PRIM_TEXT:
7835 Color4 textColor = part.GetTextColor(); 8400 Color4 textColor = part.GetTextColor();
@@ -8379,8 +8944,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8379 // The function returns an ordered list 8944 // The function returns an ordered list
8380 // representing the tokens found in the supplied 8945 // representing the tokens found in the supplied
8381 // sources string. If two successive tokenizers 8946 // sources string. If two successive tokenizers
8382 // are encountered, then a NULL entry is added 8947 // are encountered, then a null-string entry is
8383 // to the list. 8948 // added to the list.
8384 // 8949 //
8385 // It is a precondition that the source and 8950 // It is a precondition that the source and
8386 // toekizer lisst are non-null. If they are null, 8951 // toekizer lisst are non-null. If they are null,
@@ -8388,7 +8953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8388 // while their lengths are being determined. 8953 // while their lengths are being determined.
8389 // 8954 //
8390 // A small amount of working memoryis required 8955 // A small amount of working memoryis required
8391 // of approximately 8*#tokenizers. 8956 // of approximately 8*#tokenizers + 8*srcstrlen.
8392 // 8957 //
8393 // There are many ways in which this function 8958 // There are many ways in which this function
8394 // can be implemented, this implementation is 8959 // can be implemented, this implementation is
@@ -8404,155 +8969,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8404 // and eliminates redundant tokenizers as soon 8969 // and eliminates redundant tokenizers as soon
8405 // as is possible. 8970 // as is possible.
8406 // 8971 //
8407 // The implementation tries to avoid any copying 8972 // The implementation tries to minimize temporary
8408 // of arrays or other objects. 8973 // garbage generation.
8409 // </remarks> 8974 // </remarks>
8410 8975
8411 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 8976 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8412 { 8977 {
8413 int beginning = 0; 8978 return ParseString2List(src, separators, spacers, true);
8414 int srclen = src.Length; 8979 }
8415 int seplen = separators.Length;
8416 object[] separray = separators.Data;
8417 int spclen = spacers.Length;
8418 object[] spcarray = spacers.Data;
8419 int mlen = seplen+spclen;
8420
8421 int[] offset = new int[mlen+1];
8422 bool[] active = new bool[mlen];
8423
8424 int best;
8425 int j;
8426
8427 // Initial capacity reduces resize cost
8428 8980
8429 LSL_List tokens = new LSL_List(); 8981 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8982 {
8983 int srclen = src.Length;
8984 int seplen = separators.Length;
8985 object[] separray = separators.Data;
8986 int spclen = spacers.Length;
8987 object[] spcarray = spacers.Data;
8988 int dellen = 0;
8989 string[] delarray = new string[seplen+spclen];
8430 8990
8431 // All entries are initially valid 8991 int outlen = 0;
8992 string[] outarray = new string[srclen*2+1];
8432 8993
8433 for (int i = 0; i < mlen; i++) 8994 int i, j;
8434 active[i] = true; 8995 string d;
8435 8996
8436 offset[mlen] = srclen; 8997 m_host.AddScriptLPS(1);
8437 8998
8438 while (beginning < srclen) 8999 /*
9000 * Convert separator and spacer lists to C# strings.
9001 * Also filter out null strings so we don't hang.
9002 */
9003 for (i = 0; i < seplen; i ++)
8439 { 9004 {
9005 d = separray[i].ToString();
9006 if (d.Length > 0)
9007 {
9008 delarray[dellen++] = d;
9009 }
9010 }
9011 seplen = dellen;
8440 9012
8441 best = mlen; // as bad as it gets 9013 for (i = 0; i < spclen; i ++)
9014 {
9015 d = spcarray[i].ToString();
9016 if (d.Length > 0)
9017 {
9018 delarray[dellen++] = d;
9019 }
9020 }
8442 9021
8443 // Scan for separators 9022 /*
9023 * Scan through source string from beginning to end.
9024 */
9025 for (i = 0;;)
9026 {
8444 9027
8445 for (j = 0; j < seplen; j++) 9028 /*
9029 * Find earliest delimeter in src starting at i (if any).
9030 */
9031 int earliestDel = -1;
9032 int earliestSrc = srclen;
9033 string earliestStr = null;
9034 for (j = 0; j < dellen; j ++)
8446 { 9035 {
8447 if (separray[j].ToString() == String.Empty) 9036 d = delarray[j];
8448 active[j] = false; 9037 if (d != null)
8449
8450 if (active[j])
8451 { 9038 {
8452 // scan all of the markers 9039 int index = src.IndexOf(d, i);
8453 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9040 if (index < 0)
8454 { 9041 {
8455 // not present at all 9042 delarray[j] = null; // delim nowhere in src, don't check it anymore
8456 active[j] = false;
8457 } 9043 }
8458 else 9044 else if (index < earliestSrc)
8459 { 9045 {
8460 // present and correct 9046 earliestSrc = index; // where delimeter starts in source string
8461 if (offset[j] < offset[best]) 9047 earliestDel = j; // where delimeter is in delarray[]
8462 { 9048 earliestStr = d; // the delimeter string from delarray[]
8463 // closest so far 9049 if (index == i) break; // can't do any better than found at beg of string
8464 best = j;
8465 if (offset[best] == beginning)
8466 break;
8467 }
8468 } 9050 }
8469 } 9051 }
8470 } 9052 }
8471 9053
8472 // Scan for spacers 9054 /*
8473 9055 * Output source string starting at i through start of earliest delimeter.
8474 if (offset[best] != beginning) 9056 */
9057 if (keepNulls || (earliestSrc > i))
8475 { 9058 {
8476 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9059 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8477 {
8478 if (spcarray[j-seplen].ToString() == String.Empty)
8479 active[j] = false;
8480
8481 if (active[j])
8482 {
8483 // scan all of the markers
8484 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8485 {
8486 // not present at all
8487 active[j] = false;
8488 }
8489 else
8490 {
8491 // present and correct
8492 if (offset[j] < offset[best])
8493 {
8494 // closest so far
8495 best = j;
8496 }
8497 }
8498 }
8499 }
8500 } 9060 }
8501 9061
8502 // This is the normal exit from the scanning loop 9062 /*
9063 * If no delimeter found at or after i, we're done scanning.
9064 */
9065 if (earliestDel < 0) break;
8503 9066
8504 if (best == mlen) 9067 /*
9068 * If delimeter was a spacer, output the spacer.
9069 */
9070 if (earliestDel >= seplen)
8505 { 9071 {
8506 // no markers were found on this pass 9072 outarray[outlen++] = earliestStr;
8507 // so we're pretty much done
8508 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8509 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8510 break;
8511 } 9073 }
8512 9074
8513 // Otherwise we just add the newly delimited token 9075 /*
8514 // and recalculate where the search should continue. 9076 * Look at rest of src string following delimeter.
8515 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9077 */
8516 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9078 i = earliestSrc + earliestStr.Length;
8517
8518 if (best < seplen)
8519 {
8520 beginning = offset[best] + (separray[best].ToString()).Length;
8521 }
8522 else
8523 {
8524 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8525 string str = spcarray[best - seplen].ToString();
8526 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8527 tokens.Add(new LSL_String(str));
8528 }
8529 } 9079 }
8530 9080
8531 // This an awkward an not very intuitive boundary case. If the 9081 /*
8532 // last substring is a tokenizer, then there is an implied trailing 9082 * Make up an exact-sized output array suitable for an LSL_List object.
8533 // null list entry. Hopefully the single comparison will not be too 9083 */
8534 // arduous. Alternatively the 'break' could be replced with a return 9084 object[] outlist = new object[outlen];
8535 // but that's shabby programming. 9085 for (i = 0; i < outlen; i ++)
8536
8537 if ((beginning == srclen) && (keepNulls))
8538 { 9086 {
8539 if (srclen != 0) 9087 outlist[i] = new LSL_String(outarray[i]);
8540 tokens.Add(new LSL_String(""));
8541 } 9088 }
8542 9089 return new LSL_List(outlist);
8543 return tokens;
8544 }
8545
8546 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8547 {
8548 m_host.AddScriptLPS(1);
8549 return this.ParseString(src, separators, spacers, false);
8550 }
8551
8552 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8553 {
8554 m_host.AddScriptLPS(1);
8555 return this.ParseString(src, separators, spacers, true);
8556 } 9090 }
8557 9091
8558 public LSL_Integer llGetObjectPermMask(int mask) 9092 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8629,28 +9163,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8629 { 9163 {
8630 m_host.AddScriptLPS(1); 9164 m_host.AddScriptLPS(1);
8631 9165
8632 lock (m_host.TaskInventory) 9166 m_host.TaskInventory.LockItemsForRead(true);
9167 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8633 { 9168 {
8634 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9169 if (inv.Value.Name == item)
8635 { 9170 {
8636 if (inv.Value.Name == item) 9171 m_host.TaskInventory.LockItemsForRead(false);
9172 switch (mask)
8637 { 9173 {
8638 switch (mask) 9174 case 0:
8639 { 9175 return (int)inv.Value.BasePermissions;
8640 case 0: 9176 case 1:
8641 return (int)inv.Value.BasePermissions; 9177 return (int)inv.Value.CurrentPermissions;
8642 case 1: 9178 case 2:
8643 return (int)inv.Value.CurrentPermissions; 9179 return (int)inv.Value.GroupPermissions;
8644 case 2: 9180 case 3:
8645 return (int)inv.Value.GroupPermissions; 9181 return (int)inv.Value.EveryonePermissions;
8646 case 3: 9182 case 4:
8647 return (int)inv.Value.EveryonePermissions; 9183 return (int)inv.Value.NextPermissions;
8648 case 4:
8649 return (int)inv.Value.NextPermissions;
8650 }
8651 } 9184 }
8652 } 9185 }
8653 } 9186 }
9187 m_host.TaskInventory.LockItemsForRead(false);
8654 9188
8655 return -1; 9189 return -1;
8656 } 9190 }
@@ -8697,16 +9231,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8697 { 9231 {
8698 m_host.AddScriptLPS(1); 9232 m_host.AddScriptLPS(1);
8699 9233
8700 lock (m_host.TaskInventory) 9234 m_host.TaskInventory.LockItemsForRead(true);
9235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8701 { 9236 {
8702 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9237 if (inv.Value.Name == item)
8703 { 9238 {
8704 if (inv.Value.Name == item) 9239 m_host.TaskInventory.LockItemsForRead(false);
8705 { 9240 return inv.Value.CreatorID.ToString();
8706 return inv.Value.CreatorID.ToString();
8707 }
8708 } 9241 }
8709 } 9242 }
9243 m_host.TaskInventory.LockItemsForRead(false);
8710 9244
8711 llSay(0, "No item name '" + item + "'"); 9245 llSay(0, "No item name '" + item + "'");
8712 9246
@@ -8757,8 +9291,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8757 return UUID.Zero.ToString(); 9291 return UUID.Zero.ToString();
8758 } 9292 }
8759 reply = new LSL_Vector( 9293 reply = new LSL_Vector(
8760 info.RegionLocX * Constants.RegionSize, 9294 info.RegionLocX,
8761 info.RegionLocY * Constants.RegionSize, 9295 info.RegionLocY,
8762 0).ToString(); 9296 0).ToString();
8763 break; 9297 break;
8764 case 6: // DATA_SIM_STATUS 9298 case 6: // DATA_SIM_STATUS
@@ -8971,17 +9505,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8971 int width = 0; 9505 int width = 0;
8972 int height = 0; 9506 int height = 0;
8973 9507
8974 ParcelMediaCommandEnum? commandToSend = null; 9508 uint commandToSend = 0;
8975 float time = 0.0f; // default is from start 9509 float time = 0.0f; // default is from start
8976 9510
8977 ScenePresence presence = null; 9511 ScenePresence presence = null;
8978 9512
8979 for (int i = 0; i < commandList.Data.Length; i++) 9513 for (int i = 0; i < commandList.Data.Length; i++)
8980 { 9514 {
8981 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9515 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8982 switch (command) 9516 switch (command)
8983 { 9517 {
8984 case ParcelMediaCommandEnum.Agent: 9518 case (uint)ParcelMediaCommandEnum.Agent:
8985 // we send only to one agent 9519 // we send only to one agent
8986 if ((i + 1) < commandList.Length) 9520 if ((i + 1) < commandList.Length)
8987 { 9521 {
@@ -8998,25 +9532,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8998 } 9532 }
8999 break; 9533 break;
9000 9534
9001 case ParcelMediaCommandEnum.Loop: 9535 case (uint)ParcelMediaCommandEnum.Loop:
9002 loop = 1; 9536 loop = 1;
9003 commandToSend = command; 9537 commandToSend = command;
9004 update = true; //need to send the media update packet to set looping 9538 update = true; //need to send the media update packet to set looping
9005 break; 9539 break;
9006 9540
9007 case ParcelMediaCommandEnum.Play: 9541 case (uint)ParcelMediaCommandEnum.Play:
9008 loop = 0; 9542 loop = 0;
9009 commandToSend = command; 9543 commandToSend = command;
9010 update = true; //need to send the media update packet to make sure it doesn't loop 9544 update = true; //need to send the media update packet to make sure it doesn't loop
9011 break; 9545 break;
9012 9546
9013 case ParcelMediaCommandEnum.Pause: 9547 case (uint)ParcelMediaCommandEnum.Pause:
9014 case ParcelMediaCommandEnum.Stop: 9548 case (uint)ParcelMediaCommandEnum.Stop:
9015 case ParcelMediaCommandEnum.Unload: 9549 case (uint)ParcelMediaCommandEnum.Unload:
9016 commandToSend = command; 9550 commandToSend = command;
9017 break; 9551 break;
9018 9552
9019 case ParcelMediaCommandEnum.Url: 9553 case (uint)ParcelMediaCommandEnum.Url:
9020 if ((i + 1) < commandList.Length) 9554 if ((i + 1) < commandList.Length)
9021 { 9555 {
9022 if (commandList.Data[i + 1] is LSL_String) 9556 if (commandList.Data[i + 1] is LSL_String)
@@ -9029,7 +9563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9029 } 9563 }
9030 break; 9564 break;
9031 9565
9032 case ParcelMediaCommandEnum.Texture: 9566 case (uint)ParcelMediaCommandEnum.Texture:
9033 if ((i + 1) < commandList.Length) 9567 if ((i + 1) < commandList.Length)
9034 { 9568 {
9035 if (commandList.Data[i + 1] is LSL_String) 9569 if (commandList.Data[i + 1] is LSL_String)
@@ -9042,7 +9576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9042 } 9576 }
9043 break; 9577 break;
9044 9578
9045 case ParcelMediaCommandEnum.Time: 9579 case (uint)ParcelMediaCommandEnum.Time:
9046 if ((i + 1) < commandList.Length) 9580 if ((i + 1) < commandList.Length)
9047 { 9581 {
9048 if (commandList.Data[i + 1] is LSL_Float) 9582 if (commandList.Data[i + 1] is LSL_Float)
@@ -9054,7 +9588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9054 } 9588 }
9055 break; 9589 break;
9056 9590
9057 case ParcelMediaCommandEnum.AutoAlign: 9591 case (uint)ParcelMediaCommandEnum.AutoAlign:
9058 if ((i + 1) < commandList.Length) 9592 if ((i + 1) < commandList.Length)
9059 { 9593 {
9060 if (commandList.Data[i + 1] is LSL_Integer) 9594 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9068,7 +9602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9068 } 9602 }
9069 break; 9603 break;
9070 9604
9071 case ParcelMediaCommandEnum.Type: 9605 case (uint)ParcelMediaCommandEnum.Type:
9072 if ((i + 1) < commandList.Length) 9606 if ((i + 1) < commandList.Length)
9073 { 9607 {
9074 if (commandList.Data[i + 1] is LSL_String) 9608 if (commandList.Data[i + 1] is LSL_String)
@@ -9081,7 +9615,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9081 } 9615 }
9082 break; 9616 break;
9083 9617
9084 case ParcelMediaCommandEnum.Desc: 9618 case (uint)ParcelMediaCommandEnum.Desc:
9085 if ((i + 1) < commandList.Length) 9619 if ((i + 1) < commandList.Length)
9086 { 9620 {
9087 if (commandList.Data[i + 1] is LSL_String) 9621 if (commandList.Data[i + 1] is LSL_String)
@@ -9094,7 +9628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9094 } 9628 }
9095 break; 9629 break;
9096 9630
9097 case ParcelMediaCommandEnum.Size: 9631 case (uint)ParcelMediaCommandEnum.Size:
9098 if ((i + 2) < commandList.Length) 9632 if ((i + 2) < commandList.Length)
9099 { 9633 {
9100 if (commandList.Data[i + 1] is LSL_Integer) 9634 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9164,7 +9698,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9164 } 9698 }
9165 } 9699 }
9166 9700
9167 if (commandToSend != null) 9701 if (commandToSend != 0)
9168 { 9702 {
9169 // the commandList contained a start/stop/... command, too 9703 // the commandList contained a start/stop/... command, too
9170 if (presence == null) 9704 if (presence == null)
@@ -9201,7 +9735,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9201 9735
9202 if (aList.Data[i] != null) 9736 if (aList.Data[i] != null)
9203 { 9737 {
9204 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9738 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9205 { 9739 {
9206 case ParcelMediaCommandEnum.Url: 9740 case ParcelMediaCommandEnum.Url:
9207 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9741 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9244,16 +9778,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9244 { 9778 {
9245 m_host.AddScriptLPS(1); 9779 m_host.AddScriptLPS(1);
9246 9780
9247 lock (m_host.TaskInventory) 9781 m_host.TaskInventory.LockItemsForRead(true);
9782 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9248 { 9783 {
9249 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9784 if (inv.Value.Name == name)
9250 { 9785 {
9251 if (inv.Value.Name == name) 9786 m_host.TaskInventory.LockItemsForRead(false);
9252 { 9787 return inv.Value.Type;
9253 return inv.Value.Type;
9254 }
9255 } 9788 }
9256 } 9789 }
9790 m_host.TaskInventory.LockItemsForRead(false);
9257 9791
9258 return -1; 9792 return -1;
9259 } 9793 }
@@ -9264,15 +9798,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9264 9798
9265 if (quick_pay_buttons.Data.Length < 4) 9799 if (quick_pay_buttons.Data.Length < 4)
9266 { 9800 {
9267 LSLError("List must have at least 4 elements"); 9801 int x;
9268 return; 9802 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9803 {
9804 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9805 }
9269 } 9806 }
9270 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9807 int[] nPrice = new int[5];
9271 9808 nPrice[0]=price;
9272 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9809 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9273 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9810 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9274 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9811 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9275 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9812 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9813 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9276 m_host.ParentGroup.HasGroupChanged = true; 9814 m_host.ParentGroup.HasGroupChanged = true;
9277 } 9815 }
9278 9816
@@ -9284,17 +9822,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9284 if (invItemID == UUID.Zero) 9822 if (invItemID == UUID.Zero)
9285 return new LSL_Vector(); 9823 return new LSL_Vector();
9286 9824
9287 lock (m_host.TaskInventory) 9825 m_host.TaskInventory.LockItemsForRead(true);
9826 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9288 { 9827 {
9289 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9828 m_host.TaskInventory.LockItemsForRead(false);
9290 return new LSL_Vector(); 9829 return new LSL_Vector();
9830 }
9291 9831
9292 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9832 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9293 { 9833 {
9294 ShoutError("No permissions to track the camera"); 9834 ShoutError("No permissions to track the camera");
9295 return new LSL_Vector(); 9835 m_host.TaskInventory.LockItemsForRead(false);
9296 } 9836 return new LSL_Vector();
9297 } 9837 }
9838 m_host.TaskInventory.LockItemsForRead(false);
9298 9839
9299 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9840 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9300 if (presence != null) 9841 if (presence != null)
@@ -9312,17 +9853,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9312 if (invItemID == UUID.Zero) 9853 if (invItemID == UUID.Zero)
9313 return new LSL_Rotation(); 9854 return new LSL_Rotation();
9314 9855
9315 lock (m_host.TaskInventory) 9856 m_host.TaskInventory.LockItemsForRead(true);
9857 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9316 { 9858 {
9317 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9859 m_host.TaskInventory.LockItemsForRead(false);
9318 return new LSL_Rotation(); 9860 return new LSL_Rotation();
9319
9320 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9321 {
9322 ShoutError("No permissions to track the camera");
9323 return new LSL_Rotation();
9324 }
9325 } 9861 }
9862 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9863 {
9864 ShoutError("No permissions to track the camera");
9865 m_host.TaskInventory.LockItemsForRead(false);
9866 return new LSL_Rotation();
9867 }
9868 m_host.TaskInventory.LockItemsForRead(false);
9326 9869
9327 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9870 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9328 if (presence != null) 9871 if (presence != null)
@@ -9384,8 +9927,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9384 { 9927 {
9385 m_host.AddScriptLPS(1); 9928 m_host.AddScriptLPS(1);
9386 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9929 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9387 if (detectedParams == null) return; // only works on the first detected avatar 9930 if (detectedParams == null)
9388 9931 {
9932 if (m_host.IsAttachment == true)
9933 {
9934 detectedParams = new DetectParams();
9935 detectedParams.Key = m_host.OwnerID;
9936 }
9937 else
9938 {
9939 return;
9940 }
9941 }
9942
9389 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9943 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9390 if (avatar != null) 9944 if (avatar != null)
9391 { 9945 {
@@ -9393,6 +9947,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9393 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9947 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9394 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9948 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9395 } 9949 }
9950
9396 ScriptSleep(1000); 9951 ScriptSleep(1000);
9397 } 9952 }
9398 9953
@@ -9472,14 +10027,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9472 if (objectID == UUID.Zero) return; 10027 if (objectID == UUID.Zero) return;
9473 10028
9474 UUID agentID; 10029 UUID agentID;
9475 lock (m_host.TaskInventory) 10030 m_host.TaskInventory.LockItemsForRead(true);
9476 { 10031 // we need the permission first, to know which avatar we want to set the camera for
9477 // we need the permission first, to know which avatar we want to set the camera for 10032 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9478 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9479 10033
9480 if (agentID == UUID.Zero) return; 10034 if (agentID == UUID.Zero)
9481 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10035 {
10036 m_host.TaskInventory.LockItemsForRead(false);
10037 return;
9482 } 10038 }
10039 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10040 {
10041 m_host.TaskInventory.LockItemsForRead(false);
10042 return;
10043 }
10044 m_host.TaskInventory.LockItemsForRead(false);
9483 10045
9484 ScenePresence presence = World.GetScenePresence(agentID); 10046 ScenePresence presence = World.GetScenePresence(agentID);
9485 10047
@@ -9488,12 +10050,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9488 10050
9489 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10051 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9490 object[] data = rules.Data; 10052 object[] data = rules.Data;
9491 for (int i = 0; i < data.Length; ++i) { 10053 for (int i = 0; i < data.Length; ++i)
10054 {
9492 int type = Convert.ToInt32(data[i++].ToString()); 10055 int type = Convert.ToInt32(data[i++].ToString());
9493 if (i >= data.Length) break; // odd number of entries => ignore the last 10056 if (i >= data.Length) break; // odd number of entries => ignore the last
9494 10057
9495 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10058 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9496 switch (type) { 10059 switch (type)
10060 {
9497 case ScriptBaseClass.CAMERA_FOCUS: 10061 case ScriptBaseClass.CAMERA_FOCUS:
9498 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10062 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9499 case ScriptBaseClass.CAMERA_POSITION: 10063 case ScriptBaseClass.CAMERA_POSITION:
@@ -9529,12 +10093,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9529 10093
9530 // we need the permission first, to know which avatar we want to clear the camera for 10094 // we need the permission first, to know which avatar we want to clear the camera for
9531 UUID agentID; 10095 UUID agentID;
9532 lock (m_host.TaskInventory) 10096 m_host.TaskInventory.LockItemsForRead(true);
10097 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10098 if (agentID == UUID.Zero)
9533 { 10099 {
9534 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10100 m_host.TaskInventory.LockItemsForRead(false);
9535 if (agentID == UUID.Zero) return; 10101 return;
9536 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10102 }
10103 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10104 {
10105 m_host.TaskInventory.LockItemsForRead(false);
10106 return;
9537 } 10107 }
10108 m_host.TaskInventory.LockItemsForRead(false);
9538 10109
9539 ScenePresence presence = World.GetScenePresence(agentID); 10110 ScenePresence presence = World.GetScenePresence(agentID);
9540 10111
@@ -9601,19 +10172,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9601 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10172 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9602 { 10173 {
9603 m_host.AddScriptLPS(1); 10174 m_host.AddScriptLPS(1);
9604 string ret = String.Empty; 10175
9605 string src1 = llBase64ToString(str1); 10176 if (str1 == String.Empty)
9606 string src2 = llBase64ToString(str2); 10177 return String.Empty;
9607 int c = 0; 10178 if (str2 == String.Empty)
9608 for (int i = 0; i < src1.Length; i++) 10179 return str1;
10180
10181 byte[] data1;
10182 byte[] data2;
10183 try
10184 {
10185 data1 = Convert.FromBase64String(str1);
10186 data2 = Convert.FromBase64String(str2);
10187 }
10188 catch (Exception)
9609 { 10189 {
9610 ret += (char) (src1[i] ^ src2[c]); 10190 return new LSL_String(String.Empty);
10191 }
9611 10192
9612 c++; 10193 byte[] d2 = new Byte[data1.Length];
9613 if (c >= src2.Length) 10194 int pos = 0;
9614 c = 0; 10195
10196 if (data1.Length <= data2.Length)
10197 {
10198 Array.Copy(data2, 0, d2, 0, data1.Length);
9615 } 10199 }
9616 return llStringToBase64(ret); 10200 else
10201 {
10202 while (pos < data1.Length)
10203 {
10204 int len = data1.Length - pos;
10205 if (len > data2.Length)
10206 len = data2.Length;
10207
10208 Array.Copy(data2, 0, d2, pos, len);
10209 pos += len;
10210 }
10211 }
10212
10213 for (pos = 0 ; pos < data1.Length ; pos++ )
10214 data1[pos] ^= d2[pos];
10215
10216 return Convert.ToBase64String(data1);
9617 } 10217 }
9618 10218
9619 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10219 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9672,12 +10272,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9672 Regex r = new Regex(authregex); 10272 Regex r = new Regex(authregex);
9673 int[] gnums = r.GetGroupNumbers(); 10273 int[] gnums = r.GetGroupNumbers();
9674 Match m = r.Match(url); 10274 Match m = r.Match(url);
9675 if (m.Success) { 10275 if (m.Success)
9676 for (int i = 1; i < gnums.Length; i++) { 10276 {
10277 for (int i = 1; i < gnums.Length; i++)
10278 {
9677 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10279 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9678 //CaptureCollection cc = g.Captures; 10280 //CaptureCollection cc = g.Captures;
9679 } 10281 }
9680 if (m.Groups.Count == 5) { 10282 if (m.Groups.Count == 5)
10283 {
9681 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10284 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9682 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10285 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9683 } 10286 }
@@ -9994,15 +10597,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9994 10597
9995 internal UUID ScriptByName(string name) 10598 internal UUID ScriptByName(string name)
9996 { 10599 {
9997 lock (m_host.TaskInventory) 10600 m_host.TaskInventory.LockItemsForRead(true);
10601
10602 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9998 { 10603 {
9999 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10604 if (item.Type == 10 && item.Name == name)
10000 { 10605 {
10001 if (item.Type == 10 && item.Name == name) 10606 m_host.TaskInventory.LockItemsForRead(false);
10002 return item.ItemID; 10607 return item.ItemID;
10003 } 10608 }
10004 } 10609 }
10005 10610
10611 m_host.TaskInventory.LockItemsForRead(false);
10612
10006 return UUID.Zero; 10613 return UUID.Zero;
10007 } 10614 }
10008 10615
@@ -10043,6 +10650,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10043 { 10650 {
10044 m_host.AddScriptLPS(1); 10651 m_host.AddScriptLPS(1);
10045 10652
10653 //Clone is thread safe
10046 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10654 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10047 10655
10048 UUID assetID = UUID.Zero; 10656 UUID assetID = UUID.Zero;
@@ -10105,6 +10713,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10105 { 10713 {
10106 m_host.AddScriptLPS(1); 10714 m_host.AddScriptLPS(1);
10107 10715
10716 //Clone is thread safe
10108 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10717 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10109 10718
10110 UUID assetID = UUID.Zero; 10719 UUID assetID = UUID.Zero;
@@ -10184,6 +10793,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10184 10793
10185 return GetLinkPrimitiveParams(obj, rules); 10794 return GetLinkPrimitiveParams(obj, rules);
10186 } 10795 }
10796
10797 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10798 {
10799 List<SceneObjectPart> parts = GetLinkParts(link);
10800 if (parts.Count < 1)
10801 return 0;
10802
10803 return GetNumberOfSides(parts[0]);
10804 }
10187 } 10805 }
10188 10806
10189 public class NotecardCache 10807 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 e6a323e..7ce3716 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()
@@ -799,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
799 if (target != null) 808 if (target != null)
800 { 809 {
801 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
802 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
803 { 813 {
804 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
805 { 815 {
806 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
807 { 817 animID = inv.Value.AssetID;
808 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
809 animID = inv.Value.AssetID;
810 continue;
811 }
812 } 819 }
813 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
814 if (animID == UUID.Zero) 822 if (animID == UUID.Zero)
815 target.Animator.AddAnimation(animation, m_host.UUID); 823 target.Animator.AddAnimation(animation, m_host.UUID);
816 else 824 else
@@ -832,18 +840,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
832 if (target != null) 840 if (target != null)
833 { 841 {
834 UUID animID=UUID.Zero; 842 UUID animID=UUID.Zero;
835 lock (m_host.TaskInventory) 843 m_host.TaskInventory.LockItemsForRead(true);
844 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
836 { 845 {
837 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 846 if (inv.Value.Name == animation)
838 { 847 {
839 if (inv.Value.Name == animation) 848 if (inv.Value.Type == (int)AssetType.Animation)
840 { 849 animID = inv.Value.AssetID;
841 if (inv.Value.Type == (int)AssetType.Animation) 850 continue;
842 animID = inv.Value.AssetID;
843 continue;
844 }
845 } 851 }
846 } 852 }
853 m_host.TaskInventory.LockItemsForRead(false);
847 854
848 if (animID == UUID.Zero) 855 if (animID == UUID.Zero)
849 target.Animator.RemoveAnimation(animation); 856 target.Animator.RemoveAnimation(animation);
@@ -1694,6 +1701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1694 1701
1695 if (!UUID.TryParse(name, out assetID)) 1702 if (!UUID.TryParse(name, out assetID))
1696 { 1703 {
1704 m_host.TaskInventory.LockItemsForRead(true);
1697 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1705 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1698 { 1706 {
1699 if (item.Type == 7 && item.Name == name) 1707 if (item.Type == 7 && item.Name == name)
@@ -1701,6 +1709,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1701 assetID = item.AssetID; 1709 assetID = item.AssetID;
1702 } 1710 }
1703 } 1711 }
1712 m_host.TaskInventory.LockItemsForRead(false);
1704 } 1713 }
1705 1714
1706 if (assetID == UUID.Zero) 1715 if (assetID == UUID.Zero)
@@ -1747,6 +1756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1747 1756
1748 if (!UUID.TryParse(name, out assetID)) 1757 if (!UUID.TryParse(name, out assetID))
1749 { 1758 {
1759 m_host.TaskInventory.LockItemsForRead(true);
1750 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1760 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1751 { 1761 {
1752 if (item.Type == 7 && item.Name == name) 1762 if (item.Type == 7 && item.Name == name)
@@ -1754,6 +1764,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1754 assetID = item.AssetID; 1764 assetID = item.AssetID;
1755 } 1765 }
1756 } 1766 }
1767 m_host.TaskInventory.LockItemsForRead(false);
1757 } 1768 }
1758 1769
1759 if (assetID == UUID.Zero) 1770 if (assetID == UUID.Zero)
@@ -1804,6 +1815,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 1815
1805 if (!UUID.TryParse(name, out assetID)) 1816 if (!UUID.TryParse(name, out assetID))
1806 { 1817 {
1818 m_host.TaskInventory.LockItemsForRead(true);
1807 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1819 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1808 { 1820 {
1809 if (item.Type == 7 && item.Name == name) 1821 if (item.Type == 7 && item.Name == name)
@@ -1811,6 +1823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1811 assetID = item.AssetID; 1823 assetID = item.AssetID;
1812 } 1824 }
1813 } 1825 }
1826 m_host.TaskInventory.LockItemsForRead(false);
1814 } 1827 }
1815 1828
1816 if (assetID == UUID.Zero) 1829 if (assetID == UUID.Zero)
@@ -2290,9 +2303,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2290 { 2303 {
2291 if (avatar.IsChildAgent == false) 2304 if (avatar.IsChildAgent == false)
2292 { 2305 {
2293 result.Add(avatar.UUID); 2306 result.Add(new LSL_Key(avatar.UUID.ToString()));
2294 result.Add(avatar.AbsolutePosition); 2307 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2295 result.Add(avatar.Name); 2308 result.Add(new LSL_String(avatar.Name));
2296 } 2309 }
2297 } 2310 }
2298 }); 2311 });
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 c9a24f6..028bb42 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 b3c4d95..93d544b 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 {