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.cs1871
-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/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs341
14 files changed, 1550 insertions, 872 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 0692fdb..e299f96 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)
@@ -291,40 +349,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
291 protected UUID InventorySelf() 349 protected UUID InventorySelf()
292 { 350 {
293 UUID invItemID = new UUID(); 351 UUID invItemID = new UUID();
294 352 bool unlock = false;
295 lock (m_host.TaskInventory) 353 if (!m_host.TaskInventory.IsReadLockedByMe())
296 { 354 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 m_host.TaskInventory.LockItemsForRead(true);
356 unlock = true;
357 }
358 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
359 {
360 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
298 { 361 {
299 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 362 invItemID = inv.Key;
300 { 363 break;
301 invItemID = inv.Key;
302 break;
303 }
304 } 364 }
305 } 365 }
306 366 if (unlock)
367 {
368 m_host.TaskInventory.LockItemsForRead(false);
369 }
307 return invItemID; 370 return invItemID;
308 } 371 }
309 372
310 protected UUID InventoryKey(string name, int type) 373 protected UUID InventoryKey(string name, int type)
311 { 374 {
312 m_host.AddScriptLPS(1); 375 m_host.AddScriptLPS(1);
313 376 m_host.TaskInventory.LockItemsForRead(true);
314 lock (m_host.TaskInventory) 377
378 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 379 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 380 if (inv.Value.Name == name)
317 { 381 {
318 if (inv.Value.Name == name) 382 m_host.TaskInventory.LockItemsForRead(false);
383
384 if (inv.Value.Type != type)
319 { 385 {
320 if (inv.Value.Type != type) 386 return UUID.Zero;
321 return UUID.Zero;
322
323 return inv.Value.AssetID;
324 } 387 }
388
389 return inv.Value.AssetID;
325 } 390 }
326 } 391 }
327 392
393 m_host.TaskInventory.LockItemsForRead(false);
328 return UUID.Zero; 394 return UUID.Zero;
329 } 395 }
330 396
@@ -332,17 +398,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
332 { 398 {
333 m_host.AddScriptLPS(1); 399 m_host.AddScriptLPS(1);
334 400
335 lock (m_host.TaskInventory) 401
402 m_host.TaskInventory.LockItemsForRead(true);
403
404 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
336 { 405 {
337 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 406 if (inv.Value.Name == name)
338 { 407 {
339 if (inv.Value.Name == name) 408 m_host.TaskInventory.LockItemsForRead(false);
340 { 409 return inv.Value.AssetID;
341 return inv.Value.AssetID;
342 }
343 } 410 }
344 } 411 }
345 412
413 m_host.TaskInventory.LockItemsForRead(false);
414
415
346 return UUID.Zero; 416 return UUID.Zero;
347 } 417 }
348 418
@@ -484,26 +554,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
484 554
485 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 555 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
486 556
487 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 557 // Utility function for llRot2Euler
488 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 558
559 // normalize an angle between -PI and PI (-180 to +180 degrees)
560 protected double NormalizeAngle(double angle)
561 {
562 if (angle > -Math.PI && angle < Math.PI)
563 return angle;
564
565 int numPis = (int)(Math.PI / angle);
566 double remainder = angle - Math.PI * numPis;
567 if (numPis % 2 == 1)
568 return Math.PI - angle;
569 return remainder;
570 }
489 571
490 public LSL_Vector llRot2Euler(LSL_Rotation r) 572 public LSL_Vector llRot2Euler(LSL_Rotation q1)
491 { 573 {
492 m_host.AddScriptLPS(1); 574 m_host.AddScriptLPS(1);
493 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 575 LSL_Vector eul = new LSL_Vector();
494 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 576
495 double m = (t.x + t.y + t.z + t.s); 577 double sqw = q1.s*q1.s;
496 if (m == 0) return new LSL_Vector(); 578 double sqx = q1.x*q1.x;
497 double n = 2 * (r.y * r.s + r.x * r.z); 579 double sqy = q1.z*q1.z;
498 double p = m * m - n * n; 580 double sqz = q1.y*q1.y;
499 if (p > 0) 581 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
500 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 582 double test = q1.x*q1.z + q1.y*q1.s;
501 Math.Atan2(n, Math.Sqrt(p)), 583 if (test > 0.4999*unit) { // singularity at north pole
502 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 584 eul.z = 2 * Math.Atan2(q1.x,q1.s);
503 else if (n > 0) 585 eul.y = Math.PI/2;
504 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)); 586 eul.x = 0;
505 else 587 return eul;
506 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)); 588 }
589 if (test < -0.4999*unit) { // singularity at south pole
590 eul.z = -2 * Math.Atan2(q1.x,q1.s);
591 eul.y = -Math.PI/2;
592 eul.x = 0;
593 return eul;
594 }
595 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
596 eul.y = Math.Asin(2*test/unit);
597 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
598 return eul;
507 } 599 }
508 600
509 /* From wiki: 601 /* From wiki:
@@ -705,77 +797,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 797 {
706 //A and B should both be normalized 798 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 799 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 800 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 801 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 802
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 803 double dotProduct = LSL_Vector.Dot(a, b);
804 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
805 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
806 double angle = Math.Acos(dotProduct / magProduct);
807 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
808 double s = Math.Sin(angle / 2);
809
810 double x = axis.x * s;
811 double y = axis.y * s;
812 double z = axis.z * s;
813 double w = Math.Cos(angle / 2);
814
815 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
817
818 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
819 */
820
821 // This method mimics the 180 errors found in SL
822 // See www.euclideanspace.com... angleBetween
823 LSL_Vector vec_a = a;
824 LSL_Vector vec_b = b;
825
826 // Eliminate zero length
827 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
828 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
829 if (vec_a_mag < 0.00001 ||
830 vec_b_mag < 0.00001)
712 { 831 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 832 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 833 }
715 else 834
835 // Normalize
836 vec_a = llVecNorm(vec_a);
837 vec_b = llVecNorm(vec_b);
838
839 // Calculate axis and rotation angle
840 LSL_Vector axis = vec_a % vec_b;
841 LSL_Float cos_theta = vec_a * vec_b;
842
843 // Check if parallel
844 if (cos_theta > 0.99999)
716 { 845 {
717 a = LSL_Vector.Norm(a); 846 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 847 }
719 double dotProduct = LSL_Vector.Dot(a, b); 848
720 // There are two degenerate cases possible. These are for vectors 180 or 849 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 850 else if (cos_theta < -0.99999)
722 // 851 {
723 // Check for vectors 180 degrees apart. 852 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 853 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 854 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 855 }
727 // First assume X axis is orthogonal to the vectors. 856 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 857 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 858 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 859 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 860 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 861 s = Math.Cos(theta);
733 { 862 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 863 x = axis.x * t;
735 } 864 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 865 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 866 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 867 }
776 return rotBetween;
777 } 868 }
778 869
779 public void llWhisper(int channelID, string text) 870 public void llWhisper(int channelID, string text)
780 { 871 {
781 m_host.AddScriptLPS(1); 872 m_host.AddScriptLPS(1);
@@ -1099,10 +1190,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1099 return detectedParams.TouchUV; 1190 return detectedParams.TouchUV;
1100 } 1191 }
1101 1192
1193 [DebuggerNonUserCode]
1102 public virtual void llDie() 1194 public virtual void llDie()
1103 { 1195 {
1104 m_host.AddScriptLPS(1); 1196 m_host.AddScriptLPS(1);
1105 throw new SelfDeleteException(); 1197 if (!m_host.IsAttachment) throw new SelfDeleteException();
1106 } 1198 }
1107 1199
1108 public LSL_Float llGround(LSL_Vector offset) 1200 public LSL_Float llGround(LSL_Vector offset)
@@ -1175,6 +1267,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1175 1267
1176 public void llSetStatus(int status, int value) 1268 public void llSetStatus(int status, int value)
1177 { 1269 {
1270 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1271 return;
1178 m_host.AddScriptLPS(1); 1272 m_host.AddScriptLPS(1);
1179 1273
1180 int statusrotationaxis = 0; 1274 int statusrotationaxis = 0;
@@ -1408,6 +1502,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1408 { 1502 {
1409 m_host.AddScriptLPS(1); 1503 m_host.AddScriptLPS(1);
1410 1504
1505 SetColor(m_host, color, face);
1506 }
1507
1508 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1509 {
1510 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1511 return;
1512
1513 Primitive.TextureEntry tex = part.Shape.Textures;
1514 Color4 texcolor;
1515 if (face >= 0 && face < GetNumberOfSides(part))
1516 {
1517 texcolor = tex.CreateFace((uint)face).RGBA;
1518 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1519 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1520 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1521 tex.FaceTextures[face].RGBA = texcolor;
1522 part.UpdateTexture(tex);
1523 return;
1524 }
1525 else if (face == ScriptBaseClass.ALL_SIDES)
1526 {
1527 for (uint i = 0; i < GetNumberOfSides(part); i++)
1528 {
1529 if (tex.FaceTextures[i] != null)
1530 {
1531 texcolor = tex.FaceTextures[i].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.FaceTextures[i].RGBA = texcolor;
1536 }
1537 texcolor = tex.DefaultTexture.RGBA;
1538 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1539 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1540 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1541 tex.DefaultTexture.RGBA = texcolor;
1542 }
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546
1411 if (face == ScriptBaseClass.ALL_SIDES) 1547 if (face == ScriptBaseClass.ALL_SIDES)
1412 face = SceneObjectPart.ALL_SIDES; 1548 face = SceneObjectPart.ALL_SIDES;
1413 1549
@@ -1416,6 +1552,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 1552
1417 public void SetTexGen(SceneObjectPart part, int face,int style) 1553 public void SetTexGen(SceneObjectPart part, int face,int style)
1418 { 1554 {
1555 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1556 return;
1557
1419 Primitive.TextureEntry tex = part.Shape.Textures; 1558 Primitive.TextureEntry tex = part.Shape.Textures;
1420 MappingType textype; 1559 MappingType textype;
1421 textype = MappingType.Default; 1560 textype = MappingType.Default;
@@ -1446,6 +1585,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1446 1585
1447 public void SetGlow(SceneObjectPart part, int face, float glow) 1586 public void SetGlow(SceneObjectPart part, int face, float glow)
1448 { 1587 {
1588 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1589 return;
1590
1449 Primitive.TextureEntry tex = part.Shape.Textures; 1591 Primitive.TextureEntry tex = part.Shape.Textures;
1450 if (face >= 0 && face < GetNumberOfSides(part)) 1592 if (face >= 0 && face < GetNumberOfSides(part))
1451 { 1593 {
@@ -1471,6 +1613,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 1613
1472 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1614 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1473 { 1615 {
1616 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1617 return;
1474 1618
1475 Shininess sval = new Shininess(); 1619 Shininess sval = new Shininess();
1476 1620
@@ -1521,6 +1665,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 1665
1522 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1666 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1523 { 1667 {
1668 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1669 return;
1670
1524 Primitive.TextureEntry tex = part.Shape.Textures; 1671 Primitive.TextureEntry tex = part.Shape.Textures;
1525 if (face >= 0 && face < GetNumberOfSides(part)) 1672 if (face >= 0 && face < GetNumberOfSides(part))
1526 { 1673 {
@@ -1581,13 +1728,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1581 m_host.AddScriptLPS(1); 1728 m_host.AddScriptLPS(1);
1582 1729
1583 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1730 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1584 1731 if (parts.Count > 0)
1585 foreach (SceneObjectPart part in parts) 1732 {
1586 SetAlpha(part, alpha, face); 1733 try
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = true;
1736 foreach (SceneObjectPart part in parts)
1737 SetAlpha(part, alpha, face);
1738 }
1739 finally
1740 {
1741 parts[0].ParentGroup.areUpdatesSuspended = false;
1742 }
1743 }
1587 } 1744 }
1588 1745
1589 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1746 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1590 { 1747 {
1748 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1749 return;
1750
1591 Primitive.TextureEntry tex = part.Shape.Textures; 1751 Primitive.TextureEntry tex = part.Shape.Textures;
1592 Color4 texcolor; 1752 Color4 texcolor;
1593 if (face >= 0 && face < GetNumberOfSides(part)) 1753 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1633,7 +1793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1633 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1793 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1634 float wind, float tension, LSL_Vector Force) 1794 float wind, float tension, LSL_Vector Force)
1635 { 1795 {
1636 if (part == null) 1796 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1637 return; 1797 return;
1638 1798
1639 if (flexi) 1799 if (flexi)
@@ -1668,7 +1828,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1668 /// <param name="falloff"></param> 1828 /// <param name="falloff"></param>
1669 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1829 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1670 { 1830 {
1671 if (part == null) 1831 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1672 return; 1832 return;
1673 1833
1674 if (light) 1834 if (light)
@@ -1745,15 +1905,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1745 m_host.AddScriptLPS(1); 1905 m_host.AddScriptLPS(1);
1746 1906
1747 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1907 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1748 1908 if (parts.Count > 0)
1749 foreach (SceneObjectPart part in parts) 1909 {
1750 SetTexture(part, texture, face); 1910 try
1751 1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = true;
1913 foreach (SceneObjectPart part in parts)
1914 SetTexture(part, texture, face);
1915 }
1916 finally
1917 {
1918 parts[0].ParentGroup.areUpdatesSuspended = false;
1919 }
1920 }
1752 ScriptSleep(200); 1921 ScriptSleep(200);
1753 } 1922 }
1754 1923
1755 protected void SetTexture(SceneObjectPart part, string texture, int face) 1924 protected void SetTexture(SceneObjectPart part, string texture, int face)
1756 { 1925 {
1926 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1927 return;
1928
1757 UUID textureID=new UUID(); 1929 UUID textureID=new UUID();
1758 1930
1759 if (!UUID.TryParse(texture, out textureID)) 1931 if (!UUID.TryParse(texture, out textureID))
@@ -1799,6 +1971,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 1971
1800 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1972 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1801 { 1973 {
1974 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1975 return;
1976
1802 Primitive.TextureEntry tex = part.Shape.Textures; 1977 Primitive.TextureEntry tex = part.Shape.Textures;
1803 if (face >= 0 && face < GetNumberOfSides(part)) 1978 if (face >= 0 && face < GetNumberOfSides(part))
1804 { 1979 {
@@ -1835,6 +2010,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1835 2010
1836 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2011 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1837 { 2012 {
2013 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2014 return;
2015
1838 Primitive.TextureEntry tex = part.Shape.Textures; 2016 Primitive.TextureEntry tex = part.Shape.Textures;
1839 if (face >= 0 && face < GetNumberOfSides(part)) 2017 if (face >= 0 && face < GetNumberOfSides(part))
1840 { 2018 {
@@ -1871,6 +2049,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1871 2049
1872 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2050 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1873 { 2051 {
2052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2053 return;
2054
1874 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1875 if (face >= 0 && face < GetNumberOfSides(part)) 2056 if (face >= 0 && face < GetNumberOfSides(part))
1876 { 2057 {
@@ -1941,6 +2122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1941 2122
1942 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2123 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1943 { 2124 {
2125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2126 return;
2127
1944 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2128 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1945 LSL_Vector currentPos = GetPartLocalPos(part); 2129 LSL_Vector currentPos = GetPartLocalPos(part);
1946 2130
@@ -1957,7 +2141,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1957 } 2141 }
1958 else 2142 else
1959 { 2143 {
1960 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2144 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1961 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2145 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1962 SceneObjectGroup parent = part.ParentGroup; 2146 SceneObjectGroup parent = part.ParentGroup;
1963 parent.HasGroupChanged = true; 2147 parent.HasGroupChanged = true;
@@ -2040,6 +2224,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2040 2224
2041 protected void SetRot(SceneObjectPart part, Quaternion rot) 2225 protected void SetRot(SceneObjectPart part, Quaternion rot)
2042 { 2226 {
2227 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2228 return;
2229
2043 part.UpdateRotation(rot); 2230 part.UpdateRotation(rot);
2044 // Update rotation does not move the object in the physics scene if it's a linkset. 2231 // Update rotation does not move the object in the physics scene if it's a linkset.
2045 2232
@@ -2659,12 +2846,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2659 2846
2660 m_host.AddScriptLPS(1); 2847 m_host.AddScriptLPS(1);
2661 2848
2849 m_host.TaskInventory.LockItemsForRead(true);
2662 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2850 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2663 2851 m_host.TaskInventory.LockItemsForRead(false);
2664 lock (m_host.TaskInventory)
2665 {
2666 item = m_host.TaskInventory[invItemID];
2667 }
2668 2852
2669 if (item.PermsGranter == UUID.Zero) 2853 if (item.PermsGranter == UUID.Zero)
2670 return 0; 2854 return 0;
@@ -2739,6 +2923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2739 if (dist > m_ScriptDistanceFactor * 10.0f) 2923 if (dist > m_ScriptDistanceFactor * 10.0f)
2740 return; 2924 return;
2741 2925
2926 //Clone is thread-safe
2742 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2927 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2743 2928
2744 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2801,6 +2986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2801 2986
2802 public void llLookAt(LSL_Vector target, double strength, double damping) 2987 public void llLookAt(LSL_Vector target, double strength, double damping)
2803 { 2988 {
2989 /*
2804 m_host.AddScriptLPS(1); 2990 m_host.AddScriptLPS(1);
2805 // Determine where we are looking from 2991 // Determine where we are looking from
2806 LSL_Vector from = llGetPos(); 2992 LSL_Vector from = llGetPos();
@@ -2820,10 +3006,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2820 // the angles of rotation in radians into rotation value 3006 // the angles of rotation in radians into rotation value
2821 3007
2822 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3008 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2823 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3009
2824 m_host.startLookAt(rotation, (float)damping, (float)strength); 3010 // This would only work if your physics system contains an APID controller:
3011 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3012 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3013
2825 // Orient the object to the angle calculated 3014 // Orient the object to the angle calculated
2826 //llSetRot(rot); 3015 llSetRot(rot);
3016 */
3017
3018 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3019 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3020 // http://bugs.meta7.com/view.php?id=28
3021 // - Tom
3022
3023 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3024 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3025
3026 }
3027
3028 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3029 {
3030 m_host.AddScriptLPS(1);
3031// NotImplemented("llRotLookAt");
3032 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3033
2827 } 3034 }
2828 3035
2829 public void llStopLookAt() 3036 public void llStopLookAt()
@@ -2872,13 +3079,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2872 { 3079 {
2873 TaskInventoryItem item; 3080 TaskInventoryItem item;
2874 3081
2875 lock (m_host.TaskInventory) 3082 m_host.TaskInventory.LockItemsForRead(true);
3083 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2876 { 3084 {
2877 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3085 m_host.TaskInventory.LockItemsForRead(false);
2878 return; 3086 return;
2879 else 3087 }
2880 item = m_host.TaskInventory[InventorySelf()]; 3088 else
3089 {
3090 item = m_host.TaskInventory[InventorySelf()];
2881 } 3091 }
3092 m_host.TaskInventory.LockItemsForRead(false);
2882 3093
2883 if (item.PermsGranter != UUID.Zero) 3094 if (item.PermsGranter != UUID.Zero)
2884 { 3095 {
@@ -2900,13 +3111,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2900 { 3111 {
2901 TaskInventoryItem item; 3112 TaskInventoryItem item;
2902 3113
3114 m_host.TaskInventory.LockItemsForRead(true);
2903 lock (m_host.TaskInventory) 3115 lock (m_host.TaskInventory)
2904 { 3116 {
3117
2905 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3118 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3119 {
3120 m_host.TaskInventory.LockItemsForRead(false);
2906 return; 3121 return;
3122 }
2907 else 3123 else
3124 {
2908 item = m_host.TaskInventory[InventorySelf()]; 3125 item = m_host.TaskInventory[InventorySelf()];
3126 }
2909 } 3127 }
3128 m_host.TaskInventory.LockItemsForRead(false);
2910 3129
2911 m_host.AddScriptLPS(1); 3130 m_host.AddScriptLPS(1);
2912 3131
@@ -2938,19 +3157,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 { 3157 {
2939 m_host.AddScriptLPS(1); 3158 m_host.AddScriptLPS(1);
2940 3159
2941 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2942 return;
2943
2944 TaskInventoryItem item; 3160 TaskInventoryItem item;
2945 3161
2946 lock (m_host.TaskInventory) 3162 m_host.TaskInventory.LockItemsForRead(true);
3163
3164 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2947 { 3165 {
2948 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3166 m_host.TaskInventory.LockItemsForRead(false);
2949 return; 3167 return;
2950 else 3168 }
2951 item = m_host.TaskInventory[InventorySelf()]; 3169 else
3170 {
3171 item = m_host.TaskInventory[InventorySelf()];
2952 } 3172 }
2953 3173
3174 m_host.TaskInventory.LockItemsForRead(false);
3175
2954 if (item.PermsGranter != m_host.OwnerID) 3176 if (item.PermsGranter != m_host.OwnerID)
2955 return; 3177 return;
2956 3178
@@ -2960,10 +3182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2960 3182
2961 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3183 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2962 3184
2963 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3185 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2964 if (attachmentsModule != null)
2965 attachmentsModule.AttachObject(presence.ControllingClient,
2966 grp, (uint)attachment, false);
2967 } 3186 }
2968 } 3187 }
2969 3188
@@ -2976,13 +3195,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 3195
2977 TaskInventoryItem item; 3196 TaskInventoryItem item;
2978 3197
2979 lock (m_host.TaskInventory) 3198 m_host.TaskInventory.LockItemsForRead(true);
3199
3200 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2980 { 3201 {
2981 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3202 m_host.TaskInventory.LockItemsForRead(false);
2982 return; 3203 return;
2983 else 3204 }
2984 item = m_host.TaskInventory[InventorySelf()]; 3205 else
3206 {
3207 item = m_host.TaskInventory[InventorySelf()];
2985 } 3208 }
3209 m_host.TaskInventory.LockItemsForRead(false);
3210
2986 3211
2987 if (item.PermsGranter != m_host.OwnerID) 3212 if (item.PermsGranter != m_host.OwnerID)
2988 return; 3213 return;
@@ -3021,6 +3246,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3021 3246
3022 public void llInstantMessage(string user, string message) 3247 public void llInstantMessage(string user, string message)
3023 { 3248 {
3249 UUID result;
3250 if (!UUID.TryParse(user, out result))
3251 {
3252 ShoutError("An invalid key was passed to llInstantMessage");
3253 ScriptSleep(2000);
3254 return;
3255 }
3256
3257
3024 m_host.AddScriptLPS(1); 3258 m_host.AddScriptLPS(1);
3025 3259
3026 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3260 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3035,14 +3269,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3035 UUID friendTransactionID = UUID.Random(); 3269 UUID friendTransactionID = UUID.Random();
3036 3270
3037 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3271 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3038 3272
3039 GridInstantMessage msg = new GridInstantMessage(); 3273 GridInstantMessage msg = new GridInstantMessage();
3040 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3274 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3041 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3275 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3042 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3276 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3043// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3277// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3044// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3278// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3045 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3279 DateTime dt = DateTime.UtcNow;
3280
3281 // Ticks from UtcNow, but make it look like local. Evil, huh?
3282 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3283
3284 try
3285 {
3286 // Convert that to the PST timezone
3287 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3288 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3289 }
3290 catch
3291 {
3292 // No logging here, as it could be VERY spammy
3293 }
3294
3295 // And make it look local again to fool the unix time util
3296 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3297
3298 msg.timestamp = (uint)Util.ToUnixTime(dt);
3299
3046 //if (client != null) 3300 //if (client != null)
3047 //{ 3301 //{
3048 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3302 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3056,13 +3310,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 msg.message = message.Substring(0, 1024); 3310 msg.message = message.Substring(0, 1024);
3057 else 3311 else
3058 msg.message = message; 3312 msg.message = message;
3059 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3313 msg.dialog = (byte)19; // MessageFromObject
3060 msg.fromGroup = false;// fromGroup; 3314 msg.fromGroup = false;// fromGroup;
3061 msg.offline = (byte)0; //offline; 3315 msg.offline = (byte)0; //offline;
3062 msg.ParentEstateID = 0; //ParentEstateID; 3316 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3063 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3317 msg.Position = new Vector3(m_host.AbsolutePosition);
3064 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3318 msg.RegionID = World.RegionInfo.RegionID.Guid;
3065 msg.binaryBucket = new byte[0];// binaryBucket; 3319 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3066 3320
3067 if (m_TransferModule != null) 3321 if (m_TransferModule != null)
3068 { 3322 {
@@ -3082,7 +3336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 } 3336 }
3083 3337
3084 emailModule.SendEmail(m_host.UUID, address, subject, message); 3338 emailModule.SendEmail(m_host.UUID, address, subject, message);
3085 ScriptSleep(20000); 3339 ScriptSleep(15000);
3086 } 3340 }
3087 3341
3088 public void llGetNextEmail(string address, string subject) 3342 public void llGetNextEmail(string address, string subject)
@@ -3184,13 +3438,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3184 m_host.AddScriptLPS(1); 3438 m_host.AddScriptLPS(1);
3185 } 3439 }
3186 3440
3187 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3188 {
3189 m_host.AddScriptLPS(1);
3190 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3191 m_host.RotLookAt(rot, (float)strength, (float)damping);
3192 }
3193
3194 public LSL_Integer llStringLength(string str) 3441 public LSL_Integer llStringLength(string str)
3195 { 3442 {
3196 m_host.AddScriptLPS(1); 3443 m_host.AddScriptLPS(1);
@@ -3214,14 +3461,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3214 3461
3215 TaskInventoryItem item; 3462 TaskInventoryItem item;
3216 3463
3217 lock (m_host.TaskInventory) 3464 m_host.TaskInventory.LockItemsForRead(true);
3465 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3218 { 3466 {
3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3467 m_host.TaskInventory.LockItemsForRead(false);
3220 return; 3468 return;
3221 else
3222 item = m_host.TaskInventory[InventorySelf()];
3223 } 3469 }
3224 3470 else
3471 {
3472 item = m_host.TaskInventory[InventorySelf()];
3473 }
3474 m_host.TaskInventory.LockItemsForRead(false);
3225 if (item.PermsGranter == UUID.Zero) 3475 if (item.PermsGranter == UUID.Zero)
3226 return; 3476 return;
3227 3477
@@ -3251,13 +3501,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3251 3501
3252 TaskInventoryItem item; 3502 TaskInventoryItem item;
3253 3503
3254 lock (m_host.TaskInventory) 3504 m_host.TaskInventory.LockItemsForRead(true);
3505 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3255 { 3506 {
3256 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3507 m_host.TaskInventory.LockItemsForRead(false);
3257 return; 3508 return;
3258 else 3509 }
3259 item = m_host.TaskInventory[InventorySelf()]; 3510 else
3511 {
3512 item = m_host.TaskInventory[InventorySelf()];
3260 } 3513 }
3514 m_host.TaskInventory.LockItemsForRead(false);
3515
3261 3516
3262 if (item.PermsGranter == UUID.Zero) 3517 if (item.PermsGranter == UUID.Zero)
3263 return; 3518 return;
@@ -3328,10 +3583,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3328 3583
3329 TaskInventoryItem item; 3584 TaskInventoryItem item;
3330 3585
3331 lock (m_host.TaskInventory) 3586
3587 m_host.TaskInventory.LockItemsForRead(true);
3588 if (!m_host.TaskInventory.ContainsKey(invItemID))
3589 {
3590 m_host.TaskInventory.LockItemsForRead(false);
3591 return;
3592 }
3593 else
3332 { 3594 {
3333 item = m_host.TaskInventory[invItemID]; 3595 item = m_host.TaskInventory[invItemID];
3334 } 3596 }
3597 m_host.TaskInventory.LockItemsForRead(false);
3335 3598
3336 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3599 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3337 { 3600 {
@@ -3363,11 +3626,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3363 3626
3364 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3627 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3365 { 3628 {
3366 lock (m_host.TaskInventory) 3629 m_host.TaskInventory.LockItemsForWrite(true);
3367 { 3630 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3368 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3631 m_host.TaskInventory[invItemID].PermsMask = perm;
3369 m_host.TaskInventory[invItemID].PermsMask = perm; 3632 m_host.TaskInventory.LockItemsForWrite(false);
3370 }
3371 3633
3372 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3634 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3373 "run_time_permissions", new Object[] { 3635 "run_time_permissions", new Object[] {
@@ -3387,11 +3649,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3387 3649
3388 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3650 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3389 { 3651 {
3390 lock (m_host.TaskInventory) 3652 m_host.TaskInventory.LockItemsForWrite(true);
3391 { 3653 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3392 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3654 m_host.TaskInventory[invItemID].PermsMask = perm;
3393 m_host.TaskInventory[invItemID].PermsMask = perm; 3655 m_host.TaskInventory.LockItemsForWrite(false);
3394 }
3395 3656
3396 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3657 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3397 "run_time_permissions", new Object[] { 3658 "run_time_permissions", new Object[] {
@@ -3412,11 +3673,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3412 3673
3413 if (!m_waitingForScriptAnswer) 3674 if (!m_waitingForScriptAnswer)
3414 { 3675 {
3415 lock (m_host.TaskInventory) 3676 m_host.TaskInventory.LockItemsForWrite(true);
3416 { 3677 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3417 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3678 m_host.TaskInventory[invItemID].PermsMask = 0;
3418 m_host.TaskInventory[invItemID].PermsMask = 0; 3679 m_host.TaskInventory.LockItemsForWrite(false);
3419 }
3420 3680
3421 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3681 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3422 m_waitingForScriptAnswer=true; 3682 m_waitingForScriptAnswer=true;
@@ -3451,10 +3711,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3451 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3711 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3452 llReleaseControls(); 3712 llReleaseControls();
3453 3713
3454 lock (m_host.TaskInventory) 3714
3455 { 3715 m_host.TaskInventory.LockItemsForWrite(true);
3456 m_host.TaskInventory[invItemID].PermsMask = answer; 3716 m_host.TaskInventory[invItemID].PermsMask = answer;
3457 } 3717 m_host.TaskInventory.LockItemsForWrite(false);
3718
3458 3719
3459 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3720 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3460 "run_time_permissions", new Object[] { 3721 "run_time_permissions", new Object[] {
@@ -3466,16 +3727,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3466 { 3727 {
3467 m_host.AddScriptLPS(1); 3728 m_host.AddScriptLPS(1);
3468 3729
3469 lock (m_host.TaskInventory) 3730 m_host.TaskInventory.LockItemsForRead(true);
3731
3732 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3470 { 3733 {
3471 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3734 if (item.Type == 10 && item.ItemID == m_itemID)
3472 { 3735 {
3473 if (item.Type == 10 && item.ItemID == m_itemID) 3736 m_host.TaskInventory.LockItemsForRead(false);
3474 { 3737 return item.PermsGranter.ToString();
3475 return item.PermsGranter.ToString();
3476 }
3477 } 3738 }
3478 } 3739 }
3740 m_host.TaskInventory.LockItemsForRead(false);
3479 3741
3480 return UUID.Zero.ToString(); 3742 return UUID.Zero.ToString();
3481 } 3743 }
@@ -3484,19 +3746,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3484 { 3746 {
3485 m_host.AddScriptLPS(1); 3747 m_host.AddScriptLPS(1);
3486 3748
3487 lock (m_host.TaskInventory) 3749 m_host.TaskInventory.LockItemsForRead(true);
3750
3751 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3488 { 3752 {
3489 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3753 if (item.Type == 10 && item.ItemID == m_itemID)
3490 { 3754 {
3491 if (item.Type == 10 && item.ItemID == m_itemID) 3755 int perms = item.PermsMask;
3492 { 3756 if (m_automaticLinkPermission)
3493 int perms = item.PermsMask; 3757 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3494 if (m_automaticLinkPermission) 3758 m_host.TaskInventory.LockItemsForRead(false);
3495 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3759 return perms;
3496 return perms;
3497 }
3498 } 3760 }
3499 } 3761 }
3762 m_host.TaskInventory.LockItemsForRead(false);
3500 3763
3501 return 0; 3764 return 0;
3502 } 3765 }
@@ -3518,9 +3781,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3518 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3781 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3519 { 3782 {
3520 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3783 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3521 3784 if (parts.Count > 0)
3522 foreach (SceneObjectPart part in parts) 3785 {
3523 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3786 try
3787 {
3788 parts[0].ParentGroup.areUpdatesSuspended = true;
3789 foreach (SceneObjectPart part in parts)
3790 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3791 }
3792 finally
3793 {
3794 parts[0].ParentGroup.areUpdatesSuspended = false;
3795 }
3796 }
3524 } 3797 }
3525 3798
3526 public void llCreateLink(string target, int parent) 3799 public void llCreateLink(string target, int parent)
@@ -3533,11 +3806,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 return; 3806 return;
3534 3807
3535 TaskInventoryItem item; 3808 TaskInventoryItem item;
3536 lock (m_host.TaskInventory) 3809 m_host.TaskInventory.LockItemsForRead(true);
3537 { 3810 item = m_host.TaskInventory[invItemID];
3538 item = m_host.TaskInventory[invItemID]; 3811 m_host.TaskInventory.LockItemsForRead(false);
3539 } 3812
3540
3541 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3813 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3542 && !m_automaticLinkPermission) 3814 && !m_automaticLinkPermission)
3543 { 3815 {
@@ -3590,16 +3862,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3590 m_host.AddScriptLPS(1); 3862 m_host.AddScriptLPS(1);
3591 UUID invItemID = InventorySelf(); 3863 UUID invItemID = InventorySelf();
3592 3864
3593 lock (m_host.TaskInventory) 3865 m_host.TaskInventory.LockItemsForRead(true);
3594 {
3595 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3866 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3596 && !m_automaticLinkPermission) 3867 && !m_automaticLinkPermission)
3597 { 3868 {
3598 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3869 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3870 m_host.TaskInventory.LockItemsForRead(false);
3599 return; 3871 return;
3600 } 3872 }
3601 } 3873 m_host.TaskInventory.LockItemsForRead(false);
3602 3874
3603 if (linknum < ScriptBaseClass.LINK_THIS) 3875 if (linknum < ScriptBaseClass.LINK_THIS)
3604 return; 3876 return;
3605 3877
@@ -3639,30 +3911,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 if (linknum == ScriptBaseClass.LINK_ROOT) 3911 if (linknum == ScriptBaseClass.LINK_ROOT)
3640 { 3912 {
3641 // Restructuring Multiple Prims. 3913 // Restructuring Multiple Prims.
3642 lock (parentPrim.Children) 3914 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3915 parts.Remove(parentPrim.RootPart);
3916 if (parts.Count > 0)
3643 { 3917 {
3644 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3918 try
3645 parts.Remove(parentPrim.RootPart); 3919 {
3646 foreach (SceneObjectPart part in parts) 3920 parts[0].ParentGroup.areUpdatesSuspended = true;
3921 foreach (SceneObjectPart part in parts)
3922 {
3923 parentPrim.DelinkFromGroup(part.LocalId, true);
3924 }
3925 }
3926 finally
3647 { 3927 {
3648 parentPrim.DelinkFromGroup(part.LocalId, true); 3928 parts[0].ParentGroup.areUpdatesSuspended = false;
3649 } 3929 }
3650 parentPrim.HasGroupChanged = true; 3930 }
3651 parentPrim.ScheduleGroupForFullUpdate(); 3931
3652 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3932 parentPrim.HasGroupChanged = true;
3653 3933 parentPrim.ScheduleGroupForFullUpdate();
3654 if (parts.Count > 0) 3934 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3935
3936 if (parts.Count > 0)
3937 {
3938 SceneObjectPart newRoot = parts[0];
3939 parts.Remove(newRoot);
3940
3941 try
3655 { 3942 {
3656 SceneObjectPart newRoot = parts[0]; 3943 parts[0].ParentGroup.areUpdatesSuspended = true;
3657 parts.Remove(newRoot);
3658 foreach (SceneObjectPart part in parts) 3944 foreach (SceneObjectPart part in parts)
3659 { 3945 {
3660 part.UpdateFlag = 0; 3946 part.UpdateFlag = 0;
3661 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3947 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3662 } 3948 }
3663 newRoot.ParentGroup.HasGroupChanged = true;
3664 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3665 } 3949 }
3950 finally
3951 {
3952 parts[0].ParentGroup.areUpdatesSuspended = false;
3953 }
3954
3955
3956 newRoot.ParentGroup.HasGroupChanged = true;
3957 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3666 } 3958 }
3667 } 3959 }
3668 else 3960 else
@@ -3709,6 +4001,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3709 } 4001 }
3710 else 4002 else
3711 { 4003 {
4004 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4005 {
4006 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4007
4008 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4009 if (avatars.Count > linknum)
4010 {
4011 return avatars[linknum].UUID.ToString();
4012 }
4013 }
3712 return UUID.Zero.ToString(); 4014 return UUID.Zero.ToString();
3713 } 4015 }
3714 } 4016 }
@@ -3785,17 +4087,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3785 m_host.AddScriptLPS(1); 4087 m_host.AddScriptLPS(1);
3786 int count = 0; 4088 int count = 0;
3787 4089
3788 lock (m_host.TaskInventory) 4090 m_host.TaskInventory.LockItemsForRead(true);
4091 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3789 { 4092 {
3790 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4093 if (inv.Value.Type == type || type == -1)
3791 { 4094 {
3792 if (inv.Value.Type == type || type == -1) 4095 count = count + 1;
3793 {
3794 count = count + 1;
3795 }
3796 } 4096 }
3797 } 4097 }
3798 4098
4099 m_host.TaskInventory.LockItemsForRead(false);
3799 return count; 4100 return count;
3800 } 4101 }
3801 4102
@@ -3804,16 +4105,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 m_host.AddScriptLPS(1); 4105 m_host.AddScriptLPS(1);
3805 ArrayList keys = new ArrayList(); 4106 ArrayList keys = new ArrayList();
3806 4107
3807 lock (m_host.TaskInventory) 4108 m_host.TaskInventory.LockItemsForRead(true);
4109 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3808 { 4110 {
3809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4111 if (inv.Value.Type == type || type == -1)
3810 { 4112 {
3811 if (inv.Value.Type == type || type == -1) 4113 keys.Add(inv.Value.Name);
3812 {
3813 keys.Add(inv.Value.Name);
3814 }
3815 } 4114 }
3816 } 4115 }
4116 m_host.TaskInventory.LockItemsForRead(false);
3817 4117
3818 if (keys.Count == 0) 4118 if (keys.Count == 0)
3819 { 4119 {
@@ -3850,20 +4150,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3850 } 4150 }
3851 4151
3852 // move the first object found with this inventory name 4152 // move the first object found with this inventory name
3853 lock (m_host.TaskInventory) 4153 m_host.TaskInventory.LockItemsForRead(true);
4154 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3854 { 4155 {
3855 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4156 if (inv.Value.Name == inventory)
3856 { 4157 {
3857 if (inv.Value.Name == inventory) 4158 found = true;
3858 { 4159 objId = inv.Key;
3859 found = true; 4160 assetType = inv.Value.Type;
3860 objId = inv.Key; 4161 objName = inv.Value.Name;
3861 assetType = inv.Value.Type; 4162 break;
3862 objName = inv.Value.Name;
3863 break;
3864 }
3865 } 4163 }
3866 } 4164 }
4165 m_host.TaskInventory.LockItemsForRead(false);
3867 4166
3868 if (!found) 4167 if (!found)
3869 { 4168 {
@@ -3871,9 +4170,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4170 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3872 } 4171 }
3873 4172
3874 // check if destination is an avatar 4173 // check if destination is an object
3875 if (World.GetScenePresence(destId) != null) 4174 if (World.GetSceneObjectPart(destId) != null)
3876 { 4175 {
4176 // destination is an object
4177 World.MoveTaskInventoryItem(destId, m_host, objId);
4178 }
4179 else
4180 {
4181 ScenePresence presence = World.GetScenePresence(destId);
4182
4183 if (presence == null)
4184 {
4185 UserAccount account =
4186 World.UserAccountService.GetUserAccount(
4187 World.RegionInfo.ScopeID,
4188 destId);
4189
4190 if (account == null)
4191 {
4192 llSay(0, "Can't find destination "+destId.ToString());
4193 return;
4194 }
4195 }
4196
3877 // destination is an avatar 4197 // destination is an avatar
3878 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4198 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3879 4199
@@ -3897,31 +4217,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 4217
3898 if (m_TransferModule != null) 4218 if (m_TransferModule != null)
3899 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4219 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4220
4221 //This delay should only occur when giving inventory to avatars.
4222 ScriptSleep(3000);
3900 } 4223 }
3901 else
3902 {
3903 // destination is an object
3904 World.MoveTaskInventoryItem(destId, m_host, objId);
3905 }
3906 ScriptSleep(3000);
3907 } 4224 }
3908 4225
4226 [DebuggerNonUserCode]
3909 public void llRemoveInventory(string name) 4227 public void llRemoveInventory(string name)
3910 { 4228 {
3911 m_host.AddScriptLPS(1); 4229 m_host.AddScriptLPS(1);
3912 4230
3913 lock (m_host.TaskInventory) 4231 List<TaskInventoryItem> inv;
4232 try
3914 { 4233 {
3915 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4236 }
4237 finally
4238 {
4239 m_host.TaskInventory.LockItemsForRead(false);
4240 }
4241 foreach (TaskInventoryItem item in inv)
4242 {
4243 if (item.Name == name)
3916 { 4244 {
3917 if (item.Name == name) 4245 if (item.ItemID == m_itemID)
3918 { 4246 throw new ScriptDeleteException();
3919 if (item.ItemID == m_itemID) 4247 else
3920 throw new ScriptDeleteException(); 4248 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3921 else 4249 return;
3922 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3923 return;
3924 }
3925 } 4250 }
3926 } 4251 }
3927 } 4252 }
@@ -3977,6 +4302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3977 ce.time = Util.EnvironmentTickCount(); 4302 ce.time = Util.EnvironmentTickCount();
3978 ce.account = account; 4303 ce.account = account;
3979 ce.pinfo = pinfo; 4304 ce.pinfo = pinfo;
4305 m_userInfoCache[uuid] = ce;
3980 } 4306 }
3981 else 4307 else
3982 { 4308 {
@@ -4040,6 +4366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4040 { 4366 {
4041 m_host.AddScriptLPS(1); 4367 m_host.AddScriptLPS(1);
4042 4368
4369 //Clone is thread safe
4043 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4370 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4044 4371
4045 foreach (TaskInventoryItem item in itemDictionary.Values) 4372 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4093,6 +4420,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4093 ScenePresence presence = World.GetScenePresence(agentId); 4420 ScenePresence presence = World.GetScenePresence(agentId);
4094 if (presence != null) 4421 if (presence != null)
4095 { 4422 {
4423 // agent must not be a god
4424 if (presence.GodLevel >= 200) return;
4425
4096 // agent must be over the owners land 4426 // agent must be over the owners land
4097 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4427 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4098 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4428 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4152,17 +4482,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4152 UUID soundId = UUID.Zero; 4482 UUID soundId = UUID.Zero;
4153 if (!UUID.TryParse(impact_sound, out soundId)) 4483 if (!UUID.TryParse(impact_sound, out soundId))
4154 { 4484 {
4155 lock (m_host.TaskInventory) 4485 m_host.TaskInventory.LockItemsForRead(true);
4486 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4156 { 4487 {
4157 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4488 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4158 { 4489 {
4159 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4490 soundId = item.AssetID;
4160 { 4491 break;
4161 soundId = item.AssetID;
4162 break;
4163 }
4164 } 4492 }
4165 } 4493 }
4494 m_host.TaskInventory.LockItemsForRead(false);
4166 } 4495 }
4167 m_host.CollisionSound = soundId; 4496 m_host.CollisionSound = soundId;
4168 m_host.CollisionSoundVolume = (float)impact_volume; 4497 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4208,6 +4537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4208 UUID partItemID; 4537 UUID partItemID;
4209 foreach (SceneObjectPart part in parts) 4538 foreach (SceneObjectPart part in parts)
4210 { 4539 {
4540 //Clone is thread safe
4211 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4541 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4212 4542
4213 foreach (TaskInventoryItem item in itemsDictionary.Values) 4543 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4422,17 +4752,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4422 4752
4423 m_host.AddScriptLPS(1); 4753 m_host.AddScriptLPS(1);
4424 4754
4425 lock (m_host.TaskInventory) 4755 m_host.TaskInventory.LockItemsForRead(true);
4756 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4426 { 4757 {
4427 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4758 if (item.Type == 10 && item.ItemID == m_itemID)
4428 { 4759 {
4429 if (item.Type == 10 && item.ItemID == m_itemID) 4760 result = item.Name!=null?item.Name:String.Empty;
4430 { 4761 break;
4431 result = item.Name != null ? item.Name : String.Empty;
4432 break;
4433 }
4434 } 4762 }
4435 } 4763 }
4764 m_host.TaskInventory.LockItemsForRead(false);
4436 4765
4437 return result; 4766 return result;
4438 } 4767 }
@@ -4585,23 +4914,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4585 { 4914 {
4586 m_host.AddScriptLPS(1); 4915 m_host.AddScriptLPS(1);
4587 4916
4588 lock (m_host.TaskInventory) 4917 m_host.TaskInventory.LockItemsForRead(true);
4918 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4589 { 4919 {
4590 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4920 if (inv.Value.Name == name)
4591 { 4921 {
4592 if (inv.Value.Name == name) 4922 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4593 { 4923 {
4594 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4924 m_host.TaskInventory.LockItemsForRead(false);
4595 { 4925 return inv.Value.AssetID.ToString();
4596 return inv.Value.AssetID.ToString(); 4926 }
4597 } 4927 else
4598 else 4928 {
4599 { 4929 m_host.TaskInventory.LockItemsForRead(false);
4600 return UUID.Zero.ToString(); 4930 return UUID.Zero.ToString();
4601 }
4602 } 4931 }
4603 } 4932 }
4604 } 4933 }
4934 m_host.TaskInventory.LockItemsForRead(false);
4605 4935
4606 return UUID.Zero.ToString(); 4936 return UUID.Zero.ToString();
4607 } 4937 }
@@ -4754,14 +5084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4754 { 5084 {
4755 m_host.AddScriptLPS(1); 5085 m_host.AddScriptLPS(1);
4756 5086
4757 if (src == null) 5087 return src.Length;
4758 {
4759 return 0;
4760 }
4761 else
4762 {
4763 return src.Length;
4764 }
4765 } 5088 }
4766 5089
4767 public LSL_Integer llList2Integer(LSL_List src, int index) 5090 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4807,7 +5130,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4807 else if (src.Data[index] is LSL_Float) 5130 else if (src.Data[index] is LSL_Float)
4808 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5131 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4809 else if (src.Data[index] is LSL_String) 5132 else if (src.Data[index] is LSL_String)
4810 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5133 {
5134 string str = ((LSL_String) src.Data[index]).m_string;
5135 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5136 if (m != Match.Empty)
5137 {
5138 str = m.Value;
5139 double d = 0.0;
5140 if (!Double.TryParse(str, out d))
5141 return 0.0;
5142
5143 return d;
5144 }
5145 return 0.0;
5146 }
4811 return Convert.ToDouble(src.Data[index]); 5147 return Convert.ToDouble(src.Data[index]);
4812 } 5148 }
4813 catch (FormatException) 5149 catch (FormatException)
@@ -5492,7 +5828,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5492 public void llSetSoundQueueing(int queue) 5828 public void llSetSoundQueueing(int queue)
5493 { 5829 {
5494 m_host.AddScriptLPS(1); 5830 m_host.AddScriptLPS(1);
5495 NotImplemented("llSetSoundQueueing");
5496 } 5831 }
5497 5832
5498 public void llSetSoundRadius(double radius) 5833 public void llSetSoundRadius(double radius)
@@ -5537,10 +5872,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5537 m_host.AddScriptLPS(1); 5872 m_host.AddScriptLPS(1);
5538 5873
5539 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5874 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5540 5875 if (parts.Count > 0)
5541 foreach (var part in parts)
5542 { 5876 {
5543 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5877 try
5878 {
5879 parts[0].ParentGroup.areUpdatesSuspended = true;
5880 foreach (var part in parts)
5881 {
5882 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5883 }
5884 }
5885 finally
5886 {
5887 parts[0].ParentGroup.areUpdatesSuspended = false;
5888 }
5544 } 5889 }
5545 } 5890 }
5546 5891
@@ -5596,74 +5941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5596 5941
5597 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5942 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5598 { 5943 {
5599 m_host.AddScriptLPS(1); 5944 return ParseString2List(str, separators, in_spacers, false);
5600 LSL_List ret = new LSL_List();
5601 LSL_List spacers = new LSL_List();
5602 if (in_spacers.Length > 0 && separators.Length > 0)
5603 {
5604 for (int i = 0; i < in_spacers.Length; i++)
5605 {
5606 object s = in_spacers.Data[i];
5607 for (int j = 0; j < separators.Length; j++)
5608 {
5609 if (separators.Data[j].ToString() == s.ToString())
5610 {
5611 s = null;
5612 break;
5613 }
5614 }
5615 if (s != null)
5616 {
5617 spacers.Add(s);
5618 }
5619 }
5620 }
5621 object[] delimiters = new object[separators.Length + spacers.Length];
5622 separators.Data.CopyTo(delimiters, 0);
5623 spacers.Data.CopyTo(delimiters, separators.Length);
5624 bool dfound = false;
5625 do
5626 {
5627 dfound = false;
5628 int cindex = -1;
5629 string cdeli = "";
5630 for (int i = 0; i < delimiters.Length; i++)
5631 {
5632 int index = str.IndexOf(delimiters[i].ToString());
5633 bool found = index != -1;
5634 if (found && String.Empty != delimiters[i].ToString())
5635 {
5636 if ((cindex > index) || (cindex == -1))
5637 {
5638 cindex = index;
5639 cdeli = delimiters[i].ToString();
5640 }
5641 dfound = dfound || found;
5642 }
5643 }
5644 if (cindex != -1)
5645 {
5646 if (cindex > 0)
5647 {
5648 ret.Add(new LSL_String(str.Substring(0, cindex)));
5649 }
5650 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5651 for (int j = 0; j < spacers.Length; j++)
5652 {
5653 if (spacers.Data[j].ToString() == cdeli)
5654 {
5655 ret.Add(new LSL_String(cdeli));
5656 break;
5657 }
5658 }
5659 str = str.Substring(cindex + cdeli.Length);
5660 }
5661 } while (dfound);
5662 if (str != "")
5663 {
5664 ret.Add(new LSL_String(str));
5665 }
5666 return ret;
5667 } 5945 }
5668 5946
5669 public LSL_Integer llOverMyLand(string id) 5947 public LSL_Integer llOverMyLand(string id)
@@ -5866,7 +6144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5866 return m_host.ParentGroup.RootPart.AttachmentPoint; 6144 return m_host.ParentGroup.RootPart.AttachmentPoint;
5867 } 6145 }
5868 6146
5869 public LSL_Integer llGetFreeMemory() 6147 public virtual LSL_Integer llGetFreeMemory()
5870 { 6148 {
5871 m_host.AddScriptLPS(1); 6149 m_host.AddScriptLPS(1);
5872 // Make scripts designed for LSO happy 6150 // Make scripts designed for LSO happy
@@ -6177,14 +6455,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6177 6455
6178 protected UUID GetTaskInventoryItem(string name) 6456 protected UUID GetTaskInventoryItem(string name)
6179 { 6457 {
6180 lock (m_host.TaskInventory) 6458 m_host.TaskInventory.LockItemsForRead(true);
6459 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6181 { 6460 {
6182 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6461 if (inv.Value.Name == name)
6183 { 6462 {
6184 if (inv.Value.Name == name) 6463 m_host.TaskInventory.LockItemsForRead(false);
6185 return inv.Key; 6464 return inv.Key;
6186 } 6465 }
6187 } 6466 }
6467 m_host.TaskInventory.LockItemsForRead(false);
6188 6468
6189 return UUID.Zero; 6469 return UUID.Zero;
6190 } 6470 }
@@ -6512,22 +6792,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6512 } 6792 }
6513 6793
6514 // copy the first script found with this inventory name 6794 // copy the first script found with this inventory name
6515 lock (m_host.TaskInventory) 6795 m_host.TaskInventory.LockItemsForRead(true);
6796 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6516 { 6797 {
6517 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6798 if (inv.Value.Name == name)
6518 { 6799 {
6519 if (inv.Value.Name == name) 6800 // make sure the object is a script
6801 if (10 == inv.Value.Type)
6520 { 6802 {
6521 // make sure the object is a script 6803 found = true;
6522 if (10 == inv.Value.Type) 6804 srcId = inv.Key;
6523 { 6805 break;
6524 found = true;
6525 srcId = inv.Key;
6526 break;
6527 }
6528 } 6806 }
6529 } 6807 }
6530 } 6808 }
6809 m_host.TaskInventory.LockItemsForRead(false);
6531 6810
6532 if (!found) 6811 if (!found)
6533 { 6812 {
@@ -6611,6 +6890,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6611 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6890 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6612 { 6891 {
6613 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6892 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6893 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6894 return shapeBlock;
6614 6895
6615 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6896 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6616 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6897 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6686,6 +6967,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6686 6967
6687 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6968 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6688 { 6969 {
6970 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6971 return;
6972
6689 ObjectShapePacket.ObjectDataBlock shapeBlock; 6973 ObjectShapePacket.ObjectDataBlock shapeBlock;
6690 6974
6691 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6975 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6735,6 +7019,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6735 7019
6736 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7020 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6737 { 7021 {
7022 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7023 return;
7024
6738 ObjectShapePacket.ObjectDataBlock shapeBlock; 7025 ObjectShapePacket.ObjectDataBlock shapeBlock;
6739 7026
6740 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7027 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6777,6 +7064,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6777 7064
6778 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) 7065 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)
6779 { 7066 {
7067 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7068 return;
7069
6780 ObjectShapePacket.ObjectDataBlock shapeBlock; 7070 ObjectShapePacket.ObjectDataBlock shapeBlock;
6781 7071
6782 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7072 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6903,6 +7193,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6903 7193
6904 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7194 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6905 { 7195 {
7196 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7197 return;
7198
6906 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7199 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6907 UUID sculptId; 7200 UUID sculptId;
6908 7201
@@ -6918,13 +7211,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6918 shapeBlock.PathScaleX = 100; 7211 shapeBlock.PathScaleX = 100;
6919 shapeBlock.PathScaleY = 150; 7212 shapeBlock.PathScaleY = 150;
6920 7213
6921 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7214 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6922 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7215 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6923 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7216 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6924 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7217 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6925 { 7218 {
6926 // default 7219 // default
6927 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7220 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6928 } 7221 }
6929 7222
6930 // retain pathcurve 7223 // retain pathcurve
@@ -6941,23 +7234,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 SetPrimParams(m_host, rules); 7234 SetPrimParams(m_host, rules);
6942 } 7235 }
6943 7236
6944 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7237 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6945 { 7238 {
6946 m_host.AddScriptLPS(1); 7239 m_host.AddScriptLPS(1);
6947 7240
6948 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7241 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7242 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7243 if (parts.Count>0)
7244 {
7245 try
7246 {
7247 parts[0].ParentGroup.areUpdatesSuspended = true;
7248 foreach (SceneObjectPart part in parts)
7249 SetPrimParams(part, rules);
7250 }
7251 finally
7252 {
7253 parts[0].ParentGroup.areUpdatesSuspended = false;
7254 }
7255 }
7256 if (avatars.Count > 0)
7257 {
7258 foreach (ScenePresence avatar in avatars)
7259 SetPrimParams(avatar, rules);
7260 }
7261 }
6949 7262
6950 foreach (SceneObjectPart part in parts) 7263 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6951 SetPrimParams(part, rules); 7264 {
7265 llSetLinkPrimitiveParamsFast(linknumber, rules);
7266 ScriptSleep(200);
6952 } 7267 }
6953 7268
6954 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7269 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6955 { 7270 {
6956 llSetLinkPrimitiveParams(linknumber, rules); 7271 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7272 //We only support PRIM_POSITION and PRIM_ROTATION
7273
7274 int idx = 0;
7275
7276 while (idx < rules.Length)
7277 {
7278 int code = rules.GetLSLIntegerItem(idx++);
7279
7280 int remain = rules.Length - idx;
7281
7282
7283
7284 switch (code)
7285 {
7286 case (int)ScriptBaseClass.PRIM_POSITION:
7287 if (remain < 1)
7288 return;
7289 LSL_Vector v;
7290 v = rules.GetVector3Item(idx++);
7291 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7292 av.SendFullUpdateToAllClients();
7293
7294 break;
7295
7296 case (int)ScriptBaseClass.PRIM_ROTATION:
7297 if (remain < 1)
7298 return;
7299 LSL_Rotation r;
7300 r = rules.GetQuaternionItem(idx++);
7301 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7302 av.SendFullUpdateToAllClients();
7303 break;
7304 }
7305 }
7306
6957 } 7307 }
6958 7308
6959 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7309 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6960 { 7310 {
7311 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7312 return;
7313
6961 int idx = 0; 7314 int idx = 0;
6962 7315
6963 while (idx < rules.Length) 7316 while (idx < rules.Length)
@@ -7474,13 +7827,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7474 public LSL_Integer llGetNumberOfPrims() 7827 public LSL_Integer llGetNumberOfPrims()
7475 { 7828 {
7476 m_host.AddScriptLPS(1); 7829 m_host.AddScriptLPS(1);
7477 int avatarCount = 0; 7830 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7478 World.ForEachScenePresence(delegate(ScenePresence presence) 7831
7479 {
7480 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7481 avatarCount++;
7482 });
7483
7484 return m_host.ParentGroup.PrimCount + avatarCount; 7832 return m_host.ParentGroup.PrimCount + avatarCount;
7485 } 7833 }
7486 7834
@@ -7496,55 +7844,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7496 m_host.AddScriptLPS(1); 7844 m_host.AddScriptLPS(1);
7497 UUID objID = UUID.Zero; 7845 UUID objID = UUID.Zero;
7498 LSL_List result = new LSL_List(); 7846 LSL_List result = new LSL_List();
7847
7848 // If the ID is not valid, return null result
7499 if (!UUID.TryParse(obj, out objID)) 7849 if (!UUID.TryParse(obj, out objID))
7500 { 7850 {
7501 result.Add(new LSL_Vector()); 7851 result.Add(new LSL_Vector());
7502 result.Add(new LSL_Vector()); 7852 result.Add(new LSL_Vector());
7503 return result; 7853 return result;
7504 } 7854 }
7855
7856 // Check if this is an attached prim. If so, replace
7857 // the UUID with the avatar UUID and report it's bounding box
7858 SceneObjectPart part = World.GetSceneObjectPart(objID);
7859 if (part != null && part.ParentGroup.IsAttachment)
7860 objID = part.ParentGroup.RootPart.AttachedAvatar;
7861
7862 // Find out if this is an avatar ID. If so, return it's box
7505 ScenePresence presence = World.GetScenePresence(objID); 7863 ScenePresence presence = World.GetScenePresence(objID);
7506 if (presence != null) 7864 if (presence != null)
7507 { 7865 {
7508 if (presence.ParentID == 0) // not sat on an object 7866 // As per LSL Wiki, there is no difference between sitting
7867 // and standing avatar since server 1.36
7868 LSL_Vector lower;
7869 LSL_Vector upper;
7870 if (presence.Animator.Animations.DefaultAnimation.AnimID
7871 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7509 { 7872 {
7510 LSL_Vector lower; 7873 // This is for ground sitting avatars
7511 LSL_Vector upper; 7874 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7512 if (presence.Animator.Animations.DefaultAnimation.AnimID 7875 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7513 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7876 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7514 {
7515 // This is for ground sitting avatars
7516 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7517 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7518 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7519 }
7520 else
7521 {
7522 // This is for standing/flying avatars
7523 float height = presence.Appearance.AvatarHeight / 2.0f;
7524 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7525 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7526 }
7527 result.Add(lower);
7528 result.Add(upper);
7529 return result;
7530 } 7877 }
7531 else 7878 else
7532 { 7879 {
7533 // sitting on an object so we need the bounding box of that 7880 // This is for standing/flying avatars
7534 // which should include the avatar so set the UUID to the 7881 float height = presence.Appearance.AvatarHeight / 2.0f;
7535 // UUID of the object the avatar is sat on and allow it to fall through 7882 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7536 // to processing an object 7883 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7537 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7538 objID = p.UUID;
7539 } 7884 }
7885
7886 // Adjust to the documented error offsets (see LSL Wiki)
7887 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7888 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7889
7890 if (lower.x > upper.x)
7891 lower.x = upper.x;
7892 if (lower.y > upper.y)
7893 lower.y = upper.y;
7894 if (lower.z > upper.z)
7895 lower.z = upper.z;
7896
7897 result.Add(lower);
7898 result.Add(upper);
7899 return result;
7540 } 7900 }
7541 SceneObjectPart part = World.GetSceneObjectPart(objID); 7901
7902 part = World.GetSceneObjectPart(objID);
7542 // Currently only works for single prims without a sitting avatar 7903 // Currently only works for single prims without a sitting avatar
7543 if (part != null) 7904 if (part != null)
7544 { 7905 {
7545 Vector3 halfSize = part.Scale / 2.0f; 7906 float minX;
7546 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7907 float maxX;
7547 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7908 float minY;
7909 float maxY;
7910 float minZ;
7911 float maxZ;
7912
7913 // This BBox is in sim coordinates, with the offset being
7914 // a contained point.
7915 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7916 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7917
7918 minX -= offsets[0].X;
7919 maxX -= offsets[0].X;
7920 minY -= offsets[0].Y;
7921 maxY -= offsets[0].Y;
7922 minZ -= offsets[0].Z;
7923 maxZ -= offsets[0].Z;
7924
7925 LSL_Vector lower;
7926 LSL_Vector upper;
7927
7928 // Adjust to the documented error offsets (see LSL Wiki)
7929 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7930 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7931
7932 if (lower.x > upper.x)
7933 lower.x = upper.x;
7934 if (lower.y > upper.y)
7935 lower.y = upper.y;
7936 if (lower.z > upper.z)
7937 lower.z = upper.z;
7938
7548 result.Add(lower); 7939 result.Add(lower);
7549 result.Add(upper); 7940 result.Add(upper);
7550 return result; 7941 return result;
@@ -7789,24 +8180,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7789 break; 8180 break;
7790 8181
7791 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8182 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7792 // TODO--------------
7793 if (remain < 1) 8183 if (remain < 1)
7794 return res; 8184 return res;
8185 face = (int)rules.GetLSLIntegerItem(idx++);
7795 8186
7796 face=(int)rules.GetLSLIntegerItem(idx++); 8187 tex = part.Shape.Textures;
7797 8188 int shiny;
7798 res.Add(new LSL_Integer(0)); 8189 if (face == ScriptBaseClass.ALL_SIDES)
7799 res.Add(new LSL_Integer(0)); 8190 {
8191 for (face = 0; face < GetNumberOfSides(part); face++)
8192 {
8193 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8194 if (shinyness == Shininess.High)
8195 {
8196 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8197 }
8198 else if (shinyness == Shininess.Medium)
8199 {
8200 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8201 }
8202 else if (shinyness == Shininess.Low)
8203 {
8204 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8205 }
8206 else
8207 {
8208 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8209 }
8210 res.Add(new LSL_Integer(shiny));
8211 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8212 }
8213 }
8214 else
8215 {
8216 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8217 if (shinyness == Shininess.High)
8218 {
8219 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8220 }
8221 else if (shinyness == Shininess.Medium)
8222 {
8223 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8224 }
8225 else if (shinyness == Shininess.Low)
8226 {
8227 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8228 }
8229 else
8230 {
8231 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8232 }
8233 res.Add(new LSL_Integer(shiny));
8234 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8235 }
7800 break; 8236 break;
7801 8237
7802 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8238 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7803 // TODO--------------
7804 if (remain < 1) 8239 if (remain < 1)
7805 return res; 8240 return res;
8241 face = (int)rules.GetLSLIntegerItem(idx++);
7806 8242
7807 face=(int)rules.GetLSLIntegerItem(idx++); 8243 tex = part.Shape.Textures;
7808 8244 int fullbright;
7809 res.Add(new LSL_Integer(0)); 8245 if (face == ScriptBaseClass.ALL_SIDES)
8246 {
8247 for (face = 0; face < GetNumberOfSides(part); face++)
8248 {
8249 if (tex.GetFace((uint)face).Fullbright == true)
8250 {
8251 fullbright = ScriptBaseClass.TRUE;
8252 }
8253 else
8254 {
8255 fullbright = ScriptBaseClass.FALSE;
8256 }
8257 res.Add(new LSL_Integer(fullbright));
8258 }
8259 }
8260 else
8261 {
8262 if (tex.GetFace((uint)face).Fullbright == true)
8263 {
8264 fullbright = ScriptBaseClass.TRUE;
8265 }
8266 else
8267 {
8268 fullbright = ScriptBaseClass.FALSE;
8269 }
8270 res.Add(new LSL_Integer(fullbright));
8271 }
7810 break; 8272 break;
7811 8273
7812 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8274 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7827,14 +8289,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7827 break; 8289 break;
7828 8290
7829 case (int)ScriptBaseClass.PRIM_TEXGEN: 8291 case (int)ScriptBaseClass.PRIM_TEXGEN:
7830 // TODO--------------
7831 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8292 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7832 if (remain < 1) 8293 if (remain < 1)
7833 return res; 8294 return res;
8295 face = (int)rules.GetLSLIntegerItem(idx++);
7834 8296
7835 face=(int)rules.GetLSLIntegerItem(idx++); 8297 tex = part.Shape.Textures;
7836 8298 if (face == ScriptBaseClass.ALL_SIDES)
7837 res.Add(new LSL_Integer(0)); 8299 {
8300 for (face = 0; face < GetNumberOfSides(part); face++)
8301 {
8302 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8303 {
8304 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8305 }
8306 else
8307 {
8308 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8309 }
8310 }
8311 }
8312 else
8313 {
8314 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8315 {
8316 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8317 }
8318 else
8319 {
8320 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8321 }
8322 }
7838 break; 8323 break;
7839 8324
7840 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8325 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7853,13 +8338,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7853 break; 8338 break;
7854 8339
7855 case (int)ScriptBaseClass.PRIM_GLOW: 8340 case (int)ScriptBaseClass.PRIM_GLOW:
7856 // TODO--------------
7857 if (remain < 1) 8341 if (remain < 1)
7858 return res; 8342 return res;
8343 face = (int)rules.GetLSLIntegerItem(idx++);
7859 8344
7860 face=(int)rules.GetLSLIntegerItem(idx++); 8345 tex = part.Shape.Textures;
7861 8346 float primglow;
7862 res.Add(new LSL_Float(0)); 8347 if (face == ScriptBaseClass.ALL_SIDES)
8348 {
8349 for (face = 0; face < GetNumberOfSides(part); face++)
8350 {
8351 primglow = tex.GetFace((uint)face).Glow;
8352 res.Add(new LSL_Float(primglow));
8353 }
8354 }
8355 else
8356 {
8357 primglow = tex.GetFace((uint)face).Glow;
8358 res.Add(new LSL_Float(primglow));
8359 }
7863 break; 8360 break;
7864 case (int)ScriptBaseClass.PRIM_TEXT: 8361 case (int)ScriptBaseClass.PRIM_TEXT:
7865 Color4 textColor = part.GetTextColor(); 8362 Color4 textColor = part.GetTextColor();
@@ -8400,8 +8897,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8400 // The function returns an ordered list 8897 // The function returns an ordered list
8401 // representing the tokens found in the supplied 8898 // representing the tokens found in the supplied
8402 // sources string. If two successive tokenizers 8899 // sources string. If two successive tokenizers
8403 // are encountered, then a NULL entry is added 8900 // are encountered, then a null-string entry is
8404 // to the list. 8901 // added to the list.
8405 // 8902 //
8406 // It is a precondition that the source and 8903 // It is a precondition that the source and
8407 // toekizer lisst are non-null. If they are null, 8904 // toekizer lisst are non-null. If they are null,
@@ -8409,7 +8906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8409 // while their lengths are being determined. 8906 // while their lengths are being determined.
8410 // 8907 //
8411 // A small amount of working memoryis required 8908 // A small amount of working memoryis required
8412 // of approximately 8*#tokenizers. 8909 // of approximately 8*#tokenizers + 8*srcstrlen.
8413 // 8910 //
8414 // There are many ways in which this function 8911 // There are many ways in which this function
8415 // can be implemented, this implementation is 8912 // can be implemented, this implementation is
@@ -8425,136 +8922,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8425 // and eliminates redundant tokenizers as soon 8922 // and eliminates redundant tokenizers as soon
8426 // as is possible. 8923 // as is possible.
8427 // 8924 //
8428 // The implementation tries to avoid any copying 8925 // The implementation tries to minimize temporary
8429 // of arrays or other objects. 8926 // garbage generation.
8430 // </remarks> 8927 // </remarks>
8431 8928
8432 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8929 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8433 { 8930 {
8434 int beginning = 0; 8931 return ParseString2List(src, separators, spacers, true);
8435 int srclen = src.Length; 8932 }
8436 int seplen = separators.Length;
8437 object[] separray = separators.Data;
8438 int spclen = spacers.Length;
8439 object[] spcarray = spacers.Data;
8440 int mlen = seplen+spclen;
8441
8442 int[] offset = new int[mlen+1];
8443 bool[] active = new bool[mlen];
8444 8933
8445 int best; 8934 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8446 int j; 8935 {
8936 int srclen = src.Length;
8937 int seplen = separators.Length;
8938 object[] separray = separators.Data;
8939 int spclen = spacers.Length;
8940 object[] spcarray = spacers.Data;
8941 int dellen = 0;
8942 string[] delarray = new string[seplen+spclen];
8447 8943
8448 // Initial capacity reduces resize cost 8944 int outlen = 0;
8945 string[] outarray = new string[srclen*2+1];
8449 8946
8450 LSL_List tokens = new LSL_List(); 8947 int i, j;
8948 string d;
8451 8949
8452 m_host.AddScriptLPS(1); 8950 m_host.AddScriptLPS(1);
8453 8951
8454 // All entries are initially valid 8952 /*
8455 8953 * Convert separator and spacer lists to C# strings.
8456 for (int i = 0; i < mlen; i++) 8954 * Also filter out null strings so we don't hang.
8457 active[i] = true; 8955 */
8458 8956 for (i = 0; i < seplen; i ++) {
8459 offset[mlen] = srclen; 8957 d = separray[i].ToString();
8460 8958 if (d.Length > 0) {
8461 while (beginning < srclen) 8959 delarray[dellen++] = d;
8462 { 8960 }
8463 8961 }
8464 best = mlen; // as bad as it gets 8962 seplen = dellen;
8465
8466 // Scan for separators
8467 8963
8468 for (j = 0; j < seplen; j++) 8964 for (i = 0; i < spclen; i ++) {
8469 { 8965 d = spcarray[i].ToString();
8470 if (active[j]) 8966 if (d.Length > 0) {
8471 { 8967 delarray[dellen++] = d;
8472 // scan all of the markers
8473 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8474 {
8475 // not present at all
8476 active[j] = false;
8477 }
8478 else
8479 {
8480 // present and correct
8481 if (offset[j] < offset[best])
8482 {
8483 // closest so far
8484 best = j;
8485 if (offset[best] == beginning)
8486 break;
8487 }
8488 }
8489 }
8490 } 8968 }
8969 }
8491 8970
8492 // Scan for spacers 8971 /*
8972 * Scan through source string from beginning to end.
8973 */
8974 for (i = 0;;) {
8493 8975
8494 if (offset[best] != beginning) 8976 /*
8495 { 8977 * Find earliest delimeter in src starting at i (if any).
8496 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8978 */
8497 { 8979 int earliestDel = -1;
8498 if (active[j]) 8980 int earliestSrc = srclen;
8499 { 8981 string earliestStr = null;
8500 // scan all of the markers 8982 for (j = 0; j < dellen; j ++) {
8501 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8983 d = delarray[j];
8502 { 8984 if (d != null) {
8503 // not present at all 8985 int index = src.IndexOf(d, i);
8504 active[j] = false; 8986 if (index < 0) {
8505 } 8987 delarray[j] = null; // delim nowhere in src, don't check it anymore
8506 else 8988 } else if (index < earliestSrc) {
8507 { 8989 earliestSrc = index; // where delimeter starts in source string
8508 // present and correct 8990 earliestDel = j; // where delimeter is in delarray[]
8509 if (offset[j] < offset[best]) 8991 earliestStr = d; // the delimeter string from delarray[]
8510 { 8992 if (index == i) break; // can't do any better than found at beg of string
8511 // closest so far
8512 best = j;
8513 }
8514 }
8515 } 8993 }
8516 } 8994 }
8517 } 8995 }
8518 8996
8519 // This is the normal exit from the scanning loop 8997 /*
8520 8998 * Output source string starting at i through start of earliest delimeter.
8521 if (best == mlen) 8999 */
8522 { 9000 if (keepNulls || (earliestSrc > i)) {
8523 // no markers were found on this pass 9001 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8524 // so we're pretty much done
8525 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8526 break;
8527 } 9002 }
8528 9003
8529 // Otherwise we just add the newly delimited token 9004 /*
8530 // and recalculate where the search should continue. 9005 * If no delimeter found at or after i, we're done scanning.
8531 9006 */
8532 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9007 if (earliestDel < 0) break;
8533 9008
8534 if (best < seplen) 9009 /*
8535 { 9010 * If delimeter was a spacer, output the spacer.
8536 beginning = offset[best] + (separray[best].ToString()).Length; 9011 */
8537 } 9012 if (earliestDel >= seplen) {
8538 else 9013 outarray[outlen++] = earliestStr;
8539 {
8540 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8541 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8542 } 9014 }
8543 }
8544
8545 // This an awkward an not very intuitive boundary case. If the
8546 // last substring is a tokenizer, then there is an implied trailing
8547 // null list entry. Hopefully the single comparison will not be too
8548 // arduous. Alternatively the 'break' could be replced with a return
8549 // but that's shabby programming.
8550 9015
8551 if (beginning == srclen) 9016 /*
8552 { 9017 * Look at rest of src string following delimeter.
8553 if (srclen != 0) 9018 */
8554 tokens.Add(new LSL_String("")); 9019 i = earliestSrc + earliestStr.Length;
8555 } 9020 }
8556 9021
8557 return tokens; 9022 /*
9023 * Make up an exact-sized output array suitable for an LSL_List object.
9024 */
9025 object[] outlist = new object[outlen];
9026 for (i = 0; i < outlen; i ++) {
9027 outlist[i] = new LSL_String(outarray[i]);
9028 }
9029 return new LSL_List(outlist);
8558 } 9030 }
8559 9031
8560 public LSL_Integer llGetObjectPermMask(int mask) 9032 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8631,28 +9103,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8631 { 9103 {
8632 m_host.AddScriptLPS(1); 9104 m_host.AddScriptLPS(1);
8633 9105
8634 lock (m_host.TaskInventory) 9106 m_host.TaskInventory.LockItemsForRead(true);
9107 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8635 { 9108 {
8636 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9109 if (inv.Value.Name == item)
8637 { 9110 {
8638 if (inv.Value.Name == item) 9111 m_host.TaskInventory.LockItemsForRead(false);
9112 switch (mask)
8639 { 9113 {
8640 switch (mask) 9114 case 0:
8641 { 9115 return (int)inv.Value.BasePermissions;
8642 case 0: 9116 case 1:
8643 return (int)inv.Value.BasePermissions; 9117 return (int)inv.Value.CurrentPermissions;
8644 case 1: 9118 case 2:
8645 return (int)inv.Value.CurrentPermissions; 9119 return (int)inv.Value.GroupPermissions;
8646 case 2: 9120 case 3:
8647 return (int)inv.Value.GroupPermissions; 9121 return (int)inv.Value.EveryonePermissions;
8648 case 3: 9122 case 4:
8649 return (int)inv.Value.EveryonePermissions; 9123 return (int)inv.Value.NextPermissions;
8650 case 4:
8651 return (int)inv.Value.NextPermissions;
8652 }
8653 } 9124 }
8654 } 9125 }
8655 } 9126 }
9127 m_host.TaskInventory.LockItemsForRead(false);
8656 9128
8657 return -1; 9129 return -1;
8658 } 9130 }
@@ -8699,16 +9171,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8699 { 9171 {
8700 m_host.AddScriptLPS(1); 9172 m_host.AddScriptLPS(1);
8701 9173
8702 lock (m_host.TaskInventory) 9174 m_host.TaskInventory.LockItemsForRead(true);
9175 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8703 { 9176 {
8704 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9177 if (inv.Value.Name == item)
8705 { 9178 {
8706 if (inv.Value.Name == item) 9179 m_host.TaskInventory.LockItemsForRead(false);
8707 { 9180 return inv.Value.CreatorID.ToString();
8708 return inv.Value.CreatorID.ToString();
8709 }
8710 } 9181 }
8711 } 9182 }
9183 m_host.TaskInventory.LockItemsForRead(false);
8712 9184
8713 llSay(0, "No item name '" + item + "'"); 9185 llSay(0, "No item name '" + item + "'");
8714 9186
@@ -8759,8 +9231,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8759 return UUID.Zero.ToString(); 9231 return UUID.Zero.ToString();
8760 } 9232 }
8761 reply = new LSL_Vector( 9233 reply = new LSL_Vector(
8762 info.RegionLocX * Constants.RegionSize, 9234 info.RegionLocX,
8763 info.RegionLocY * Constants.RegionSize, 9235 info.RegionLocY,
8764 0).ToString(); 9236 0).ToString();
8765 break; 9237 break;
8766 case 6: // DATA_SIM_STATUS 9238 case 6: // DATA_SIM_STATUS
@@ -8973,17 +9445,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8973 int width = 0; 9445 int width = 0;
8974 int height = 0; 9446 int height = 0;
8975 9447
8976 ParcelMediaCommandEnum? commandToSend = null; 9448 uint commandToSend = 0;
8977 float time = 0.0f; // default is from start 9449 float time = 0.0f; // default is from start
8978 9450
8979 ScenePresence presence = null; 9451 ScenePresence presence = null;
8980 9452
8981 for (int i = 0; i < commandList.Data.Length; i++) 9453 for (int i = 0; i < commandList.Data.Length; i++)
8982 { 9454 {
8983 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9455 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8984 switch (command) 9456 switch (command)
8985 { 9457 {
8986 case ParcelMediaCommandEnum.Agent: 9458 case (uint)ParcelMediaCommandEnum.Agent:
8987 // we send only to one agent 9459 // we send only to one agent
8988 if ((i + 1) < commandList.Length) 9460 if ((i + 1) < commandList.Length)
8989 { 9461 {
@@ -9000,25 +9472,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9000 } 9472 }
9001 break; 9473 break;
9002 9474
9003 case ParcelMediaCommandEnum.Loop: 9475 case (uint)ParcelMediaCommandEnum.Loop:
9004 loop = 1; 9476 loop = 1;
9005 commandToSend = command; 9477 commandToSend = command;
9006 update = true; //need to send the media update packet to set looping 9478 update = true; //need to send the media update packet to set looping
9007 break; 9479 break;
9008 9480
9009 case ParcelMediaCommandEnum.Play: 9481 case (uint)ParcelMediaCommandEnum.Play:
9010 loop = 0; 9482 loop = 0;
9011 commandToSend = command; 9483 commandToSend = command;
9012 update = true; //need to send the media update packet to make sure it doesn't loop 9484 update = true; //need to send the media update packet to make sure it doesn't loop
9013 break; 9485 break;
9014 9486
9015 case ParcelMediaCommandEnum.Pause: 9487 case (uint)ParcelMediaCommandEnum.Pause:
9016 case ParcelMediaCommandEnum.Stop: 9488 case (uint)ParcelMediaCommandEnum.Stop:
9017 case ParcelMediaCommandEnum.Unload: 9489 case (uint)ParcelMediaCommandEnum.Unload:
9018 commandToSend = command; 9490 commandToSend = command;
9019 break; 9491 break;
9020 9492
9021 case ParcelMediaCommandEnum.Url: 9493 case (uint)ParcelMediaCommandEnum.Url:
9022 if ((i + 1) < commandList.Length) 9494 if ((i + 1) < commandList.Length)
9023 { 9495 {
9024 if (commandList.Data[i + 1] is LSL_String) 9496 if (commandList.Data[i + 1] is LSL_String)
@@ -9031,7 +9503,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9031 } 9503 }
9032 break; 9504 break;
9033 9505
9034 case ParcelMediaCommandEnum.Texture: 9506 case (uint)ParcelMediaCommandEnum.Texture:
9035 if ((i + 1) < commandList.Length) 9507 if ((i + 1) < commandList.Length)
9036 { 9508 {
9037 if (commandList.Data[i + 1] is LSL_String) 9509 if (commandList.Data[i + 1] is LSL_String)
@@ -9044,7 +9516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9044 } 9516 }
9045 break; 9517 break;
9046 9518
9047 case ParcelMediaCommandEnum.Time: 9519 case (uint)ParcelMediaCommandEnum.Time:
9048 if ((i + 1) < commandList.Length) 9520 if ((i + 1) < commandList.Length)
9049 { 9521 {
9050 if (commandList.Data[i + 1] is LSL_Float) 9522 if (commandList.Data[i + 1] is LSL_Float)
@@ -9056,7 +9528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9056 } 9528 }
9057 break; 9529 break;
9058 9530
9059 case ParcelMediaCommandEnum.AutoAlign: 9531 case (uint)ParcelMediaCommandEnum.AutoAlign:
9060 if ((i + 1) < commandList.Length) 9532 if ((i + 1) < commandList.Length)
9061 { 9533 {
9062 if (commandList.Data[i + 1] is LSL_Integer) 9534 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9070,7 +9542,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9070 } 9542 }
9071 break; 9543 break;
9072 9544
9073 case ParcelMediaCommandEnum.Type: 9545 case (uint)ParcelMediaCommandEnum.Type:
9074 if ((i + 1) < commandList.Length) 9546 if ((i + 1) < commandList.Length)
9075 { 9547 {
9076 if (commandList.Data[i + 1] is LSL_String) 9548 if (commandList.Data[i + 1] is LSL_String)
@@ -9083,7 +9555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9083 } 9555 }
9084 break; 9556 break;
9085 9557
9086 case ParcelMediaCommandEnum.Desc: 9558 case (uint)ParcelMediaCommandEnum.Desc:
9087 if ((i + 1) < commandList.Length) 9559 if ((i + 1) < commandList.Length)
9088 { 9560 {
9089 if (commandList.Data[i + 1] is LSL_String) 9561 if (commandList.Data[i + 1] is LSL_String)
@@ -9096,7 +9568,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9096 } 9568 }
9097 break; 9569 break;
9098 9570
9099 case ParcelMediaCommandEnum.Size: 9571 case (uint)ParcelMediaCommandEnum.Size:
9100 if ((i + 2) < commandList.Length) 9572 if ((i + 2) < commandList.Length)
9101 { 9573 {
9102 if (commandList.Data[i + 1] is LSL_Integer) 9574 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9166,7 +9638,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 } 9638 }
9167 } 9639 }
9168 9640
9169 if (commandToSend != null) 9641 if (commandToSend != 0)
9170 { 9642 {
9171 // the commandList contained a start/stop/... command, too 9643 // the commandList contained a start/stop/... command, too
9172 if (presence == null) 9644 if (presence == null)
@@ -9203,7 +9675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9203 9675
9204 if (aList.Data[i] != null) 9676 if (aList.Data[i] != null)
9205 { 9677 {
9206 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9678 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9207 { 9679 {
9208 case ParcelMediaCommandEnum.Url: 9680 case ParcelMediaCommandEnum.Url:
9209 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9681 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9246,16 +9718,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 { 9718 {
9247 m_host.AddScriptLPS(1); 9719 m_host.AddScriptLPS(1);
9248 9720
9249 lock (m_host.TaskInventory) 9721 m_host.TaskInventory.LockItemsForRead(true);
9722 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9250 { 9723 {
9251 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9724 if (inv.Value.Name == name)
9252 { 9725 {
9253 if (inv.Value.Name == name) 9726 m_host.TaskInventory.LockItemsForRead(false);
9254 { 9727 return inv.Value.Type;
9255 return inv.Value.Type;
9256 }
9257 } 9728 }
9258 } 9729 }
9730 m_host.TaskInventory.LockItemsForRead(false);
9259 9731
9260 return -1; 9732 return -1;
9261 } 9733 }
@@ -9266,15 +9738,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 9738
9267 if (quick_pay_buttons.Data.Length < 4) 9739 if (quick_pay_buttons.Data.Length < 4)
9268 { 9740 {
9269 LSLError("List must have at least 4 elements"); 9741 int x;
9270 return; 9742 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9743 {
9744 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9745 }
9271 } 9746 }
9272 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9747 int[] nPrice = new int[5];
9273 9748 nPrice[0]=price;
9274 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9749 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9275 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9750 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9276 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9751 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9277 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9752 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9753 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9278 m_host.ParentGroup.HasGroupChanged = true; 9754 m_host.ParentGroup.HasGroupChanged = true;
9279 } 9755 }
9280 9756
@@ -9286,17 +9762,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9286 if (invItemID == UUID.Zero) 9762 if (invItemID == UUID.Zero)
9287 return new LSL_Vector(); 9763 return new LSL_Vector();
9288 9764
9289 lock (m_host.TaskInventory) 9765 m_host.TaskInventory.LockItemsForRead(true);
9766 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9290 { 9767 {
9291 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9768 m_host.TaskInventory.LockItemsForRead(false);
9292 return new LSL_Vector(); 9769 return new LSL_Vector();
9770 }
9293 9771
9294 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9772 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9295 { 9773 {
9296 ShoutError("No permissions to track the camera"); 9774 ShoutError("No permissions to track the camera");
9297 return new LSL_Vector(); 9775 m_host.TaskInventory.LockItemsForRead(false);
9298 } 9776 return new LSL_Vector();
9299 } 9777 }
9778 m_host.TaskInventory.LockItemsForRead(false);
9300 9779
9301 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9780 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9302 if (presence != null) 9781 if (presence != null)
@@ -9314,17 +9793,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9314 if (invItemID == UUID.Zero) 9793 if (invItemID == UUID.Zero)
9315 return new LSL_Rotation(); 9794 return new LSL_Rotation();
9316 9795
9317 lock (m_host.TaskInventory) 9796 m_host.TaskInventory.LockItemsForRead(true);
9797 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9318 { 9798 {
9319 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9799 m_host.TaskInventory.LockItemsForRead(false);
9320 return new LSL_Rotation(); 9800 return new LSL_Rotation();
9321 9801 }
9322 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9802 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9323 { 9803 {
9324 ShoutError("No permissions to track the camera"); 9804 ShoutError("No permissions to track the camera");
9325 return new LSL_Rotation(); 9805 m_host.TaskInventory.LockItemsForRead(false);
9326 } 9806 return new LSL_Rotation();
9327 } 9807 }
9808 m_host.TaskInventory.LockItemsForRead(false);
9328 9809
9329 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9810 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9330 if (presence != null) 9811 if (presence != null)
@@ -9386,8 +9867,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 { 9867 {
9387 m_host.AddScriptLPS(1); 9868 m_host.AddScriptLPS(1);
9388 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9869 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9389 if (detectedParams == null) return; // only works on the first detected avatar 9870 if (detectedParams == null)
9390 9871 {
9872 if (m_host.IsAttachment == true)
9873 {
9874 detectedParams = new DetectParams();
9875 detectedParams.Key = m_host.OwnerID;
9876 }
9877 else
9878 {
9879 return;
9880 }
9881 }
9882
9391 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9883 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9392 if (avatar != null) 9884 if (avatar != null)
9393 { 9885 {
@@ -9395,6 +9887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9395 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9887 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9396 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9888 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9397 } 9889 }
9890
9398 ScriptSleep(1000); 9891 ScriptSleep(1000);
9399 } 9892 }
9400 9893
@@ -9474,14 +9967,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9474 if (objectID == UUID.Zero) return; 9967 if (objectID == UUID.Zero) return;
9475 9968
9476 UUID agentID; 9969 UUID agentID;
9477 lock (m_host.TaskInventory) 9970 m_host.TaskInventory.LockItemsForRead(true);
9478 { 9971 // we need the permission first, to know which avatar we want to set the camera for
9479 // we need the permission first, to know which avatar we want to set the camera for 9972 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9480 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9481 9973
9482 if (agentID == UUID.Zero) return; 9974 if (agentID == UUID.Zero)
9483 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9975 {
9976 m_host.TaskInventory.LockItemsForRead(false);
9977 return;
9978 }
9979 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9980 {
9981 m_host.TaskInventory.LockItemsForRead(false);
9982 return;
9484 } 9983 }
9984 m_host.TaskInventory.LockItemsForRead(false);
9485 9985
9486 ScenePresence presence = World.GetScenePresence(agentID); 9986 ScenePresence presence = World.GetScenePresence(agentID);
9487 9987
@@ -9531,12 +10031,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9531 10031
9532 // we need the permission first, to know which avatar we want to clear the camera for 10032 // we need the permission first, to know which avatar we want to clear the camera for
9533 UUID agentID; 10033 UUID agentID;
9534 lock (m_host.TaskInventory) 10034 m_host.TaskInventory.LockItemsForRead(true);
10035 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10036 if (agentID == UUID.Zero)
10037 {
10038 m_host.TaskInventory.LockItemsForRead(false);
10039 return;
10040 }
10041 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9535 { 10042 {
9536 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10043 m_host.TaskInventory.LockItemsForRead(false);
9537 if (agentID == UUID.Zero) return; 10044 return;
9538 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9539 } 10045 }
10046 m_host.TaskInventory.LockItemsForRead(false);
9540 10047
9541 ScenePresence presence = World.GetScenePresence(agentID); 10048 ScenePresence presence = World.GetScenePresence(agentID);
9542 10049
@@ -9603,19 +10110,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9603 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10110 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9604 { 10111 {
9605 m_host.AddScriptLPS(1); 10112 m_host.AddScriptLPS(1);
9606 string ret = String.Empty; 10113
9607 string src1 = llBase64ToString(str1); 10114 if (str1 == String.Empty)
9608 string src2 = llBase64ToString(str2); 10115 return String.Empty;
9609 int c = 0; 10116 if (str2 == String.Empty)
9610 for (int i = 0; i < src1.Length; i++) 10117 return str1;
10118
10119 byte[] data1 = Convert.FromBase64String(str1);
10120 byte[] data2 = Convert.FromBase64String(str2);
10121
10122 byte[] d2 = new Byte[data1.Length];
10123 int pos = 0;
10124
10125 if (data1.Length <= data2.Length)
10126 {
10127 Array.Copy(data2, 0, d2, 0, data1.Length);
10128 }
10129 else
9611 { 10130 {
9612 ret += (char) (src1[i] ^ src2[c]); 10131 while (pos < data1.Length)
10132 {
10133 int len = data1.Length - pos;
10134 if (len > data2.Length)
10135 len = data2.Length;
9613 10136
9614 c++; 10137 Array.Copy(data2, 0, d2, pos, len);
9615 if (c >= src2.Length) 10138 pos += len;
9616 c = 0; 10139 }
9617 } 10140 }
9618 return llStringToBase64(ret); 10141
10142 for (pos = 0 ; pos < data1.Length ; pos++ )
10143 data1[pos] ^= d2[pos];
10144
10145 return Convert.ToBase64String(data1);
9619 } 10146 }
9620 10147
9621 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10148 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9993,15 +10520,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9993 10520
9994 internal UUID ScriptByName(string name) 10521 internal UUID ScriptByName(string name)
9995 { 10522 {
9996 lock (m_host.TaskInventory) 10523 m_host.TaskInventory.LockItemsForRead(true);
10524
10525 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9997 { 10526 {
9998 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10527 if (item.Type == 10 && item.Name == name)
9999 { 10528 {
10000 if (item.Type == 10 && item.Name == name) 10529 m_host.TaskInventory.LockItemsForRead(false);
10001 return item.ItemID; 10530 return item.ItemID;
10002 } 10531 }
10003 } 10532 }
10004 10533
10534 m_host.TaskInventory.LockItemsForRead(false);
10535
10005 return UUID.Zero; 10536 return UUID.Zero;
10006 } 10537 }
10007 10538
@@ -10042,6 +10573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10042 { 10573 {
10043 m_host.AddScriptLPS(1); 10574 m_host.AddScriptLPS(1);
10044 10575
10576 //Clone is thread safe
10045 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10577 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10046 10578
10047 UUID assetID = UUID.Zero; 10579 UUID assetID = UUID.Zero;
@@ -10104,6 +10636,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10104 { 10636 {
10105 m_host.AddScriptLPS(1); 10637 m_host.AddScriptLPS(1);
10106 10638
10639 //Clone is thread safe
10107 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10640 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10108 10641
10109 UUID assetID = UUID.Zero; 10642 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 477c52d..6827ede 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2216,9 +2229,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 { 2229 {
2217 if (avatar.IsChildAgent == false) 2230 if (avatar.IsChildAgent == false)
2218 { 2231 {
2219 result.Add(avatar.UUID); 2232 result.Add(new LSL_Key(avatar.UUID.ToString()));
2220 result.Add(avatar.AbsolutePosition); 2233 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2221 result.Add(avatar.Name); 2234 result.Add(new LSL_String(avatar.Name));
2222 } 2235 }
2223 } 2236 }
2224 }); 2237 });
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/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 78ee43c..c8f3623 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
81 // Avatar Info Commands 81 // Avatar Info Commands
82 string osGetAgentIP(string agent); 82 string osGetAgentIP(string agent);
83 LSL_List osGetAgents(); 83 LSL_List osGetAgents();
84 84
85 // Teleport commands 85 // Teleport commands
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 5da6bb9..6e8435d 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..f14967e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index f8dbe03..8280ca5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,5 +72,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
76 public LSL_List cmGetWindlightScene(LSL_List rules)
77 {
78 return m_LS_Functions.lsGetWindlightScene(rules);
79 }
80
81 public int cmSetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsSetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
87 {
88 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
89 }
75 } 90 }
76} 91}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6663aa5..b4da246 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -429,14 +429,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 429 {
430 int permsMask; 430 int permsMask;
431 UUID permsGranter; 431 UUID permsGranter;
432 lock (part.TaskInventory) 432 part.TaskInventory.LockItemsForRead(true);
433 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 434 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 435 part.TaskInventory.LockItemsForRead(false);
435 return; 436 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 437 }
438 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
439 permsMask = part.TaskInventory[m_ItemID].PermsMask;
440 part.TaskInventory.LockItemsForRead(false);
440 441
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 442 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 443 {
@@ -545,6 +546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 546 return true;
546 } 547 }
547 548
549 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 550 public void SetState(string state)
549 { 551 {
550 if (state == State) 552 if (state == State)
@@ -556,7 +558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 558 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 559 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 560 new DetectParams[0]));
559 561
560 throw new EventAbortException(); 562 throw new EventAbortException();
561 } 563 }
562 564
@@ -639,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 641 /// <returns></returns>
640 public object EventProcessor() 642 public object EventProcessor()
641 { 643 {
642 if (m_Suspended) 644 EventParams data = null;
643 return 0;
644 645
645 lock (m_Script) 646 lock (m_EventQueue)
646 { 647 {
647 EventParams data = null; 648 if (m_Suspended)
649 return 0;
648 650
649 lock (m_EventQueue) 651 lock (m_Script)
650 { 652 {
651 data = (EventParams) m_EventQueue.Dequeue(); 653 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 654 if (data == null) // Shouldn't happen
@@ -672,6 +674,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 674 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 675 m_CollisionInQueue = false;
674 } 676 }
677 }
678 lock(m_Script)
679 {
675 680
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 682
@@ -828,6 +833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 833 new Object[0], new DetectParams[0]));
829 } 834 }
830 835
836 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 837 public void ApiResetScript()
832 { 838 {
833 // bool running = Running; 839 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 427d4e5..e82d297 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -263,43 +331,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
263 331
264 public void RemoveRegion(Scene scene) 332 public void RemoveRegion(Scene scene)
265 { 333 {
266 lock (m_Scripts) 334 lockScriptsForRead(true);
335 foreach (IScriptInstance instance in m_Scripts.Values)
267 { 336 {
268 foreach (IScriptInstance instance in m_Scripts.Values) 337 // Force a final state save
338 //
339 if (m_Assemblies.ContainsKey(instance.AssetID))
269 { 340 {
270 // Force a final state save 341 string assembly = m_Assemblies[instance.AssetID];
271 // 342 instance.SaveState(assembly);
272 if (m_Assemblies.ContainsKey(instance.AssetID)) 343 }
273 {
274 string assembly = m_Assemblies[instance.AssetID];
275 instance.SaveState(assembly);
276 }
277 344
278 // Clear the event queue and abort the instance thread 345 // Clear the event queue and abort the instance thread
279 // 346 //
280 instance.ClearQueue(); 347 instance.ClearQueue();
281 instance.Stop(0); 348 instance.Stop(0);
282 349
283 // Release events, timer, etc 350 // Release events, timer, etc
284 // 351 //
285 instance.DestroyScriptInstance(); 352 instance.DestroyScriptInstance();
286 353
287 // Unload scripts and app domains 354 // Unload scripts and app domains
288 // Must be done explicitly because they have infinite 355 // Must be done explicitly because they have infinite
289 // lifetime 356 // lifetime
290 // 357 //
291 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 358 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
292 if (m_DomainScripts[instance.AppDomain].Count == 0) 359 if (m_DomainScripts[instance.AppDomain].Count == 0)
293 { 360 {
294 m_DomainScripts.Remove(instance.AppDomain); 361 m_DomainScripts.Remove(instance.AppDomain);
295 UnloadAppDomain(instance.AppDomain); 362 UnloadAppDomain(instance.AppDomain);
296 }
297 } 363 }
298 m_Scripts.Clear();
299 m_PrimObjects.Clear();
300 m_Assemblies.Clear();
301 m_DomainScripts.Clear();
302 } 364 }
365 lockScriptsForRead(false);
366 lockScriptsForWrite(true);
367 m_Scripts.Clear();
368 lockScriptsForWrite(false);
369 m_PrimObjects.Clear();
370 m_Assemblies.Clear();
371 m_DomainScripts.Clear();
372
303 lock (m_ScriptEngines) 373 lock (m_ScriptEngines)
304 { 374 {
305 m_ScriptEngines.Remove(this); 375 m_ScriptEngines.Remove(this);
@@ -358,22 +428,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
358 428
359 List<IScriptInstance> instances = new List<IScriptInstance>(); 429 List<IScriptInstance> instances = new List<IScriptInstance>();
360 430
361 lock (m_Scripts) 431 lockScriptsForRead(true);
362 { 432 foreach (IScriptInstance instance in m_Scripts.Values)
363 foreach (IScriptInstance instance in m_Scripts.Values)
364 instances.Add(instance); 433 instances.Add(instance);
365 } 434 lockScriptsForRead(false);
366 435
367 foreach (IScriptInstance i in instances) 436 foreach (IScriptInstance i in instances)
368 { 437 {
369 string assembly = String.Empty; 438 string assembly = String.Empty;
370 439
371 lock (m_Scripts) 440
372 {
373 if (!m_Assemblies.ContainsKey(i.AssetID)) 441 if (!m_Assemblies.ContainsKey(i.AssetID))
374 continue; 442 continue;
375 assembly = m_Assemblies[i.AssetID]; 443 assembly = m_Assemblies[i.AssetID];
376 } 444
377 445
378 i.SaveState(assembly); 446 i.SaveState(assembly);
379 } 447 }
@@ -702,92 +770,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 } 770 }
703 771
704 ScriptInstance instance = null; 772 ScriptInstance instance = null;
705 lock (m_Scripts) 773 // Create the object record
774 lockScriptsForRead(true);
775 if ((!m_Scripts.ContainsKey(itemID)) ||
776 (m_Scripts[itemID].AssetID != assetID))
706 { 777 {
707 // Create the object record 778 lockScriptsForRead(false);
708 779
709 if ((!m_Scripts.ContainsKey(itemID)) || 780 UUID appDomain = assetID;
710 (m_Scripts[itemID].AssetID != assetID))
711 {
712 UUID appDomain = assetID;
713 781
714 if (part.ParentGroup.IsAttachment) 782 if (part.ParentGroup.IsAttachment)
715 appDomain = part.ParentGroup.RootPart.UUID; 783 appDomain = part.ParentGroup.RootPart.UUID;
716 784
717 if (!m_AppDomains.ContainsKey(appDomain)) 785 if (!m_AppDomains.ContainsKey(appDomain))
786 {
787 try
718 { 788 {
719 try 789 AppDomainSetup appSetup = new AppDomainSetup();
720 { 790 // appSetup.ApplicationBase = Path.Combine(
721 AppDomainSetup appSetup = new AppDomainSetup(); 791 // "ScriptEngines",
722// appSetup.ApplicationBase = Path.Combine( 792 // m_Scene.RegionInfo.RegionID.ToString());
723// "ScriptEngines", 793
724// m_Scene.RegionInfo.RegionID.ToString()); 794 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
725 795 Evidence evidence = new Evidence(baseEvidence);
726 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 796
727 Evidence evidence = new Evidence(baseEvidence); 797 AppDomain sandbox;
728 798 if (m_AppDomainLoading)
729 AppDomain sandbox; 799 sandbox = AppDomain.CreateDomain(
730 if (m_AppDomainLoading) 800 m_Scene.RegionInfo.RegionID.ToString(),
731 sandbox = AppDomain.CreateDomain( 801 evidence, appSetup);
732 m_Scene.RegionInfo.RegionID.ToString(), 802 else
733 evidence, appSetup); 803 sandbox = AppDomain.CurrentDomain;
734 else 804
735 sandbox = AppDomain.CurrentDomain; 805 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
736 806 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
737 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 807 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
738 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 808 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
739 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 809 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
740 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 810 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
741 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 811 //sandbox.SetAppDomainPolicy(sandboxPolicy);
742 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 812
743 //sandbox.SetAppDomainPolicy(sandboxPolicy); 813 m_AppDomains[appDomain] = sandbox;
744 814
745 m_AppDomains[appDomain] = sandbox; 815 m_AppDomains[appDomain].AssemblyResolve +=
746 816 new ResolveEventHandler(
747 m_AppDomains[appDomain].AssemblyResolve += 817 AssemblyResolver.OnAssemblyResolve);
748 new ResolveEventHandler( 818 m_DomainScripts[appDomain] = new List<UUID>();
749 AssemblyResolver.OnAssemblyResolve); 819 }
750 m_DomainScripts[appDomain] = new List<UUID>(); 820 catch (Exception e)
751 } 821 {
752 catch (Exception e) 822 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
823 m_ScriptErrorMessage += "Exception creating app domain:\n";
824 m_ScriptFailCount++;
825 lock (m_AddingAssemblies)
753 { 826 {
754 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 827 m_AddingAssemblies[assembly]--;
755 m_ScriptErrorMessage += "Exception creating app domain:\n";
756 m_ScriptFailCount++;
757 lock (m_AddingAssemblies)
758 {
759 m_AddingAssemblies[assembly]--;
760 }
761 return false;
762 } 828 }
829 return false;
763 } 830 }
764 m_DomainScripts[appDomain].Add(itemID); 831 }
765 832 m_DomainScripts[appDomain].Add(itemID);
766 instance = new ScriptInstance(this, part, 833
767 itemID, assetID, assembly, 834 instance = new ScriptInstance(this, part,
768 m_AppDomains[appDomain], 835 itemID, assetID, assembly,
769 part.ParentGroup.RootPart.Name, 836 m_AppDomains[appDomain],
770 item.Name, startParam, postOnRez, 837 part.ParentGroup.RootPart.Name,
771 stateSource, m_MaxScriptQueue); 838 item.Name, startParam, postOnRez,
772 839 stateSource, m_MaxScriptQueue);
773 m_log.DebugFormat( 840
841 m_log.DebugFormat(
774 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 842 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
775 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 843 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
776 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 844 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
777 845
778 if (presence != null) 846 if (presence != null)
779 { 847 {
780 ShowScriptSaveResponse(item.OwnerID, 848 ShowScriptSaveResponse(item.OwnerID,
781 assetID, "Compile successful", true); 849 assetID, "Compile successful", true);
782 }
783
784 instance.AppDomain = appDomain;
785 instance.LineMap = linemap;
786
787 m_Scripts[itemID] = instance;
788 } 850 }
789 }
790 851
852 instance.AppDomain = appDomain;
853 instance.LineMap = linemap;
854 lockScriptsForWrite(true);
855 m_Scripts[itemID] = instance;
856 lockScriptsForWrite(false);
857 }
858 else
859 {
860 lockScriptsForRead(false);
861 }
791 lock (m_PrimObjects) 862 lock (m_PrimObjects)
792 { 863 {
793 if (!m_PrimObjects.ContainsKey(localID)) 864 if (!m_PrimObjects.ContainsKey(localID))
@@ -806,9 +877,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
806 m_AddingAssemblies[assembly]--; 877 m_AddingAssemblies[assembly]--;
807 } 878 }
808 879
809 if (instance != null) 880 if (instance!=null)
810 instance.Init(); 881 instance.Init();
811 882
812 return true; 883 return true;
813 } 884 }
814 885
@@ -821,20 +892,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
821 m_CompileDict.Remove(itemID); 892 m_CompileDict.Remove(itemID);
822 } 893 }
823 894
824 IScriptInstance instance = null; 895 lockScriptsForRead(true);
825 896 // Do we even have it?
826 lock (m_Scripts) 897 if (!m_Scripts.ContainsKey(itemID))
827 { 898 {
828 // Do we even have it? 899 lockScriptsForRead(false);
829 if (!m_Scripts.ContainsKey(itemID)) 900 return;
830 return;
831
832 instance=m_Scripts[itemID];
833 m_Scripts.Remove(itemID);
834 } 901 }
902
835 903
904 IScriptInstance instance=m_Scripts[itemID];
905 lockScriptsForRead(false);
906 lockScriptsForWrite(true);
907 m_Scripts.Remove(itemID);
908 lockScriptsForWrite(false);
836 instance.ClearQueue(); 909 instance.ClearQueue();
837 instance.Stop(0); 910 instance.Stop(0);
911
838// bool objectRemoved = false; 912// bool objectRemoved = false;
839 913
840 lock (m_PrimObjects) 914 lock (m_PrimObjects)
@@ -870,11 +944,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
870 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 944 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
871 if (handlerObjectRemoved != null) 945 if (handlerObjectRemoved != null)
872 { 946 {
873 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 947 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
874 handlerObjectRemoved(part.UUID); 948 handlerObjectRemoved(part.UUID);
875 } 949 }
876 950
877 951 CleanAssemblies();
952
878 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 953 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
879 if (handlerScriptRemoved != null) 954 if (handlerScriptRemoved != null)
880 handlerScriptRemoved(itemID); 955 handlerScriptRemoved(itemID);
@@ -1016,7 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1016 return false; 1091 return false;
1017 1092
1018 uuids = m_PrimObjects[localID]; 1093 uuids = m_PrimObjects[localID];
1019 } 1094
1020 1095
1021 foreach (UUID itemID in uuids) 1096 foreach (UUID itemID in uuids)
1022 { 1097 {
@@ -1034,6 +1109,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1034 result = true; 1109 result = true;
1035 } 1110 }
1036 } 1111 }
1112 }
1037 1113
1038 return result; 1114 return result;
1039 } 1115 }
@@ -1133,12 +1209,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 private IScriptInstance GetInstance(UUID itemID) 1209 private IScriptInstance GetInstance(UUID itemID)
1134 { 1210 {
1135 IScriptInstance instance; 1211 IScriptInstance instance;
1136 lock (m_Scripts) 1212 lockScriptsForRead(true);
1213 if (!m_Scripts.ContainsKey(itemID))
1137 { 1214 {
1138 if (!m_Scripts.ContainsKey(itemID)) 1215 lockScriptsForRead(false);
1139 return null; 1216 return null;
1140 instance = m_Scripts[itemID];
1141 } 1217 }
1218 instance = m_Scripts[itemID];
1219 lockScriptsForRead(false);
1142 return instance; 1220 return instance;
1143 } 1221 }
1144 1222
@@ -1162,6 +1240,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1162 return false; 1240 return false;
1163 } 1241 }
1164 1242
1243 [DebuggerNonUserCode]
1165 public void ApiResetScript(UUID itemID) 1244 public void ApiResetScript(UUID itemID)
1166 { 1245 {
1167 IScriptInstance instance = GetInstance(itemID); 1246 IScriptInstance instance = GetInstance(itemID);
@@ -1213,6 +1292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1213 return UUID.Zero; 1292 return UUID.Zero;
1214 } 1293 }
1215 1294
1295 [DebuggerNonUserCode]
1216 public void SetState(UUID itemID, string newState) 1296 public void SetState(UUID itemID, string newState)
1217 { 1297 {
1218 IScriptInstance instance = GetInstance(itemID); 1298 IScriptInstance instance = GetInstance(itemID);
@@ -1233,11 +1313,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1233 { 1313 {
1234 List<IScriptInstance> instances = new List<IScriptInstance>(); 1314 List<IScriptInstance> instances = new List<IScriptInstance>();
1235 1315
1236 lock (m_Scripts) 1316 lockScriptsForRead(true);
1237 { 1317 foreach (IScriptInstance instance in m_Scripts.Values)
1238 foreach (IScriptInstance instance in m_Scripts.Values)
1239 instances.Add(instance); 1318 instances.Add(instance);
1240 } 1319 lockScriptsForRead(false);
1241 1320
1242 foreach (IScriptInstance i in instances) 1321 foreach (IScriptInstance i in instances)
1243 { 1322 {