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.cs1873
-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, 1552 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..a5b3cd0 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,17 @@ 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 if (!m_debuggerSafe)
3253 {
3254 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3255 }
3256 return;
3257 }
3258
3259
3024 m_host.AddScriptLPS(1); 3260 m_host.AddScriptLPS(1);
3025 3261
3026 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3262 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3035,14 +3271,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3035 UUID friendTransactionID = UUID.Random(); 3271 UUID friendTransactionID = UUID.Random();
3036 3272
3037 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3273 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3038 3274
3039 GridInstantMessage msg = new GridInstantMessage(); 3275 GridInstantMessage msg = new GridInstantMessage();
3040 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3276 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3041 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3277 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3042 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3278 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); 3279// 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()); 3280// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3045 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3281 DateTime dt = DateTime.UtcNow;
3282
3283 // Ticks from UtcNow, but make it look like local. Evil, huh?
3284 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3285
3286 try
3287 {
3288 // Convert that to the PST timezone
3289 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3290 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3291 }
3292 catch
3293 {
3294 // No logging here, as it could be VERY spammy
3295 }
3296
3297 // And make it look local again to fool the unix time util
3298 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3299
3300 msg.timestamp = (uint)Util.ToUnixTime(dt);
3301
3046 //if (client != null) 3302 //if (client != null)
3047 //{ 3303 //{
3048 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3304 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3056,13 +3312,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 msg.message = message.Substring(0, 1024); 3312 msg.message = message.Substring(0, 1024);
3057 else 3313 else
3058 msg.message = message; 3314 msg.message = message;
3059 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3315 msg.dialog = (byte)19; // MessageFromObject
3060 msg.fromGroup = false;// fromGroup; 3316 msg.fromGroup = false;// fromGroup;
3061 msg.offline = (byte)0; //offline; 3317 msg.offline = (byte)0; //offline;
3062 msg.ParentEstateID = 0; //ParentEstateID; 3318 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3063 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3319 msg.Position = new Vector3(m_host.AbsolutePosition);
3064 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3320 msg.RegionID = World.RegionInfo.RegionID.Guid;
3065 msg.binaryBucket = new byte[0];// binaryBucket; 3321 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3066 3322
3067 if (m_TransferModule != null) 3323 if (m_TransferModule != null)
3068 { 3324 {
@@ -3082,7 +3338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 } 3338 }
3083 3339
3084 emailModule.SendEmail(m_host.UUID, address, subject, message); 3340 emailModule.SendEmail(m_host.UUID, address, subject, message);
3085 ScriptSleep(20000); 3341 ScriptSleep(15000);
3086 } 3342 }
3087 3343
3088 public void llGetNextEmail(string address, string subject) 3344 public void llGetNextEmail(string address, string subject)
@@ -3184,13 +3440,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3184 m_host.AddScriptLPS(1); 3440 m_host.AddScriptLPS(1);
3185 } 3441 }
3186 3442
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) 3443 public LSL_Integer llStringLength(string str)
3195 { 3444 {
3196 m_host.AddScriptLPS(1); 3445 m_host.AddScriptLPS(1);
@@ -3214,14 +3463,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3214 3463
3215 TaskInventoryItem item; 3464 TaskInventoryItem item;
3216 3465
3217 lock (m_host.TaskInventory) 3466 m_host.TaskInventory.LockItemsForRead(true);
3467 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3218 { 3468 {
3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3469 m_host.TaskInventory.LockItemsForRead(false);
3220 return; 3470 return;
3221 else
3222 item = m_host.TaskInventory[InventorySelf()];
3223 } 3471 }
3224 3472 else
3473 {
3474 item = m_host.TaskInventory[InventorySelf()];
3475 }
3476 m_host.TaskInventory.LockItemsForRead(false);
3225 if (item.PermsGranter == UUID.Zero) 3477 if (item.PermsGranter == UUID.Zero)
3226 return; 3478 return;
3227 3479
@@ -3251,13 +3503,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3251 3503
3252 TaskInventoryItem item; 3504 TaskInventoryItem item;
3253 3505
3254 lock (m_host.TaskInventory) 3506 m_host.TaskInventory.LockItemsForRead(true);
3507 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3255 { 3508 {
3256 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3509 m_host.TaskInventory.LockItemsForRead(false);
3257 return; 3510 return;
3258 else 3511 }
3259 item = m_host.TaskInventory[InventorySelf()]; 3512 else
3513 {
3514 item = m_host.TaskInventory[InventorySelf()];
3260 } 3515 }
3516 m_host.TaskInventory.LockItemsForRead(false);
3517
3261 3518
3262 if (item.PermsGranter == UUID.Zero) 3519 if (item.PermsGranter == UUID.Zero)
3263 return; 3520 return;
@@ -3328,10 +3585,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3328 3585
3329 TaskInventoryItem item; 3586 TaskInventoryItem item;
3330 3587
3331 lock (m_host.TaskInventory) 3588
3589 m_host.TaskInventory.LockItemsForRead(true);
3590 if (!m_host.TaskInventory.ContainsKey(invItemID))
3591 {
3592 m_host.TaskInventory.LockItemsForRead(false);
3593 return;
3594 }
3595 else
3332 { 3596 {
3333 item = m_host.TaskInventory[invItemID]; 3597 item = m_host.TaskInventory[invItemID];
3334 } 3598 }
3599 m_host.TaskInventory.LockItemsForRead(false);
3335 3600
3336 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3601 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3337 { 3602 {
@@ -3363,11 +3628,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3363 3628
3364 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3629 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3365 { 3630 {
3366 lock (m_host.TaskInventory) 3631 m_host.TaskInventory.LockItemsForWrite(true);
3367 { 3632 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3368 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3633 m_host.TaskInventory[invItemID].PermsMask = perm;
3369 m_host.TaskInventory[invItemID].PermsMask = perm; 3634 m_host.TaskInventory.LockItemsForWrite(false);
3370 }
3371 3635
3372 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3636 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3373 "run_time_permissions", new Object[] { 3637 "run_time_permissions", new Object[] {
@@ -3387,11 +3651,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3387 3651
3388 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3652 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3389 { 3653 {
3390 lock (m_host.TaskInventory) 3654 m_host.TaskInventory.LockItemsForWrite(true);
3391 { 3655 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3392 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3656 m_host.TaskInventory[invItemID].PermsMask = perm;
3393 m_host.TaskInventory[invItemID].PermsMask = perm; 3657 m_host.TaskInventory.LockItemsForWrite(false);
3394 }
3395 3658
3396 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3659 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3397 "run_time_permissions", new Object[] { 3660 "run_time_permissions", new Object[] {
@@ -3412,11 +3675,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3412 3675
3413 if (!m_waitingForScriptAnswer) 3676 if (!m_waitingForScriptAnswer)
3414 { 3677 {
3415 lock (m_host.TaskInventory) 3678 m_host.TaskInventory.LockItemsForWrite(true);
3416 { 3679 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3417 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3680 m_host.TaskInventory[invItemID].PermsMask = 0;
3418 m_host.TaskInventory[invItemID].PermsMask = 0; 3681 m_host.TaskInventory.LockItemsForWrite(false);
3419 }
3420 3682
3421 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3683 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3422 m_waitingForScriptAnswer=true; 3684 m_waitingForScriptAnswer=true;
@@ -3451,10 +3713,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3451 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3713 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3452 llReleaseControls(); 3714 llReleaseControls();
3453 3715
3454 lock (m_host.TaskInventory) 3716
3455 { 3717 m_host.TaskInventory.LockItemsForWrite(true);
3456 m_host.TaskInventory[invItemID].PermsMask = answer; 3718 m_host.TaskInventory[invItemID].PermsMask = answer;
3457 } 3719 m_host.TaskInventory.LockItemsForWrite(false);
3720
3458 3721
3459 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3722 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3460 "run_time_permissions", new Object[] { 3723 "run_time_permissions", new Object[] {
@@ -3466,16 +3729,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3466 { 3729 {
3467 m_host.AddScriptLPS(1); 3730 m_host.AddScriptLPS(1);
3468 3731
3469 lock (m_host.TaskInventory) 3732 m_host.TaskInventory.LockItemsForRead(true);
3733
3734 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3470 { 3735 {
3471 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3736 if (item.Type == 10 && item.ItemID == m_itemID)
3472 { 3737 {
3473 if (item.Type == 10 && item.ItemID == m_itemID) 3738 m_host.TaskInventory.LockItemsForRead(false);
3474 { 3739 return item.PermsGranter.ToString();
3475 return item.PermsGranter.ToString();
3476 }
3477 } 3740 }
3478 } 3741 }
3742 m_host.TaskInventory.LockItemsForRead(false);
3479 3743
3480 return UUID.Zero.ToString(); 3744 return UUID.Zero.ToString();
3481 } 3745 }
@@ -3484,19 +3748,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3484 { 3748 {
3485 m_host.AddScriptLPS(1); 3749 m_host.AddScriptLPS(1);
3486 3750
3487 lock (m_host.TaskInventory) 3751 m_host.TaskInventory.LockItemsForRead(true);
3752
3753 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3488 { 3754 {
3489 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3755 if (item.Type == 10 && item.ItemID == m_itemID)
3490 { 3756 {
3491 if (item.Type == 10 && item.ItemID == m_itemID) 3757 int perms = item.PermsMask;
3492 { 3758 if (m_automaticLinkPermission)
3493 int perms = item.PermsMask; 3759 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3494 if (m_automaticLinkPermission) 3760 m_host.TaskInventory.LockItemsForRead(false);
3495 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3761 return perms;
3496 return perms;
3497 }
3498 } 3762 }
3499 } 3763 }
3764 m_host.TaskInventory.LockItemsForRead(false);
3500 3765
3501 return 0; 3766 return 0;
3502 } 3767 }
@@ -3518,9 +3783,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3518 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3783 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3519 { 3784 {
3520 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3785 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3521 3786 if (parts.Count > 0)
3522 foreach (SceneObjectPart part in parts) 3787 {
3523 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3788 try
3789 {
3790 parts[0].ParentGroup.areUpdatesSuspended = true;
3791 foreach (SceneObjectPart part in parts)
3792 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3793 }
3794 finally
3795 {
3796 parts[0].ParentGroup.areUpdatesSuspended = false;
3797 }
3798 }
3524 } 3799 }
3525 3800
3526 public void llCreateLink(string target, int parent) 3801 public void llCreateLink(string target, int parent)
@@ -3533,11 +3808,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 return; 3808 return;
3534 3809
3535 TaskInventoryItem item; 3810 TaskInventoryItem item;
3536 lock (m_host.TaskInventory) 3811 m_host.TaskInventory.LockItemsForRead(true);
3537 { 3812 item = m_host.TaskInventory[invItemID];
3538 item = m_host.TaskInventory[invItemID]; 3813 m_host.TaskInventory.LockItemsForRead(false);
3539 } 3814
3540
3541 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3815 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3542 && !m_automaticLinkPermission) 3816 && !m_automaticLinkPermission)
3543 { 3817 {
@@ -3590,16 +3864,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3590 m_host.AddScriptLPS(1); 3864 m_host.AddScriptLPS(1);
3591 UUID invItemID = InventorySelf(); 3865 UUID invItemID = InventorySelf();
3592 3866
3593 lock (m_host.TaskInventory) 3867 m_host.TaskInventory.LockItemsForRead(true);
3594 {
3595 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3868 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3596 && !m_automaticLinkPermission) 3869 && !m_automaticLinkPermission)
3597 { 3870 {
3598 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3871 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3872 m_host.TaskInventory.LockItemsForRead(false);
3599 return; 3873 return;
3600 } 3874 }
3601 } 3875 m_host.TaskInventory.LockItemsForRead(false);
3602 3876
3603 if (linknum < ScriptBaseClass.LINK_THIS) 3877 if (linknum < ScriptBaseClass.LINK_THIS)
3604 return; 3878 return;
3605 3879
@@ -3639,30 +3913,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 if (linknum == ScriptBaseClass.LINK_ROOT) 3913 if (linknum == ScriptBaseClass.LINK_ROOT)
3640 { 3914 {
3641 // Restructuring Multiple Prims. 3915 // Restructuring Multiple Prims.
3642 lock (parentPrim.Children) 3916 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3917 parts.Remove(parentPrim.RootPart);
3918 if (parts.Count > 0)
3643 { 3919 {
3644 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3920 try
3645 parts.Remove(parentPrim.RootPart);
3646 foreach (SceneObjectPart part in parts)
3647 { 3921 {
3648 parentPrim.DelinkFromGroup(part.LocalId, true); 3922 parts[0].ParentGroup.areUpdatesSuspended = true;
3923 foreach (SceneObjectPart part in parts)
3924 {
3925 parentPrim.DelinkFromGroup(part.LocalId, true);
3926 }
3649 } 3927 }
3650 parentPrim.HasGroupChanged = true; 3928 finally
3651 parentPrim.ScheduleGroupForFullUpdate(); 3929 {
3652 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3930 parts[0].ParentGroup.areUpdatesSuspended = false;
3653 3931 }
3654 if (parts.Count > 0) 3932 }
3933
3934 parentPrim.HasGroupChanged = true;
3935 parentPrim.ScheduleGroupForFullUpdate();
3936 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3937
3938 if (parts.Count > 0)
3939 {
3940 SceneObjectPart newRoot = parts[0];
3941 parts.Remove(newRoot);
3942
3943 try
3655 { 3944 {
3656 SceneObjectPart newRoot = parts[0]; 3945 parts[0].ParentGroup.areUpdatesSuspended = true;
3657 parts.Remove(newRoot);
3658 foreach (SceneObjectPart part in parts) 3946 foreach (SceneObjectPart part in parts)
3659 { 3947 {
3660 part.UpdateFlag = 0; 3948 part.UpdateFlag = 0;
3661 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3949 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3662 } 3950 }
3663 newRoot.ParentGroup.HasGroupChanged = true;
3664 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3665 } 3951 }
3952 finally
3953 {
3954 parts[0].ParentGroup.areUpdatesSuspended = false;
3955 }
3956
3957
3958 newRoot.ParentGroup.HasGroupChanged = true;
3959 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3666 } 3960 }
3667 } 3961 }
3668 else 3962 else
@@ -3709,6 +4003,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3709 } 4003 }
3710 else 4004 else
3711 { 4005 {
4006 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4007 {
4008 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4009
4010 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4011 if (avatars.Count > linknum)
4012 {
4013 return avatars[linknum].UUID.ToString();
4014 }
4015 }
3712 return UUID.Zero.ToString(); 4016 return UUID.Zero.ToString();
3713 } 4017 }
3714 } 4018 }
@@ -3785,17 +4089,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3785 m_host.AddScriptLPS(1); 4089 m_host.AddScriptLPS(1);
3786 int count = 0; 4090 int count = 0;
3787 4091
3788 lock (m_host.TaskInventory) 4092 m_host.TaskInventory.LockItemsForRead(true);
4093 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3789 { 4094 {
3790 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4095 if (inv.Value.Type == type || type == -1)
3791 { 4096 {
3792 if (inv.Value.Type == type || type == -1) 4097 count = count + 1;
3793 {
3794 count = count + 1;
3795 }
3796 } 4098 }
3797 } 4099 }
3798 4100
4101 m_host.TaskInventory.LockItemsForRead(false);
3799 return count; 4102 return count;
3800 } 4103 }
3801 4104
@@ -3804,16 +4107,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 m_host.AddScriptLPS(1); 4107 m_host.AddScriptLPS(1);
3805 ArrayList keys = new ArrayList(); 4108 ArrayList keys = new ArrayList();
3806 4109
3807 lock (m_host.TaskInventory) 4110 m_host.TaskInventory.LockItemsForRead(true);
4111 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3808 { 4112 {
3809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4113 if (inv.Value.Type == type || type == -1)
3810 { 4114 {
3811 if (inv.Value.Type == type || type == -1) 4115 keys.Add(inv.Value.Name);
3812 {
3813 keys.Add(inv.Value.Name);
3814 }
3815 } 4116 }
3816 } 4117 }
4118 m_host.TaskInventory.LockItemsForRead(false);
3817 4119
3818 if (keys.Count == 0) 4120 if (keys.Count == 0)
3819 { 4121 {
@@ -3850,20 +4152,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3850 } 4152 }
3851 4153
3852 // move the first object found with this inventory name 4154 // move the first object found with this inventory name
3853 lock (m_host.TaskInventory) 4155 m_host.TaskInventory.LockItemsForRead(true);
4156 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3854 { 4157 {
3855 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4158 if (inv.Value.Name == inventory)
3856 { 4159 {
3857 if (inv.Value.Name == inventory) 4160 found = true;
3858 { 4161 objId = inv.Key;
3859 found = true; 4162 assetType = inv.Value.Type;
3860 objId = inv.Key; 4163 objName = inv.Value.Name;
3861 assetType = inv.Value.Type; 4164 break;
3862 objName = inv.Value.Name;
3863 break;
3864 }
3865 } 4165 }
3866 } 4166 }
4167 m_host.TaskInventory.LockItemsForRead(false);
3867 4168
3868 if (!found) 4169 if (!found)
3869 { 4170 {
@@ -3871,9 +4172,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4172 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3872 } 4173 }
3873 4174
3874 // check if destination is an avatar 4175 // check if destination is an object
3875 if (World.GetScenePresence(destId) != null) 4176 if (World.GetSceneObjectPart(destId) != null)
4177 {
4178 // destination is an object
4179 World.MoveTaskInventoryItem(destId, m_host, objId);
4180 }
4181 else
3876 { 4182 {
4183 ScenePresence presence = World.GetScenePresence(destId);
4184
4185 if (presence == null)
4186 {
4187 UserAccount account =
4188 World.UserAccountService.GetUserAccount(
4189 World.RegionInfo.ScopeID,
4190 destId);
4191
4192 if (account == null)
4193 {
4194 llSay(0, "Can't find destination "+destId.ToString());
4195 return;
4196 }
4197 }
4198
3877 // destination is an avatar 4199 // destination is an avatar
3878 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4200 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3879 4201
@@ -3897,31 +4219,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 4219
3898 if (m_TransferModule != null) 4220 if (m_TransferModule != null)
3899 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4221 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4222
4223 //This delay should only occur when giving inventory to avatars.
4224 ScriptSleep(3000);
3900 } 4225 }
3901 else
3902 {
3903 // destination is an object
3904 World.MoveTaskInventoryItem(destId, m_host, objId);
3905 }
3906 ScriptSleep(3000);
3907 } 4226 }
3908 4227
4228 [DebuggerNonUserCode]
3909 public void llRemoveInventory(string name) 4229 public void llRemoveInventory(string name)
3910 { 4230 {
3911 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3912 4232
3913 lock (m_host.TaskInventory) 4233 List<TaskInventoryItem> inv;
4234 try
3914 { 4235 {
3915 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4236 m_host.TaskInventory.LockItemsForRead(true);
4237 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4238 }
4239 finally
4240 {
4241 m_host.TaskInventory.LockItemsForRead(false);
4242 }
4243 foreach (TaskInventoryItem item in inv)
4244 {
4245 if (item.Name == name)
3916 { 4246 {
3917 if (item.Name == name) 4247 if (item.ItemID == m_itemID)
3918 { 4248 throw new ScriptDeleteException();
3919 if (item.ItemID == m_itemID) 4249 else
3920 throw new ScriptDeleteException(); 4250 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3921 else 4251 return;
3922 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3923 return;
3924 }
3925 } 4252 }
3926 } 4253 }
3927 } 4254 }
@@ -3977,6 +4304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3977 ce.time = Util.EnvironmentTickCount(); 4304 ce.time = Util.EnvironmentTickCount();
3978 ce.account = account; 4305 ce.account = account;
3979 ce.pinfo = pinfo; 4306 ce.pinfo = pinfo;
4307 m_userInfoCache[uuid] = ce;
3980 } 4308 }
3981 else 4309 else
3982 { 4310 {
@@ -4040,6 +4368,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4040 { 4368 {
4041 m_host.AddScriptLPS(1); 4369 m_host.AddScriptLPS(1);
4042 4370
4371 //Clone is thread safe
4043 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4372 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4044 4373
4045 foreach (TaskInventoryItem item in itemDictionary.Values) 4374 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4093,6 +4422,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4093 ScenePresence presence = World.GetScenePresence(agentId); 4422 ScenePresence presence = World.GetScenePresence(agentId);
4094 if (presence != null) 4423 if (presence != null)
4095 { 4424 {
4425 // agent must not be a god
4426 if (presence.GodLevel >= 200) return;
4427
4096 // agent must be over the owners land 4428 // agent must be over the owners land
4097 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4429 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4098 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4430 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4152,17 +4484,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4152 UUID soundId = UUID.Zero; 4484 UUID soundId = UUID.Zero;
4153 if (!UUID.TryParse(impact_sound, out soundId)) 4485 if (!UUID.TryParse(impact_sound, out soundId))
4154 { 4486 {
4155 lock (m_host.TaskInventory) 4487 m_host.TaskInventory.LockItemsForRead(true);
4488 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4156 { 4489 {
4157 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4490 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4158 { 4491 {
4159 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4492 soundId = item.AssetID;
4160 { 4493 break;
4161 soundId = item.AssetID;
4162 break;
4163 }
4164 } 4494 }
4165 } 4495 }
4496 m_host.TaskInventory.LockItemsForRead(false);
4166 } 4497 }
4167 m_host.CollisionSound = soundId; 4498 m_host.CollisionSound = soundId;
4168 m_host.CollisionSoundVolume = (float)impact_volume; 4499 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4208,6 +4539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4208 UUID partItemID; 4539 UUID partItemID;
4209 foreach (SceneObjectPart part in parts) 4540 foreach (SceneObjectPart part in parts)
4210 { 4541 {
4542 //Clone is thread safe
4211 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4543 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4212 4544
4213 foreach (TaskInventoryItem item in itemsDictionary.Values) 4545 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4422,17 +4754,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4422 4754
4423 m_host.AddScriptLPS(1); 4755 m_host.AddScriptLPS(1);
4424 4756
4425 lock (m_host.TaskInventory) 4757 m_host.TaskInventory.LockItemsForRead(true);
4758 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4426 { 4759 {
4427 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4760 if (item.Type == 10 && item.ItemID == m_itemID)
4428 { 4761 {
4429 if (item.Type == 10 && item.ItemID == m_itemID) 4762 result = item.Name!=null?item.Name:String.Empty;
4430 { 4763 break;
4431 result = item.Name != null ? item.Name : String.Empty;
4432 break;
4433 }
4434 } 4764 }
4435 } 4765 }
4766 m_host.TaskInventory.LockItemsForRead(false);
4436 4767
4437 return result; 4768 return result;
4438 } 4769 }
@@ -4585,23 +4916,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4585 { 4916 {
4586 m_host.AddScriptLPS(1); 4917 m_host.AddScriptLPS(1);
4587 4918
4588 lock (m_host.TaskInventory) 4919 m_host.TaskInventory.LockItemsForRead(true);
4920 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4589 { 4921 {
4590 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4922 if (inv.Value.Name == name)
4591 { 4923 {
4592 if (inv.Value.Name == name) 4924 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4593 { 4925 {
4594 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4926 m_host.TaskInventory.LockItemsForRead(false);
4595 { 4927 return inv.Value.AssetID.ToString();
4596 return inv.Value.AssetID.ToString(); 4928 }
4597 } 4929 else
4598 else 4930 {
4599 { 4931 m_host.TaskInventory.LockItemsForRead(false);
4600 return UUID.Zero.ToString(); 4932 return UUID.Zero.ToString();
4601 }
4602 } 4933 }
4603 } 4934 }
4604 } 4935 }
4936 m_host.TaskInventory.LockItemsForRead(false);
4605 4937
4606 return UUID.Zero.ToString(); 4938 return UUID.Zero.ToString();
4607 } 4939 }
@@ -4754,14 +5086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4754 { 5086 {
4755 m_host.AddScriptLPS(1); 5087 m_host.AddScriptLPS(1);
4756 5088
4757 if (src == null) 5089 return src.Length;
4758 {
4759 return 0;
4760 }
4761 else
4762 {
4763 return src.Length;
4764 }
4765 } 5090 }
4766 5091
4767 public LSL_Integer llList2Integer(LSL_List src, int index) 5092 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4807,7 +5132,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4807 else if (src.Data[index] is LSL_Float) 5132 else if (src.Data[index] is LSL_Float)
4808 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5133 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4809 else if (src.Data[index] is LSL_String) 5134 else if (src.Data[index] is LSL_String)
4810 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5135 {
5136 string str = ((LSL_String) src.Data[index]).m_string;
5137 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5138 if (m != Match.Empty)
5139 {
5140 str = m.Value;
5141 double d = 0.0;
5142 if (!Double.TryParse(str, out d))
5143 return 0.0;
5144
5145 return d;
5146 }
5147 return 0.0;
5148 }
4811 return Convert.ToDouble(src.Data[index]); 5149 return Convert.ToDouble(src.Data[index]);
4812 } 5150 }
4813 catch (FormatException) 5151 catch (FormatException)
@@ -5492,7 +5830,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5492 public void llSetSoundQueueing(int queue) 5830 public void llSetSoundQueueing(int queue)
5493 { 5831 {
5494 m_host.AddScriptLPS(1); 5832 m_host.AddScriptLPS(1);
5495 NotImplemented("llSetSoundQueueing");
5496 } 5833 }
5497 5834
5498 public void llSetSoundRadius(double radius) 5835 public void llSetSoundRadius(double radius)
@@ -5537,10 +5874,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5537 m_host.AddScriptLPS(1); 5874 m_host.AddScriptLPS(1);
5538 5875
5539 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5876 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5540 5877 if (parts.Count > 0)
5541 foreach (var part in parts)
5542 { 5878 {
5543 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5879 try
5880 {
5881 parts[0].ParentGroup.areUpdatesSuspended = true;
5882 foreach (var part in parts)
5883 {
5884 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5885 }
5886 }
5887 finally
5888 {
5889 parts[0].ParentGroup.areUpdatesSuspended = false;
5890 }
5544 } 5891 }
5545 } 5892 }
5546 5893
@@ -5596,74 +5943,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5596 5943
5597 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5944 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5598 { 5945 {
5599 m_host.AddScriptLPS(1); 5946 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 } 5947 }
5668 5948
5669 public LSL_Integer llOverMyLand(string id) 5949 public LSL_Integer llOverMyLand(string id)
@@ -5866,7 +6146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5866 return m_host.ParentGroup.RootPart.AttachmentPoint; 6146 return m_host.ParentGroup.RootPart.AttachmentPoint;
5867 } 6147 }
5868 6148
5869 public LSL_Integer llGetFreeMemory() 6149 public virtual LSL_Integer llGetFreeMemory()
5870 { 6150 {
5871 m_host.AddScriptLPS(1); 6151 m_host.AddScriptLPS(1);
5872 // Make scripts designed for LSO happy 6152 // Make scripts designed for LSO happy
@@ -6177,14 +6457,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6177 6457
6178 protected UUID GetTaskInventoryItem(string name) 6458 protected UUID GetTaskInventoryItem(string name)
6179 { 6459 {
6180 lock (m_host.TaskInventory) 6460 m_host.TaskInventory.LockItemsForRead(true);
6461 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6181 { 6462 {
6182 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6463 if (inv.Value.Name == name)
6183 { 6464 {
6184 if (inv.Value.Name == name) 6465 m_host.TaskInventory.LockItemsForRead(false);
6185 return inv.Key; 6466 return inv.Key;
6186 } 6467 }
6187 } 6468 }
6469 m_host.TaskInventory.LockItemsForRead(false);
6188 6470
6189 return UUID.Zero; 6471 return UUID.Zero;
6190 } 6472 }
@@ -6512,22 +6794,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6512 } 6794 }
6513 6795
6514 // copy the first script found with this inventory name 6796 // copy the first script found with this inventory name
6515 lock (m_host.TaskInventory) 6797 m_host.TaskInventory.LockItemsForRead(true);
6798 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6516 { 6799 {
6517 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6800 if (inv.Value.Name == name)
6518 { 6801 {
6519 if (inv.Value.Name == name) 6802 // make sure the object is a script
6803 if (10 == inv.Value.Type)
6520 { 6804 {
6521 // make sure the object is a script 6805 found = true;
6522 if (10 == inv.Value.Type) 6806 srcId = inv.Key;
6523 { 6807 break;
6524 found = true;
6525 srcId = inv.Key;
6526 break;
6527 }
6528 } 6808 }
6529 } 6809 }
6530 } 6810 }
6811 m_host.TaskInventory.LockItemsForRead(false);
6531 6812
6532 if (!found) 6813 if (!found)
6533 { 6814 {
@@ -6611,6 +6892,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6611 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6892 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6612 { 6893 {
6613 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6894 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6895 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6896 return shapeBlock;
6614 6897
6615 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6898 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6616 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6899 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6686,6 +6969,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6686 6969
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) 6970 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 { 6971 {
6972 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6973 return;
6974
6689 ObjectShapePacket.ObjectDataBlock shapeBlock; 6975 ObjectShapePacket.ObjectDataBlock shapeBlock;
6690 6976
6691 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6977 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6735,6 +7021,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6735 7021
6736 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7022 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6737 { 7023 {
7024 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7025 return;
7026
6738 ObjectShapePacket.ObjectDataBlock shapeBlock; 7027 ObjectShapePacket.ObjectDataBlock shapeBlock;
6739 7028
6740 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7029 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6777,6 +7066,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6777 7066
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) 7067 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 { 7068 {
7069 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7070 return;
7071
6780 ObjectShapePacket.ObjectDataBlock shapeBlock; 7072 ObjectShapePacket.ObjectDataBlock shapeBlock;
6781 7073
6782 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7074 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6903,6 +7195,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6903 7195
6904 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7196 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6905 { 7197 {
7198 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7199 return;
7200
6906 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7201 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6907 UUID sculptId; 7202 UUID sculptId;
6908 7203
@@ -6918,13 +7213,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6918 shapeBlock.PathScaleX = 100; 7213 shapeBlock.PathScaleX = 100;
6919 shapeBlock.PathScaleY = 150; 7214 shapeBlock.PathScaleY = 150;
6920 7215
6921 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7216 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6922 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7217 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6923 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7218 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6924 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7219 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6925 { 7220 {
6926 // default 7221 // default
6927 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7222 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6928 } 7223 }
6929 7224
6930 // retain pathcurve 7225 // retain pathcurve
@@ -6941,23 +7236,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 SetPrimParams(m_host, rules); 7236 SetPrimParams(m_host, rules);
6942 } 7237 }
6943 7238
6944 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7239 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6945 { 7240 {
6946 m_host.AddScriptLPS(1); 7241 m_host.AddScriptLPS(1);
6947 7242
6948 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7243 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7244 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7245 if (parts.Count>0)
7246 {
7247 try
7248 {
7249 parts[0].ParentGroup.areUpdatesSuspended = true;
7250 foreach (SceneObjectPart part in parts)
7251 SetPrimParams(part, rules);
7252 }
7253 finally
7254 {
7255 parts[0].ParentGroup.areUpdatesSuspended = false;
7256 }
7257 }
7258 if (avatars.Count > 0)
7259 {
7260 foreach (ScenePresence avatar in avatars)
7261 SetPrimParams(avatar, rules);
7262 }
7263 }
6949 7264
6950 foreach (SceneObjectPart part in parts) 7265 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6951 SetPrimParams(part, rules); 7266 {
7267 llSetLinkPrimitiveParamsFast(linknumber, rules);
7268 ScriptSleep(200);
6952 } 7269 }
6953 7270
6954 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7271 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6955 { 7272 {
6956 llSetLinkPrimitiveParams(linknumber, rules); 7273 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7274 //We only support PRIM_POSITION and PRIM_ROTATION
7275
7276 int idx = 0;
7277
7278 while (idx < rules.Length)
7279 {
7280 int code = rules.GetLSLIntegerItem(idx++);
7281
7282 int remain = rules.Length - idx;
7283
7284
7285
7286 switch (code)
7287 {
7288 case (int)ScriptBaseClass.PRIM_POSITION:
7289 if (remain < 1)
7290 return;
7291 LSL_Vector v;
7292 v = rules.GetVector3Item(idx++);
7293 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7294 av.SendFullUpdateToAllClients();
7295
7296 break;
7297
7298 case (int)ScriptBaseClass.PRIM_ROTATION:
7299 if (remain < 1)
7300 return;
7301 LSL_Rotation r;
7302 r = rules.GetQuaternionItem(idx++);
7303 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7304 av.SendFullUpdateToAllClients();
7305 break;
7306 }
7307 }
7308
6957 } 7309 }
6958 7310
6959 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7311 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6960 { 7312 {
7313 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7314 return;
7315
6961 int idx = 0; 7316 int idx = 0;
6962 7317
6963 while (idx < rules.Length) 7318 while (idx < rules.Length)
@@ -7474,13 +7829,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7474 public LSL_Integer llGetNumberOfPrims() 7829 public LSL_Integer llGetNumberOfPrims()
7475 { 7830 {
7476 m_host.AddScriptLPS(1); 7831 m_host.AddScriptLPS(1);
7477 int avatarCount = 0; 7832 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7478 World.ForEachScenePresence(delegate(ScenePresence presence) 7833
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; 7834 return m_host.ParentGroup.PrimCount + avatarCount;
7485 } 7835 }
7486 7836
@@ -7496,55 +7846,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7496 m_host.AddScriptLPS(1); 7846 m_host.AddScriptLPS(1);
7497 UUID objID = UUID.Zero; 7847 UUID objID = UUID.Zero;
7498 LSL_List result = new LSL_List(); 7848 LSL_List result = new LSL_List();
7849
7850 // If the ID is not valid, return null result
7499 if (!UUID.TryParse(obj, out objID)) 7851 if (!UUID.TryParse(obj, out objID))
7500 { 7852 {
7501 result.Add(new LSL_Vector()); 7853 result.Add(new LSL_Vector());
7502 result.Add(new LSL_Vector()); 7854 result.Add(new LSL_Vector());
7503 return result; 7855 return result;
7504 } 7856 }
7857
7858 // Check if this is an attached prim. If so, replace
7859 // the UUID with the avatar UUID and report it's bounding box
7860 SceneObjectPart part = World.GetSceneObjectPart(objID);
7861 if (part != null && part.ParentGroup.IsAttachment)
7862 objID = part.ParentGroup.RootPart.AttachedAvatar;
7863
7864 // Find out if this is an avatar ID. If so, return it's box
7505 ScenePresence presence = World.GetScenePresence(objID); 7865 ScenePresence presence = World.GetScenePresence(objID);
7506 if (presence != null) 7866 if (presence != null)
7507 { 7867 {
7508 if (presence.ParentID == 0) // not sat on an object 7868 // As per LSL Wiki, there is no difference between sitting
7869 // and standing avatar since server 1.36
7870 LSL_Vector lower;
7871 LSL_Vector upper;
7872 if (presence.Animator.Animations.DefaultAnimation.AnimID
7873 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7509 { 7874 {
7510 LSL_Vector lower; 7875 // This is for ground sitting avatars
7511 LSL_Vector upper; 7876 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7512 if (presence.Animator.Animations.DefaultAnimation.AnimID 7877 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7513 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7878 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 } 7879 }
7531 else 7880 else
7532 { 7881 {
7533 // sitting on an object so we need the bounding box of that 7882 // This is for standing/flying avatars
7534 // which should include the avatar so set the UUID to the 7883 float height = presence.Appearance.AvatarHeight / 2.0f;
7535 // UUID of the object the avatar is sat on and allow it to fall through 7884 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7536 // to processing an object 7885 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7537 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7538 objID = p.UUID;
7539 } 7886 }
7887
7888 // Adjust to the documented error offsets (see LSL Wiki)
7889 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7890 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7891
7892 if (lower.x > upper.x)
7893 lower.x = upper.x;
7894 if (lower.y > upper.y)
7895 lower.y = upper.y;
7896 if (lower.z > upper.z)
7897 lower.z = upper.z;
7898
7899 result.Add(lower);
7900 result.Add(upper);
7901 return result;
7540 } 7902 }
7541 SceneObjectPart part = World.GetSceneObjectPart(objID); 7903
7904 part = World.GetSceneObjectPart(objID);
7542 // Currently only works for single prims without a sitting avatar 7905 // Currently only works for single prims without a sitting avatar
7543 if (part != null) 7906 if (part != null)
7544 { 7907 {
7545 Vector3 halfSize = part.Scale / 2.0f; 7908 float minX;
7546 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7909 float maxX;
7547 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7910 float minY;
7911 float maxY;
7912 float minZ;
7913 float maxZ;
7914
7915 // This BBox is in sim coordinates, with the offset being
7916 // a contained point.
7917 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7918 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7919
7920 minX -= offsets[0].X;
7921 maxX -= offsets[0].X;
7922 minY -= offsets[0].Y;
7923 maxY -= offsets[0].Y;
7924 minZ -= offsets[0].Z;
7925 maxZ -= offsets[0].Z;
7926
7927 LSL_Vector lower;
7928 LSL_Vector upper;
7929
7930 // Adjust to the documented error offsets (see LSL Wiki)
7931 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7932 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7933
7934 if (lower.x > upper.x)
7935 lower.x = upper.x;
7936 if (lower.y > upper.y)
7937 lower.y = upper.y;
7938 if (lower.z > upper.z)
7939 lower.z = upper.z;
7940
7548 result.Add(lower); 7941 result.Add(lower);
7549 result.Add(upper); 7942 result.Add(upper);
7550 return result; 7943 return result;
@@ -7789,24 +8182,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7789 break; 8182 break;
7790 8183
7791 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8184 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7792 // TODO--------------
7793 if (remain < 1) 8185 if (remain < 1)
7794 return res; 8186 return res;
8187 face = (int)rules.GetLSLIntegerItem(idx++);
7795 8188
7796 face=(int)rules.GetLSLIntegerItem(idx++); 8189 tex = part.Shape.Textures;
7797 8190 int shiny;
7798 res.Add(new LSL_Integer(0)); 8191 if (face == ScriptBaseClass.ALL_SIDES)
7799 res.Add(new LSL_Integer(0)); 8192 {
8193 for (face = 0; face < GetNumberOfSides(part); face++)
8194 {
8195 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8196 if (shinyness == Shininess.High)
8197 {
8198 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8199 }
8200 else if (shinyness == Shininess.Medium)
8201 {
8202 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8203 }
8204 else if (shinyness == Shininess.Low)
8205 {
8206 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8207 }
8208 else
8209 {
8210 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8211 }
8212 res.Add(new LSL_Integer(shiny));
8213 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8214 }
8215 }
8216 else
8217 {
8218 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8219 if (shinyness == Shininess.High)
8220 {
8221 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8222 }
8223 else if (shinyness == Shininess.Medium)
8224 {
8225 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8226 }
8227 else if (shinyness == Shininess.Low)
8228 {
8229 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8230 }
8231 else
8232 {
8233 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8234 }
8235 res.Add(new LSL_Integer(shiny));
8236 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8237 }
7800 break; 8238 break;
7801 8239
7802 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8240 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7803 // TODO--------------
7804 if (remain < 1) 8241 if (remain < 1)
7805 return res; 8242 return res;
8243 face = (int)rules.GetLSLIntegerItem(idx++);
7806 8244
7807 face=(int)rules.GetLSLIntegerItem(idx++); 8245 tex = part.Shape.Textures;
7808 8246 int fullbright;
7809 res.Add(new LSL_Integer(0)); 8247 if (face == ScriptBaseClass.ALL_SIDES)
8248 {
8249 for (face = 0; face < GetNumberOfSides(part); face++)
8250 {
8251 if (tex.GetFace((uint)face).Fullbright == true)
8252 {
8253 fullbright = ScriptBaseClass.TRUE;
8254 }
8255 else
8256 {
8257 fullbright = ScriptBaseClass.FALSE;
8258 }
8259 res.Add(new LSL_Integer(fullbright));
8260 }
8261 }
8262 else
8263 {
8264 if (tex.GetFace((uint)face).Fullbright == true)
8265 {
8266 fullbright = ScriptBaseClass.TRUE;
8267 }
8268 else
8269 {
8270 fullbright = ScriptBaseClass.FALSE;
8271 }
8272 res.Add(new LSL_Integer(fullbright));
8273 }
7810 break; 8274 break;
7811 8275
7812 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8276 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7827,14 +8291,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7827 break; 8291 break;
7828 8292
7829 case (int)ScriptBaseClass.PRIM_TEXGEN: 8293 case (int)ScriptBaseClass.PRIM_TEXGEN:
7830 // TODO--------------
7831 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8294 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7832 if (remain < 1) 8295 if (remain < 1)
7833 return res; 8296 return res;
8297 face = (int)rules.GetLSLIntegerItem(idx++);
7834 8298
7835 face=(int)rules.GetLSLIntegerItem(idx++); 8299 tex = part.Shape.Textures;
7836 8300 if (face == ScriptBaseClass.ALL_SIDES)
7837 res.Add(new LSL_Integer(0)); 8301 {
8302 for (face = 0; face < GetNumberOfSides(part); face++)
8303 {
8304 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8305 {
8306 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8307 }
8308 else
8309 {
8310 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8311 }
8312 }
8313 }
8314 else
8315 {
8316 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8317 {
8318 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8319 }
8320 else
8321 {
8322 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8323 }
8324 }
7838 break; 8325 break;
7839 8326
7840 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8327 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7853,13 +8340,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7853 break; 8340 break;
7854 8341
7855 case (int)ScriptBaseClass.PRIM_GLOW: 8342 case (int)ScriptBaseClass.PRIM_GLOW:
7856 // TODO--------------
7857 if (remain < 1) 8343 if (remain < 1)
7858 return res; 8344 return res;
8345 face = (int)rules.GetLSLIntegerItem(idx++);
7859 8346
7860 face=(int)rules.GetLSLIntegerItem(idx++); 8347 tex = part.Shape.Textures;
7861 8348 float primglow;
7862 res.Add(new LSL_Float(0)); 8349 if (face == ScriptBaseClass.ALL_SIDES)
8350 {
8351 for (face = 0; face < GetNumberOfSides(part); face++)
8352 {
8353 primglow = tex.GetFace((uint)face).Glow;
8354 res.Add(new LSL_Float(primglow));
8355 }
8356 }
8357 else
8358 {
8359 primglow = tex.GetFace((uint)face).Glow;
8360 res.Add(new LSL_Float(primglow));
8361 }
7863 break; 8362 break;
7864 case (int)ScriptBaseClass.PRIM_TEXT: 8363 case (int)ScriptBaseClass.PRIM_TEXT:
7865 Color4 textColor = part.GetTextColor(); 8364 Color4 textColor = part.GetTextColor();
@@ -8400,8 +8899,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8400 // The function returns an ordered list 8899 // The function returns an ordered list
8401 // representing the tokens found in the supplied 8900 // representing the tokens found in the supplied
8402 // sources string. If two successive tokenizers 8901 // sources string. If two successive tokenizers
8403 // are encountered, then a NULL entry is added 8902 // are encountered, then a null-string entry is
8404 // to the list. 8903 // added to the list.
8405 // 8904 //
8406 // It is a precondition that the source and 8905 // It is a precondition that the source and
8407 // toekizer lisst are non-null. If they are null, 8906 // toekizer lisst are non-null. If they are null,
@@ -8409,7 +8908,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8409 // while their lengths are being determined. 8908 // while their lengths are being determined.
8410 // 8909 //
8411 // A small amount of working memoryis required 8910 // A small amount of working memoryis required
8412 // of approximately 8*#tokenizers. 8911 // of approximately 8*#tokenizers + 8*srcstrlen.
8413 // 8912 //
8414 // There are many ways in which this function 8913 // There are many ways in which this function
8415 // can be implemented, this implementation is 8914 // can be implemented, this implementation is
@@ -8425,136 +8924,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8425 // and eliminates redundant tokenizers as soon 8924 // and eliminates redundant tokenizers as soon
8426 // as is possible. 8925 // as is possible.
8427 // 8926 //
8428 // The implementation tries to avoid any copying 8927 // The implementation tries to minimize temporary
8429 // of arrays or other objects. 8928 // garbage generation.
8430 // </remarks> 8929 // </remarks>
8431 8930
8432 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8931 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8433 { 8932 {
8434 int beginning = 0; 8933 return ParseString2List(src, separators, spacers, true);
8435 int srclen = src.Length; 8934 }
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 8935
8445 int best; 8936 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8446 int j; 8937 {
8938 int srclen = src.Length;
8939 int seplen = separators.Length;
8940 object[] separray = separators.Data;
8941 int spclen = spacers.Length;
8942 object[] spcarray = spacers.Data;
8943 int dellen = 0;
8944 string[] delarray = new string[seplen+spclen];
8447 8945
8448 // Initial capacity reduces resize cost 8946 int outlen = 0;
8947 string[] outarray = new string[srclen*2+1];
8449 8948
8450 LSL_List tokens = new LSL_List(); 8949 int i, j;
8950 string d;
8451 8951
8452 m_host.AddScriptLPS(1); 8952 m_host.AddScriptLPS(1);
8453 8953
8454 // All entries are initially valid 8954 /*
8455 8955 * Convert separator and spacer lists to C# strings.
8456 for (int i = 0; i < mlen; i++) 8956 * Also filter out null strings so we don't hang.
8457 active[i] = true; 8957 */
8458 8958 for (i = 0; i < seplen; i ++) {
8459 offset[mlen] = srclen; 8959 d = separray[i].ToString();
8460 8960 if (d.Length > 0) {
8461 while (beginning < srclen) 8961 delarray[dellen++] = d;
8462 { 8962 }
8463 8963 }
8464 best = mlen; // as bad as it gets 8964 seplen = dellen;
8465
8466 // Scan for separators
8467 8965
8468 for (j = 0; j < seplen; j++) 8966 for (i = 0; i < spclen; i ++) {
8469 { 8967 d = spcarray[i].ToString();
8470 if (active[j]) 8968 if (d.Length > 0) {
8471 { 8969 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 } 8970 }
8971 }
8491 8972
8492 // Scan for spacers 8973 /*
8974 * Scan through source string from beginning to end.
8975 */
8976 for (i = 0;;) {
8493 8977
8494 if (offset[best] != beginning) 8978 /*
8495 { 8979 * Find earliest delimeter in src starting at i (if any).
8496 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8980 */
8497 { 8981 int earliestDel = -1;
8498 if (active[j]) 8982 int earliestSrc = srclen;
8499 { 8983 string earliestStr = null;
8500 // scan all of the markers 8984 for (j = 0; j < dellen; j ++) {
8501 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8985 d = delarray[j];
8502 { 8986 if (d != null) {
8503 // not present at all 8987 int index = src.IndexOf(d, i);
8504 active[j] = false; 8988 if (index < 0) {
8505 } 8989 delarray[j] = null; // delim nowhere in src, don't check it anymore
8506 else 8990 } else if (index < earliestSrc) {
8507 { 8991 earliestSrc = index; // where delimeter starts in source string
8508 // present and correct 8992 earliestDel = j; // where delimeter is in delarray[]
8509 if (offset[j] < offset[best]) 8993 earliestStr = d; // the delimeter string from delarray[]
8510 { 8994 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 } 8995 }
8516 } 8996 }
8517 } 8997 }
8518 8998
8519 // This is the normal exit from the scanning loop 8999 /*
8520 9000 * Output source string starting at i through start of earliest delimeter.
8521 if (best == mlen) 9001 */
8522 { 9002 if (keepNulls || (earliestSrc > i)) {
8523 // no markers were found on this pass 9003 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 } 9004 }
8528 9005
8529 // Otherwise we just add the newly delimited token 9006 /*
8530 // and recalculate where the search should continue. 9007 * If no delimeter found at or after i, we're done scanning.
8531 9008 */
8532 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9009 if (earliestDel < 0) break;
8533 9010
8534 if (best < seplen) 9011 /*
8535 { 9012 * If delimeter was a spacer, output the spacer.
8536 beginning = offset[best] + (separray[best].ToString()).Length; 9013 */
8537 } 9014 if (earliestDel >= seplen) {
8538 else 9015 outarray[outlen++] = earliestStr;
8539 {
8540 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8541 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8542 } 9016 }
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 9017
8551 if (beginning == srclen) 9018 /*
8552 { 9019 * Look at rest of src string following delimeter.
8553 if (srclen != 0) 9020 */
8554 tokens.Add(new LSL_String("")); 9021 i = earliestSrc + earliestStr.Length;
8555 } 9022 }
8556 9023
8557 return tokens; 9024 /*
9025 * Make up an exact-sized output array suitable for an LSL_List object.
9026 */
9027 object[] outlist = new object[outlen];
9028 for (i = 0; i < outlen; i ++) {
9029 outlist[i] = new LSL_String(outarray[i]);
9030 }
9031 return new LSL_List(outlist);
8558 } 9032 }
8559 9033
8560 public LSL_Integer llGetObjectPermMask(int mask) 9034 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8631,28 +9105,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8631 { 9105 {
8632 m_host.AddScriptLPS(1); 9106 m_host.AddScriptLPS(1);
8633 9107
8634 lock (m_host.TaskInventory) 9108 m_host.TaskInventory.LockItemsForRead(true);
9109 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8635 { 9110 {
8636 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9111 if (inv.Value.Name == item)
8637 { 9112 {
8638 if (inv.Value.Name == item) 9113 m_host.TaskInventory.LockItemsForRead(false);
9114 switch (mask)
8639 { 9115 {
8640 switch (mask) 9116 case 0:
8641 { 9117 return (int)inv.Value.BasePermissions;
8642 case 0: 9118 case 1:
8643 return (int)inv.Value.BasePermissions; 9119 return (int)inv.Value.CurrentPermissions;
8644 case 1: 9120 case 2:
8645 return (int)inv.Value.CurrentPermissions; 9121 return (int)inv.Value.GroupPermissions;
8646 case 2: 9122 case 3:
8647 return (int)inv.Value.GroupPermissions; 9123 return (int)inv.Value.EveryonePermissions;
8648 case 3: 9124 case 4:
8649 return (int)inv.Value.EveryonePermissions; 9125 return (int)inv.Value.NextPermissions;
8650 case 4:
8651 return (int)inv.Value.NextPermissions;
8652 }
8653 } 9126 }
8654 } 9127 }
8655 } 9128 }
9129 m_host.TaskInventory.LockItemsForRead(false);
8656 9130
8657 return -1; 9131 return -1;
8658 } 9132 }
@@ -8699,16 +9173,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8699 { 9173 {
8700 m_host.AddScriptLPS(1); 9174 m_host.AddScriptLPS(1);
8701 9175
8702 lock (m_host.TaskInventory) 9176 m_host.TaskInventory.LockItemsForRead(true);
9177 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8703 { 9178 {
8704 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9179 if (inv.Value.Name == item)
8705 { 9180 {
8706 if (inv.Value.Name == item) 9181 m_host.TaskInventory.LockItemsForRead(false);
8707 { 9182 return inv.Value.CreatorID.ToString();
8708 return inv.Value.CreatorID.ToString();
8709 }
8710 } 9183 }
8711 } 9184 }
9185 m_host.TaskInventory.LockItemsForRead(false);
8712 9186
8713 llSay(0, "No item name '" + item + "'"); 9187 llSay(0, "No item name '" + item + "'");
8714 9188
@@ -8759,8 +9233,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8759 return UUID.Zero.ToString(); 9233 return UUID.Zero.ToString();
8760 } 9234 }
8761 reply = new LSL_Vector( 9235 reply = new LSL_Vector(
8762 info.RegionLocX * Constants.RegionSize, 9236 info.RegionLocX,
8763 info.RegionLocY * Constants.RegionSize, 9237 info.RegionLocY,
8764 0).ToString(); 9238 0).ToString();
8765 break; 9239 break;
8766 case 6: // DATA_SIM_STATUS 9240 case 6: // DATA_SIM_STATUS
@@ -8973,17 +9447,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8973 int width = 0; 9447 int width = 0;
8974 int height = 0; 9448 int height = 0;
8975 9449
8976 ParcelMediaCommandEnum? commandToSend = null; 9450 uint commandToSend = 0;
8977 float time = 0.0f; // default is from start 9451 float time = 0.0f; // default is from start
8978 9452
8979 ScenePresence presence = null; 9453 ScenePresence presence = null;
8980 9454
8981 for (int i = 0; i < commandList.Data.Length; i++) 9455 for (int i = 0; i < commandList.Data.Length; i++)
8982 { 9456 {
8983 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9457 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8984 switch (command) 9458 switch (command)
8985 { 9459 {
8986 case ParcelMediaCommandEnum.Agent: 9460 case (uint)ParcelMediaCommandEnum.Agent:
8987 // we send only to one agent 9461 // we send only to one agent
8988 if ((i + 1) < commandList.Length) 9462 if ((i + 1) < commandList.Length)
8989 { 9463 {
@@ -9000,25 +9474,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9000 } 9474 }
9001 break; 9475 break;
9002 9476
9003 case ParcelMediaCommandEnum.Loop: 9477 case (uint)ParcelMediaCommandEnum.Loop:
9004 loop = 1; 9478 loop = 1;
9005 commandToSend = command; 9479 commandToSend = command;
9006 update = true; //need to send the media update packet to set looping 9480 update = true; //need to send the media update packet to set looping
9007 break; 9481 break;
9008 9482
9009 case ParcelMediaCommandEnum.Play: 9483 case (uint)ParcelMediaCommandEnum.Play:
9010 loop = 0; 9484 loop = 0;
9011 commandToSend = command; 9485 commandToSend = command;
9012 update = true; //need to send the media update packet to make sure it doesn't loop 9486 update = true; //need to send the media update packet to make sure it doesn't loop
9013 break; 9487 break;
9014 9488
9015 case ParcelMediaCommandEnum.Pause: 9489 case (uint)ParcelMediaCommandEnum.Pause:
9016 case ParcelMediaCommandEnum.Stop: 9490 case (uint)ParcelMediaCommandEnum.Stop:
9017 case ParcelMediaCommandEnum.Unload: 9491 case (uint)ParcelMediaCommandEnum.Unload:
9018 commandToSend = command; 9492 commandToSend = command;
9019 break; 9493 break;
9020 9494
9021 case ParcelMediaCommandEnum.Url: 9495 case (uint)ParcelMediaCommandEnum.Url:
9022 if ((i + 1) < commandList.Length) 9496 if ((i + 1) < commandList.Length)
9023 { 9497 {
9024 if (commandList.Data[i + 1] is LSL_String) 9498 if (commandList.Data[i + 1] is LSL_String)
@@ -9031,7 +9505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9031 } 9505 }
9032 break; 9506 break;
9033 9507
9034 case ParcelMediaCommandEnum.Texture: 9508 case (uint)ParcelMediaCommandEnum.Texture:
9035 if ((i + 1) < commandList.Length) 9509 if ((i + 1) < commandList.Length)
9036 { 9510 {
9037 if (commandList.Data[i + 1] is LSL_String) 9511 if (commandList.Data[i + 1] is LSL_String)
@@ -9044,7 +9518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9044 } 9518 }
9045 break; 9519 break;
9046 9520
9047 case ParcelMediaCommandEnum.Time: 9521 case (uint)ParcelMediaCommandEnum.Time:
9048 if ((i + 1) < commandList.Length) 9522 if ((i + 1) < commandList.Length)
9049 { 9523 {
9050 if (commandList.Data[i + 1] is LSL_Float) 9524 if (commandList.Data[i + 1] is LSL_Float)
@@ -9056,7 +9530,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9056 } 9530 }
9057 break; 9531 break;
9058 9532
9059 case ParcelMediaCommandEnum.AutoAlign: 9533 case (uint)ParcelMediaCommandEnum.AutoAlign:
9060 if ((i + 1) < commandList.Length) 9534 if ((i + 1) < commandList.Length)
9061 { 9535 {
9062 if (commandList.Data[i + 1] is LSL_Integer) 9536 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9070,7 +9544,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9070 } 9544 }
9071 break; 9545 break;
9072 9546
9073 case ParcelMediaCommandEnum.Type: 9547 case (uint)ParcelMediaCommandEnum.Type:
9074 if ((i + 1) < commandList.Length) 9548 if ((i + 1) < commandList.Length)
9075 { 9549 {
9076 if (commandList.Data[i + 1] is LSL_String) 9550 if (commandList.Data[i + 1] is LSL_String)
@@ -9083,7 +9557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9083 } 9557 }
9084 break; 9558 break;
9085 9559
9086 case ParcelMediaCommandEnum.Desc: 9560 case (uint)ParcelMediaCommandEnum.Desc:
9087 if ((i + 1) < commandList.Length) 9561 if ((i + 1) < commandList.Length)
9088 { 9562 {
9089 if (commandList.Data[i + 1] is LSL_String) 9563 if (commandList.Data[i + 1] is LSL_String)
@@ -9096,7 +9570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9096 } 9570 }
9097 break; 9571 break;
9098 9572
9099 case ParcelMediaCommandEnum.Size: 9573 case (uint)ParcelMediaCommandEnum.Size:
9100 if ((i + 2) < commandList.Length) 9574 if ((i + 2) < commandList.Length)
9101 { 9575 {
9102 if (commandList.Data[i + 1] is LSL_Integer) 9576 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9166,7 +9640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 } 9640 }
9167 } 9641 }
9168 9642
9169 if (commandToSend != null) 9643 if (commandToSend != 0)
9170 { 9644 {
9171 // the commandList contained a start/stop/... command, too 9645 // the commandList contained a start/stop/... command, too
9172 if (presence == null) 9646 if (presence == null)
@@ -9203,7 +9677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9203 9677
9204 if (aList.Data[i] != null) 9678 if (aList.Data[i] != null)
9205 { 9679 {
9206 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9680 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9207 { 9681 {
9208 case ParcelMediaCommandEnum.Url: 9682 case ParcelMediaCommandEnum.Url:
9209 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9683 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9246,16 +9720,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 { 9720 {
9247 m_host.AddScriptLPS(1); 9721 m_host.AddScriptLPS(1);
9248 9722
9249 lock (m_host.TaskInventory) 9723 m_host.TaskInventory.LockItemsForRead(true);
9724 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9250 { 9725 {
9251 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9726 if (inv.Value.Name == name)
9252 { 9727 {
9253 if (inv.Value.Name == name) 9728 m_host.TaskInventory.LockItemsForRead(false);
9254 { 9729 return inv.Value.Type;
9255 return inv.Value.Type;
9256 }
9257 } 9730 }
9258 } 9731 }
9732 m_host.TaskInventory.LockItemsForRead(false);
9259 9733
9260 return -1; 9734 return -1;
9261 } 9735 }
@@ -9266,15 +9740,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 9740
9267 if (quick_pay_buttons.Data.Length < 4) 9741 if (quick_pay_buttons.Data.Length < 4)
9268 { 9742 {
9269 LSLError("List must have at least 4 elements"); 9743 int x;
9270 return; 9744 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9745 {
9746 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9747 }
9271 } 9748 }
9272 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9749 int[] nPrice = new int[5];
9273 9750 nPrice[0]=price;
9274 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9751 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9275 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9752 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9276 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9753 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9277 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9754 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9755 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9278 m_host.ParentGroup.HasGroupChanged = true; 9756 m_host.ParentGroup.HasGroupChanged = true;
9279 } 9757 }
9280 9758
@@ -9286,17 +9764,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9286 if (invItemID == UUID.Zero) 9764 if (invItemID == UUID.Zero)
9287 return new LSL_Vector(); 9765 return new LSL_Vector();
9288 9766
9289 lock (m_host.TaskInventory) 9767 m_host.TaskInventory.LockItemsForRead(true);
9768 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9290 { 9769 {
9291 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9770 m_host.TaskInventory.LockItemsForRead(false);
9292 return new LSL_Vector(); 9771 return new LSL_Vector();
9772 }
9293 9773
9294 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9774 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9295 { 9775 {
9296 ShoutError("No permissions to track the camera"); 9776 ShoutError("No permissions to track the camera");
9297 return new LSL_Vector(); 9777 m_host.TaskInventory.LockItemsForRead(false);
9298 } 9778 return new LSL_Vector();
9299 } 9779 }
9780 m_host.TaskInventory.LockItemsForRead(false);
9300 9781
9301 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9782 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9302 if (presence != null) 9783 if (presence != null)
@@ -9314,17 +9795,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9314 if (invItemID == UUID.Zero) 9795 if (invItemID == UUID.Zero)
9315 return new LSL_Rotation(); 9796 return new LSL_Rotation();
9316 9797
9317 lock (m_host.TaskInventory) 9798 m_host.TaskInventory.LockItemsForRead(true);
9799 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9318 { 9800 {
9319 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9801 m_host.TaskInventory.LockItemsForRead(false);
9320 return new LSL_Rotation(); 9802 return new LSL_Rotation();
9321 9803 }
9322 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9804 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9323 { 9805 {
9324 ShoutError("No permissions to track the camera"); 9806 ShoutError("No permissions to track the camera");
9325 return new LSL_Rotation(); 9807 m_host.TaskInventory.LockItemsForRead(false);
9326 } 9808 return new LSL_Rotation();
9327 } 9809 }
9810 m_host.TaskInventory.LockItemsForRead(false);
9328 9811
9329 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9812 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9330 if (presence != null) 9813 if (presence != null)
@@ -9386,8 +9869,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 { 9869 {
9387 m_host.AddScriptLPS(1); 9870 m_host.AddScriptLPS(1);
9388 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9871 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9389 if (detectedParams == null) return; // only works on the first detected avatar 9872 if (detectedParams == null)
9390 9873 {
9874 if (m_host.IsAttachment == true)
9875 {
9876 detectedParams = new DetectParams();
9877 detectedParams.Key = m_host.OwnerID;
9878 }
9879 else
9880 {
9881 return;
9882 }
9883 }
9884
9391 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9885 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9392 if (avatar != null) 9886 if (avatar != null)
9393 { 9887 {
@@ -9395,6 +9889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9395 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9889 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9396 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9890 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9397 } 9891 }
9892
9398 ScriptSleep(1000); 9893 ScriptSleep(1000);
9399 } 9894 }
9400 9895
@@ -9474,14 +9969,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9474 if (objectID == UUID.Zero) return; 9969 if (objectID == UUID.Zero) return;
9475 9970
9476 UUID agentID; 9971 UUID agentID;
9477 lock (m_host.TaskInventory) 9972 m_host.TaskInventory.LockItemsForRead(true);
9478 { 9973 // 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 9974 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9480 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9481 9975
9482 if (agentID == UUID.Zero) return; 9976 if (agentID == UUID.Zero)
9483 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9977 {
9978 m_host.TaskInventory.LockItemsForRead(false);
9979 return;
9980 }
9981 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9982 {
9983 m_host.TaskInventory.LockItemsForRead(false);
9984 return;
9484 } 9985 }
9986 m_host.TaskInventory.LockItemsForRead(false);
9485 9987
9486 ScenePresence presence = World.GetScenePresence(agentID); 9988 ScenePresence presence = World.GetScenePresence(agentID);
9487 9989
@@ -9531,12 +10033,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9531 10033
9532 // we need the permission first, to know which avatar we want to clear the camera for 10034 // we need the permission first, to know which avatar we want to clear the camera for
9533 UUID agentID; 10035 UUID agentID;
9534 lock (m_host.TaskInventory) 10036 m_host.TaskInventory.LockItemsForRead(true);
10037 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10038 if (agentID == UUID.Zero)
10039 {
10040 m_host.TaskInventory.LockItemsForRead(false);
10041 return;
10042 }
10043 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9535 { 10044 {
9536 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10045 m_host.TaskInventory.LockItemsForRead(false);
9537 if (agentID == UUID.Zero) return; 10046 return;
9538 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9539 } 10047 }
10048 m_host.TaskInventory.LockItemsForRead(false);
9540 10049
9541 ScenePresence presence = World.GetScenePresence(agentID); 10050 ScenePresence presence = World.GetScenePresence(agentID);
9542 10051
@@ -9603,19 +10112,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9603 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10112 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9604 { 10113 {
9605 m_host.AddScriptLPS(1); 10114 m_host.AddScriptLPS(1);
9606 string ret = String.Empty; 10115
9607 string src1 = llBase64ToString(str1); 10116 if (str1 == String.Empty)
9608 string src2 = llBase64ToString(str2); 10117 return String.Empty;
9609 int c = 0; 10118 if (str2 == String.Empty)
9610 for (int i = 0; i < src1.Length; i++) 10119 return str1;
10120
10121 byte[] data1 = Convert.FromBase64String(str1);
10122 byte[] data2 = Convert.FromBase64String(str2);
10123
10124 byte[] d2 = new Byte[data1.Length];
10125 int pos = 0;
10126
10127 if (data1.Length <= data2.Length)
10128 {
10129 Array.Copy(data2, 0, d2, 0, data1.Length);
10130 }
10131 else
9611 { 10132 {
9612 ret += (char) (src1[i] ^ src2[c]); 10133 while (pos < data1.Length)
10134 {
10135 int len = data1.Length - pos;
10136 if (len > data2.Length)
10137 len = data2.Length;
9613 10138
9614 c++; 10139 Array.Copy(data2, 0, d2, pos, len);
9615 if (c >= src2.Length) 10140 pos += len;
9616 c = 0; 10141 }
9617 } 10142 }
9618 return llStringToBase64(ret); 10143
10144 for (pos = 0 ; pos < data1.Length ; pos++ )
10145 data1[pos] ^= d2[pos];
10146
10147 return Convert.ToBase64String(data1);
9619 } 10148 }
9620 10149
9621 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10150 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9993,15 +10522,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9993 10522
9994 internal UUID ScriptByName(string name) 10523 internal UUID ScriptByName(string name)
9995 { 10524 {
9996 lock (m_host.TaskInventory) 10525 m_host.TaskInventory.LockItemsForRead(true);
10526
10527 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9997 { 10528 {
9998 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10529 if (item.Type == 10 && item.Name == name)
9999 { 10530 {
10000 if (item.Type == 10 && item.Name == name) 10531 m_host.TaskInventory.LockItemsForRead(false);
10001 return item.ItemID; 10532 return item.ItemID;
10002 } 10533 }
10003 } 10534 }
10004 10535
10536 m_host.TaskInventory.LockItemsForRead(false);
10537
10005 return UUID.Zero; 10538 return UUID.Zero;
10006 } 10539 }
10007 10540
@@ -10042,6 +10575,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10042 { 10575 {
10043 m_host.AddScriptLPS(1); 10576 m_host.AddScriptLPS(1);
10044 10577
10578 //Clone is thread safe
10045 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10579 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10046 10580
10047 UUID assetID = UUID.Zero; 10581 UUID assetID = UUID.Zero;
@@ -10104,6 +10638,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10104 { 10638 {
10105 m_host.AddScriptLPS(1); 10639 m_host.AddScriptLPS(1);
10106 10640
10641 //Clone is thread safe
10107 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10642 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10108 10643
10109 UUID assetID = UUID.Zero; 10644 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 {